[aarch64-port-dev ] Use XOR encoding for compressed class pointers

Andrew Haley aph at redhat.com
Thu Oct 17 08:59:09 PDT 2013


The new encoding for compressed class pointers generates fugly code on AArch64.

Like this for method entry:

  0x00007fffe123f9a0: ldr	wscratch1, [x1,#8]  ;   {no_reloc}
  0x00007fffe122f784: orr	xheapbase, xzr, #0x800000000
  0x00007fffe122f788: add	xscratch1, xheapbase, xscratch1
  ;; 0x7FFFF7DA3BC8
  0x00007fffe122f78c: movz	xheapbase, #0x3bc8  ;   {external_word}
  0x00007fffe122f790: movk	xheapbase, #0xf7da, lsl #16
  0x00007fffe122f794: movk	xheapbase, #0x7fff, lsl #32
  0x00007fffe122f798: movk	xheapbase, #0x0, lsl #48
  0x00007fffe122f79c: ldr	xheapbase, [xheapbase]
  0x00007fffe122f7a0: cmp	xscratch2, xscratch1
  0x00007fffe122f7a4: b.eq	0x00007fffe122f7b0

This patch takes advantage of the fact that the default base for
compressed classes is 0x800000000, which allows us to compress and
decompress class pointers simply by flipping an address bit.  So the
above code becomes:

  0x00007fffe122e280: ldr	wscratch1, [x1,#8]
  0x00007fffe122e284: eor	xscratch1, xscratch1, #0x800000000
  0x00007fffe122e288: cmp	xscratch2, xscratch1
  0x00007fffe122e28c: b.eq	0x00007fffe122e298

When ENcoding, it's not clear to me that any work is needed at all,
because we'll be storing a 32-bit word.  However, just to be on the
safe side I'm clearing bit 0x800000000 anyway; at some point in the
future we could delete this code.

Andrew.


# HG changeset patch
# User aph
# Date 1382024809 -3600
# Node ID 7ad16844c57ec14065f6354b1d8e75f965489ab4
# Parent  03f55b66e8cf056deef588742f64ed4c8c5eb0ef
Use XOR encoding for compressed class pointers.

diff -r 03f55b66e8cf -r 7ad16844c57e src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 17 16:33:03 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 17 16:46:49 2013 +0100
@@ -2079,10 +2079,21 @@
 }

 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
-  Register rbase = dst;
+  if (use_XOR_for_compressed_class_base) {
+    if (Universe::narrow_klass_shift() != 0) {
+      eor(dst, src, (uint64_t)Universe::narrow_klass_base());
+      lsr(dst, dst, LogKlassAlignmentInBytes);
+    } else {
+      eor(dst, src, (uint64_t)Universe::narrow_klass_base());
+    }
+    return;
+  }
+
 #ifdef ASSERT
   verify_heapbase("MacroAssembler::encode_klass_not_null2: heap base corrupted?");
 #endif
+
+  Register rbase = dst;
   if (dst == src) rbase = rheapbase;
   mov(rbase, (uint64_t)Universe::narrow_klass_base());
   sub(dst, src, rbase);
@@ -2101,6 +2112,17 @@
   Register rbase = dst;
   assert(Universe::narrow_klass_base() != NULL, "Base should be initialized");
   assert (UseCompressedClassPointers, "should only be used for compressed headers");
+
+  if (use_XOR_for_compressed_class_base) {
+    if (Universe::narrow_klass_shift() != 0) {
+      lsl(dst, src, LogKlassAlignmentInBytes);
+      eor(dst, dst, (uint64_t)Universe::narrow_klass_base());
+    } else {
+      eor(dst, src, (uint64_t)Universe::narrow_klass_base());
+    }
+    return;
+  }
+
   // Cannot assert, unverified entry point counts instructions (see .ad file)
   // vtableStubs also counts instructions in pd_code_size_limit.
   // Also do not verify_oop as this is called by verify_oop.
diff -r 03f55b66e8cf -r 7ad16844c57e src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 17 16:33:03 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 17 16:46:49 2013 +0100
@@ -90,10 +90,16 @@
   void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);

   // Maximum size of class area in Metaspace when compressed
-  uint64_t useBoolForCompressedClassEncoding;
+  uint64_t use_XOR_for_compressed_class_base;

  public:
-  MacroAssembler(CodeBuffer* code) : Assembler(code) {}
+  MacroAssembler(CodeBuffer* code) : Assembler(code) {
+    use_XOR_for_compressed_class_base
+      = (operand_valid_for_logical_immediate(false /*is32*/,
+					     (uint64_t)Universe::narrow_klass_base())
+	 && ((uint64_t)Universe::narrow_klass_base()
+	     > (1u << log2_intptr(CompressedClassSpaceSize))));
+  }

   // Biased locking support
   // lock_reg and obj_reg must be loaded up with the appropriate values.



More information about the aarch64-port-dev mailing list