< prev index next >

src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp

Print this page
*** 123,22 ***
    bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
    bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
    bool on_reference = on_weak || on_phantom;
    ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
    if (on_oop && on_reference) {
!     const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
!     NOT_LP64(__ get_thread(thread));
  
      // Generate the G1 pre-barrier code to log the value of
      // the referent field in an SATB buffer.
      g1_write_barrier_pre(masm /* masm */,
                           noreg /* obj */,
                           dst /* pre_val */,
                           thread /* thread */,
                           tmp1 /* tmp */,
                           true /* tosca_live */,
                           true /* expand_call */);
    }
  }
  
  void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
                                                   Register obj,
--- 123,42 ---
    bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
    bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
    bool on_reference = on_weak || on_phantom;
    ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
    if (on_oop && on_reference) {
!     Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
! 
+ #ifndef _LP64
+     // Work around the x86_32 bug that only manifests with Loom for some reason.
+     // MacroAssembler::resolve_weak_handle calls this barrier with tmp_thread == noreg.
+     if (thread == noreg) {
+       if (dst != rcx && tmp1 != rcx) {
+         thread = rcx;
+       } else if (dst != rdx && tmp1 != rdx) {
+         thread = rdx;
+       } else if (dst != rdi && tmp1 != rdi) {
+         thread = rdi;
+       }
+     }
+     assert_different_registers(dst, tmp1, thread);
+     __ push(thread);
+     __ get_thread(thread);
+ #endif
  
      // Generate the G1 pre-barrier code to log the value of
      // the referent field in an SATB buffer.
      g1_write_barrier_pre(masm /* masm */,
                           noreg /* obj */,
                           dst /* pre_val */,
                           thread /* thread */,
                           tmp1 /* tmp */,
                           true /* tosca_live */,
                           true /* expand_call */);
+ 
+ #ifndef _LP64
+     __ pop(thread);
+ #endif
    }
  }
  
  void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
                                                   Register obj,

*** 202,18 ***
    // Record the previous value
    __ movptr(Address(tmp, 0), pre_val);
    __ jmp(done);
  
    __ bind(runtime);
-   // save the live input values
-   if(tosca_live) __ push(rax);
- 
-   if (obj != noreg && obj != rax)
-     __ push(obj);
- 
-   if (pre_val != rax)
-     __ push(pre_val);
  
    // Calling the runtime using the regular call_VM_leaf mechanism generates
    // code (generated by InterpreterMacroAssember::call_VM_leaf_base)
    // that checks that the *(ebp+frame::interpreter_frame_last_sp) == NULL.
    //
--- 222,10 ---

*** 223,11 ***
    //
    // Expanding the call directly bypasses the generation of the check.
    // So when we do not have have a full interpreter frame on the stack
    // expand_call should be passed true.
  
!   NOT_LP64( __ push(thread); )
  
    if (expand_call) {
      LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
  #ifdef _LP64
      if (c_rarg1 != thread) {
--- 235,11 ---
    //
    // Expanding the call directly bypasses the generation of the check.
    // So when we do not have have a full interpreter frame on the stack
    // expand_call should be passed true.
  
!   __ pusha();
  
    if (expand_call) {
      LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
  #ifdef _LP64
      if (c_rarg1 != thread) {

*** 243,20 ***
      __ MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), 2);
    } else {
      __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread);
    }
  
!   NOT_LP64( __ pop(thread); )
- 
-   // save the live input values
-   if (pre_val != rax)
-     __ pop(pre_val);
- 
-   if (obj != noreg && obj != rax)
-     __ pop(obj);
- 
-   if(tosca_live) __ pop(rax);
  
    __ bind(done);
  }
  
  void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
--- 255,11 ---
      __ MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), 2);
    } else {
      __ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread);
    }
  
!   __ popa();
  
    __ bind(done);
  }
  
  void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,

*** 343,13 ***
  
  void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                           Address dst, Register val, Register tmp1, Register tmp2) {
    bool in_heap = (decorators & IN_HEAP) != 0;
    bool as_normal = (decorators & AS_NORMAL) != 0;
!   assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
  
!   bool needs_pre_barrier = as_normal;
    bool needs_post_barrier = val != noreg && in_heap;
  
    Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
    Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
    // flatten object address if needed
--- 346,13 ---
  
  void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
                                           Address dst, Register val, Register tmp1, Register tmp2) {
    bool in_heap = (decorators & IN_HEAP) != 0;
    bool as_normal = (decorators & AS_NORMAL) != 0;
!   //assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
  
!   bool needs_pre_barrier = as_normal && (! (decorators & IS_DEST_UNINITIALIZED) );
    bool needs_post_barrier = val != noreg && in_heap;
  
    Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
    Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
    // flatten object address if needed
< prev index next >