< prev index next >

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Print this page

        

@@ -298,19 +298,30 @@
   CodeEmitInfo* null_check_info = NULL;
   if (x->needs_null_check()) {
     null_check_info = new CodeEmitInfo(range_check_info);
   }
 
+  LIR_Opr ary = array.result();
+  ary = shenandoah_write_barrier(ary, null_check_info, x->needs_null_check());
+  LIR_Opr val = value.result();
+  if (obj_store && UseShenandoahGC) {
+    if (! val->is_register()) {
+      assert(val->is_constant(), "expect constant");
+    } else {
+      val = shenandoah_read_barrier(val, NULL, true);
+    }
+  }
+
   // emit array address setup early so it schedules better
-  LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);
+  LIR_Address* array_addr = emit_array_address(ary, index.result(), x->elt_type(), obj_store);
 
   if (GenerateRangeChecks && needs_range_check) {
     if (use_length) {
       __ cmp(lir_cond_belowEqual, length.result(), index.result());
       __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
     } else {
-      array_range_check(array.result(), index.result(), null_check_info, range_check_info);
+      array_range_check(ary, index.result(), null_check_info, range_check_info);
       // range_check also does the null check
       null_check_info = NULL;
     }
   }
 

@@ -318,22 +329,22 @@
     LIR_Opr tmp1 = new_register(objectType);
     LIR_Opr tmp2 = new_register(objectType);
     LIR_Opr tmp3 = new_register(objectType);
 
     CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);
-    __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());
+    __ store_check(val, ary, tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());
   }
 
   if (obj_store) {
     // Needs GC write barriers.
     pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
-    __ move(value.result(), array_addr, null_check_info);
+    __ move(val, array_addr, null_check_info);
     // Seems to be a precise
     post_barrier(LIR_OprFact::address(array_addr), value.result());
   } else {
-    __ move(value.result(), array_addr, null_check_info);
+    __ move(val, array_addr, null_check_info);
   }
 }
 
 
 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {

@@ -356,11 +367,13 @@
     info_for_exception = state_for(x);
   }
   // this CodeEmitInfo must not have the xhandlers because here the
   // object is already locked (xhandlers expect object to be unlocked)
   CodeEmitInfo* info = state_for(x, x->state(), true);
-  monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
+  LIR_Opr obj_opr = obj.result();
+  obj_opr = shenandoah_write_barrier(obj_opr, state_for(x), x->needs_null_check());
+  monitor_enter(obj_opr, lock, syncTempOpr(), scratch,
                         x->monitor_no(), info_for_exception, info);
 }
 
 
 void LIRGenerator::do_MonitorExit(MonitorExit* x) {

@@ -748,31 +761,35 @@
     ShouldNotReachHere();
   }
 
   LIR_Opr addr = new_pointer_register();
   LIR_Address* a;
+
+  LIR_Opr obj_op = obj.result();
+  obj_op = shenandoah_write_barrier(obj_op, NULL, false);
+
   if(offset.result()->is_constant()) {
 #ifdef _LP64
     jlong c = offset.result()->as_jlong();
     if ((jlong)((jint)c) == c) {
-      a = new LIR_Address(obj.result(),
+      a = new LIR_Address(obj_op,
                           (jint)c,
                           as_BasicType(type));
     } else {
       LIR_Opr tmp = new_register(T_LONG);
       __ move(offset.result(), tmp);
-      a = new LIR_Address(obj.result(),
+      a = new LIR_Address(obj_op,
                           tmp,
                           as_BasicType(type));
     }
 #else
-    a = new LIR_Address(obj.result(),
+    a = new LIR_Address(obj_op,
                         offset.result()->as_jint(),
                         as_BasicType(type));
 #endif
   } else {
-    a = new LIR_Address(obj.result(),
+    a = new LIR_Address(obj_op,
                         offset.result(),
                         LIR_Address::times_1,
                         0,
                         as_BasicType(type));
   }

@@ -783,27 +800,32 @@
     pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
   }
 
   LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
-  if (type == objectType)
-    __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
+
+  LIR_Opr val_op = val.result();
+
+  if (type == objectType) {
+    val_op = shenandoah_read_barrier(val_op, NULL, true);
+    __ cas_obj(addr, cmp.result(), val_op, new_register(T_OBJECT), new_register(T_OBJECT));
+  }
   else if (type == intType)
-    __ cas_int(addr, cmp.result(), val.result(), ill, ill);
+    __ cas_int(addr, cmp.result(), val_op, ill, ill);
   else if (type == longType)
-    __ cas_long(addr, cmp.result(), val.result(), ill, ill);
+    __ cas_long(addr, cmp.result(), val_op, ill, ill);
   else {
     ShouldNotReachHere();
   }
 
   // generate conditional move of boolean result
   LIR_Opr result = rlock_result(x);
   __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
            result, as_BasicType(type));
   if (type == objectType) {   // Write-barrier needed for Object fields.
     // Seems to be precise
-    post_barrier(addr, val.result());
+    post_barrier(addr, val_op);
   }
 }
 
 
 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {

@@ -891,18 +913,23 @@
   LIRItem src_pos(x->argument_at(1), this);
   LIRItem dst(x->argument_at(2), this);
   LIRItem dst_pos(x->argument_at(3), this);
   LIRItem length(x->argument_at(4), this);
 
+  LIR_Opr dst_op = dst.result();
+  dst_op = shenandoah_write_barrier(dst_op, info, x->arg_needs_null_check(2));
+  LIR_Opr src_op = src.result();
+  src_op = shenandoah_read_barrier(src_op, info, x->arg_needs_null_check(0));
+
   // operands for arraycopy must use fixed registers, otherwise
   // LinearScan will fail allocation (because arraycopy always needs a
   // call)
 
 #ifndef _LP64
-  src.load_item_force     (FrameMap::rcx_oop_opr);
+  src_op = force_opr_to(src_op, FrameMap::rcx_oop_opr);
   src_pos.load_item_force (FrameMap::rdx_opr);
-  dst.load_item_force     (FrameMap::rax_oop_opr);
+  dst_op = force_opr_to(dst_op, FrameMap::rax_oop_opr);
   dst_pos.load_item_force (FrameMap::rbx_opr);
   length.load_item_force  (FrameMap::rdi_opr);
   LIR_Opr tmp =           (FrameMap::rsi_opr);
 #else
 

@@ -912,13 +939,13 @@
   // positions are not similar enough to pick one as the best.
   // Also because the java calling convention is a "shifted" version
   // of the C convention we can process the java args trivially into C
   // args without worry of overwriting during the xfer
 
-  src.load_item_force     (FrameMap::as_oop_opr(j_rarg0));
+  src_op = force_opr_to(src_op, FrameMap::as_oop_opr(j_rarg0));
   src_pos.load_item_force (FrameMap::as_opr(j_rarg1));
-  dst.load_item_force     (FrameMap::as_oop_opr(j_rarg2));
+  dst_op = force_opr_to(dst_op, FrameMap::as_oop_opr(j_rarg2));
   dst_pos.load_item_force (FrameMap::as_opr(j_rarg3));
   length.load_item_force  (FrameMap::as_opr(j_rarg4));
 
   LIR_Opr tmp =           FrameMap::as_opr(j_rarg5);
 #endif // LP64

@@ -927,11 +954,11 @@
 
   int flags;
   ciArrayKlass* expected_type;
   arraycopy_helper(x, &flags, &expected_type);
 
-  __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
+  __ arraycopy(src_op, src_pos.result(), dst_op, dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
 }
 
 void LIRGenerator::do_update_CRC32(Intrinsic* x) {
   assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
   // Make all state_for calls early since they can emit code

@@ -978,10 +1005,14 @@
         __ convert(Bytecodes::_i2l, index, tmp);
         index = tmp;
       }
 #endif
 
+      if (is_updateBytes) {
+        base_op = shenandoah_read_barrier(base_op, NULL, false);
+      }
+
       LIR_Address* a = new LIR_Address(base_op,
                                        index,
                                        LIR_Address::times_1,
                                        offset,
                                        T_BYTE);

@@ -1310,10 +1341,14 @@
   }
   set_no_result(x);
 
   LIR_Opr left = xin->result();
   LIR_Opr right = yin->result();
+  if (tag == objectTag && UseShenandoahGC && x->y()->type() != objectNull) { // Don't need to resolve for ifnull.
+    left = shenandoah_write_barrier(left, NULL, true);
+    right = shenandoah_read_barrier(right, NULL, true);
+  }
   __ cmp(lir_cond(cond), left, right);
   // Generate branch profiling. Profiling code doesn't kill flags.
   profile_branch(x, cond);
   move_to_phi(x->state());
   if (x->x()->type()->is_float_kind()) {

@@ -1389,10 +1424,11 @@
   }
 }
 
 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
                                      BasicType type, bool is_volatile) {
+  src = shenandoah_read_barrier(src, NULL, false);
   if (is_volatile && type == T_LONG) {
     LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
     LIR_Opr tmp = new_register(T_DOUBLE);
     __ load(addr, tmp);
     LIR_Opr spill = new_register(T_LONG);

@@ -1406,10 +1442,11 @@
 }
 
 
 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
                                      BasicType type, bool is_volatile) {
+  src = shenandoah_write_barrier(src, NULL, false);
   if (is_volatile && type == T_LONG) {
     LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
     LIR_Opr tmp = new_register(T_DOUBLE);
     LIR_Opr spill = new_register(T_DOUBLE);
     set_vreg_flag(spill, must_start_in_memory);

@@ -1421,10 +1458,11 @@
     bool is_obj = (type == T_ARRAY || type == T_OBJECT);
     if (is_obj) {
       // Do the pre-write barrier, if any.
       pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
                   true /* do_load */, false /* patch */, NULL);
+      data = shenandoah_read_barrier(data, NULL, true);
       __ move(data, addr);
       assert(src->is_register(), "must be register");
       // Seems to be a precise address
       post_barrier(LIR_OprFact::address(addr), data);
     } else {

@@ -1447,26 +1485,33 @@
   LIR_Opr data = value.result();
   bool is_obj = (type == T_ARRAY || type == T_OBJECT);
   LIR_Opr offset = off.result();
 
   assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
+
+  LIR_Opr src_op = src.result();
+  src_op = shenandoah_write_barrier(src_op, NULL, false);
+  if (is_obj) {
+    data = shenandoah_read_barrier(data, NULL, true);
+  }
+
   LIR_Address* addr;
   if (offset->is_constant()) {
 #ifdef _LP64
     jlong c = offset->as_jlong();
     if ((jlong)((jint)c) == c) {
-      addr = new LIR_Address(src.result(), (jint)c, type);
+      addr = new LIR_Address(src_op, (jint)c, type);
     } else {
       LIR_Opr tmp = new_register(T_LONG);
       __ move(offset, tmp);
-      addr = new LIR_Address(src.result(), tmp, type);
+      addr = new LIR_Address(src_op, tmp, type);
     }
 #else
-    addr = new LIR_Address(src.result(), offset->as_jint(), type);
+    addr = new LIR_Address(src_op, offset->as_jint(), type);
 #endif
   } else {
-    addr = new LIR_Address(src.result(), offset, type);
+    addr = new LIR_Address(src_op, offset, type);
   }
 
   // Because we want a 2-arg form of xchg and xadd
   __ move(data, dst);
 
< prev index next >