< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page
@@ -4476,12 +4476,34 @@
    ldr(holder, Address(method, Method::const_offset()));                      // ConstMethod*
    ldr(holder, Address(holder, ConstMethod::constants_offset()));             // ConstantPool*
    ldr(holder, Address(holder, ConstantPool::pool_holder_offset()));          // InstanceKlass*
  }
  
+ // Loads the obj's Klass* into dst.
+ // Preserves all registers (incl src, rscratch1 and rscratch2).
+ void MacroAssembler::load_nklass(Register dst, Register src) {
+   assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
+ 
+   Label fast;
+ 
+   // Check if we can take the (common) fast path, if obj is unlocked.
+   ldr(dst, Address(src, oopDesc::mark_offset_in_bytes()));
+   tbz(dst, exact_log2(markWord::monitor_value), fast);
+ 
+   // Fetch displaced header
+   ldr(dst, Address(dst, OM_OFFSET_NO_MONITOR_VALUE_TAG(header)));
+ 
+   // Fast-path: shift and decode Klass*.
+   bind(fast);
+   lsr(dst, dst, markWord::klass_shift);
+ }
+ 
  void MacroAssembler::load_klass(Register dst, Register src) {
-   if (UseCompressedClassPointers) {
+   if (UseCompactObjectHeaders) {
+     load_nklass(dst, src);
+     decode_klass_not_null(dst);
+   } else if (UseCompressedClassPointers) {
      ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
      decode_klass_not_null(dst);
    } else {
      ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
    }

@@ -4533,12 +4555,17 @@
    ldr(dst, Address(dst, mirror_offset));
    resolve_oop_handle(dst, tmp1, tmp2);
  }
  
  void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
+   assert_different_registers(oop, trial_klass, tmp);
    if (UseCompressedClassPointers) {
-     ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
+     if (UseCompactObjectHeaders) {
+       load_nklass(tmp, oop);
+     } else {
+       ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
+     }
      if (CompressedKlassPointers::base() == nullptr) {
        cmp(trial_klass, tmp, LSL, CompressedKlassPointers::shift());
        return;
      } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
                 && CompressedKlassPointers::shift() == 0) {

@@ -4551,22 +4578,40 @@
      ldr(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
    }
    cmp(trial_klass, tmp);
  }
  
+ void MacroAssembler::cmp_klass(Register src, Register dst, Register tmp1, Register tmp2) {
+   if (UseCompactObjectHeaders) {
+     load_nklass(tmp1, src);
+     load_nklass(tmp2, dst);
+     cmpw(tmp1, tmp2);
+   } else if (UseCompressedClassPointers) {
+     ldrw(tmp1, Address(src, oopDesc::klass_offset_in_bytes()));
+     ldrw(tmp2, Address(dst, oopDesc::klass_offset_in_bytes()));
+     cmpw(tmp1, tmp2);
+   } else {
+     ldr(tmp1, Address(src, oopDesc::klass_offset_in_bytes()));
+     ldr(tmp2, Address(dst, oopDesc::klass_offset_in_bytes()));
+     cmp(tmp1, tmp2);
+   }
+ }
+ 
  void MacroAssembler::store_klass(Register dst, Register src) {
    // FIXME: Should this be a store release?  concurrent gcs assumes
    // klass length is valid if klass field is not null.
+   assert(!UseCompactObjectHeaders, "not with compact headers");
    if (UseCompressedClassPointers) {
      encode_klass_not_null(src);
      strw(src, Address(dst, oopDesc::klass_offset_in_bytes()));
    } else {
      str(src, Address(dst, oopDesc::klass_offset_in_bytes()));
    }
  }
  
  void MacroAssembler::store_klass_gap(Register dst, Register src) {
+   assert(!UseCompactObjectHeaders, "not with compact headers");
    if (UseCompressedClassPointers) {
      // Store to klass gap in destination
      strw(src, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
    }
  }
< prev index next >