< prev index next >

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Print this page
@@ -4536,20 +4536,68 @@
    movptr(holder, Address(method, Method::const_offset()));                      // ConstMethod*
    movptr(holder, Address(holder, ConstMethod::constants_offset()));             // ConstantPool*
    movptr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass*
  }
  
- void MacroAssembler::load_klass(Register dst, Register src, Register tmp) {
+ void MacroAssembler::load_klass(Register dst, Register src, Register tmp, bool null_check_src) {
    assert_different_registers(src, tmp);
    assert_different_registers(dst, tmp);
  #ifdef _LP64
-   if (UseCompressedClassPointers) {
-     movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
-     decode_klass_not_null(dst, tmp);
-   } else
+   assert(UseCompressedClassPointers, "expect compressed class pointers");
+ 
+   Label slow, done;
+   if (null_check_src) {
+     null_check(src, oopDesc::mark_offset_in_bytes());
+   }
+   movq(tmp, Address(src, oopDesc::mark_offset_in_bytes()));
+   // NOTE: While it would seem nice to use xorb instead (for which we don't have an encoding in our assembler),
+   // the encoding for xorq uses the signed version (0x81/6) of xor, which encodes as compact as xorb would,
+   // and does't make a difference performance-wise.
+   xorq(tmp, markWord::unlocked_value);
+   testb(tmp, markWord::lock_mask_in_place);
+   jccb(Assembler::notZero, slow);
+ 
+   movq(dst, tmp);
+   shrq(dst, markWord::klass_shift);
+   decode_klass_not_null(dst, tmp);
+   jmp(done);
+   bind(slow);
+ 
+   if (dst != rax) {
+     push(rax);
+   }
+   push(rdi);
+   push(rsi);
+   push(rdx);
+   push(rcx);
+   push(r8);
+   push(r9);
+   push(r10);
+   push(r11);
+ 
+   MacroAssembler::call_VM_leaf(CAST_FROM_FN_PTR(address, oopDesc::load_klass_runtime), src);
+ 
+   pop(r11);
+   pop(r10);
+   pop(r9);
+   pop(r8);
+   pop(rcx);
+   pop(rdx);
+   pop(rsi);
+   pop(rdi);
+   if (dst != rax) {
+     mov(dst, rax);
+     pop(rax);
+   }
+ 
+   bind(done);
+ #else
+   if (null_check_src) {
+     null_check(src, oopDesc::klass_offset_in_bytes());
+   }
+   movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
  #endif
-     movptr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
  }
  
  void MacroAssembler::store_klass(Register dst, Register src, Register tmp) {
    assert_different_registers(src, tmp);
    assert_different_registers(dst, tmp);
< prev index next >