< prev index next >

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

Print this page
@@ -123,22 +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) {
-     const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
-     NOT_LP64(__ get_thread(thread));
+     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 +222,10 @@
    // 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.
    //

@@ -223,11 +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.
  
-   NOT_LP64( __ push(thread); )
+   __ pusha();
  
    if (expand_call) {
      LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
  #ifdef _LP64
      if (c_rarg1 != thread) {

@@ -243,20 +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);
    }
  
-   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);
+   __ popa();
  
    __ bind(done);
  }
  
  void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,

@@ -343,13 +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");
+   //assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
  
-   bool needs_pre_barrier = as_normal;
+   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 >