< prev index next >

src/cpu/aarch64/vm/c1_LIRGenerator_aarch64.cpp

Print this page

        

@@ -352,20 +352,31 @@
   CodeEmitInfo* null_check_info = NULL;
   if (x->needs_null_check()) {
     null_check_info = new CodeEmitInfo(range_check_info);
   }
 
+  LIR_Opr ary = array.result();
+  LIR_Opr val = value.result();
+  value = NULL;
+
+#if INCLUDE_ALL_GCS
+  ary = shenandoah_write_barrier(ary, null_check_info, x->needs_null_check());
+  if (obj_store && UseShenandoahGC) {
+    val = shenandoah_read_barrier(val, NULL, true);
+  }
+#endif
+
   // emit array address setup early so it schedules better
   // FIXME?  No harm in this on aarch64, and it might help
-  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;
     }
   }
 

@@ -373,22 +384,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());
+    post_barrier(LIR_OprFact::address(array_addr), val);
   } else {
-    LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+    LIR_Opr result = maybe_mask_boolean(x, ary, val, null_check_info);
     __ move(result, array_addr, null_check_info);
   }
 }
 
 void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {

@@ -411,11 +422,15 @@
     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();
+#if INCLUDE_ALL_GCS
+  obj_opr = shenandoah_write_barrier(obj_opr, state_for(x), x->needs_null_check());
+#endif
+  monitor_enter(obj_opr, lock, syncTempOpr(), scratch,
                         x->monitor_no(), info_for_exception, info);
 }
 
 
 void LIRGenerator::do_MonitorExit(MonitorExit* x) {

@@ -796,25 +811,31 @@
   offset.load_nonconstant();
   val.load_item();
   cmp.load_item();
 
   LIR_Address* a;
+
+  LIR_Opr obj_op = obj.result();
+#if INCLUDE_ALL_GCS
+  obj_op = shenandoah_write_barrier(obj_op, NULL, true);
+#endif
+
   if(offset.result()->is_constant()) {
     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(),
                         LIR_Address::times_1,
                         0,
                         as_BasicType(type));
   }

@@ -826,28 +847,31 @@
     pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
                 true /* do_load */, false /* patch */, NULL);
   }
 
   LIR_Opr result = rlock_result(x);
+  LIR_Opr val_op = val.result();
 
   LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
-  if (type == objectType)
-    __ cas_obj(addr, cmp.result(), val.result(), new_register(T_INT), new_register(T_INT),
+
+  if (type == objectType) {
+#if INCLUDE_ALL_GCS
+    val_op = shenandoah_read_barrier(val_op, NULL, true);
+#endif
+    __ cas_obj(addr, cmp.result(), val_op, new_register(T_INT), new_register(T_INT),
                result);
-  else if (type == intType)
-    __ cas_int(addr, cmp.result(), val.result(), ill, ill);
+  } else if (type == intType)
+    __ cas_int(addr, cmp.result(), val_op, ill, ill, result);
   else if (type == longType)
-    __ cas_long(addr, cmp.result(), val.result(), ill, ill);
+    __ cas_long(addr, cmp.result(), val_op, ill, ill, result);
   else {
     ShouldNotReachHere();
   }
 
-  __ logical_xor(FrameMap::r8_opr, LIR_OprFact::intConst(1), result);
-
   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) {
   switch (x->id()) {

@@ -927,10 +951,17 @@
   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();
+  LIR_Opr src_op = src.result();
+#if INCLUDE_ALL_GCS
+  dst_op = shenandoah_write_barrier(dst_op, info, x->arg_needs_null_check(2));
+  src_op = shenandoah_read_barrier(src_op, info, x->arg_needs_null_check(0));
+#endif
+
   // operands for arraycopy must use fixed registers, otherwise
   // LinearScan will fail allocation (because arraycopy always needs a
   // call)
 
   // The java calling convention will give us enough registers

@@ -939,13 +970,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);
 

@@ -953,11 +984,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, "why are we here?");
   // Make all state_for calls early since they can emit code

@@ -997,10 +1028,16 @@
         LIR_Opr tmp = new_register(T_LONG);
         __ convert(Bytecodes::_i2l, index, tmp);
         index = tmp;
       }
 
+#if INCLUDE_ALL_GCS
+      if (is_updateBytes) {
+        base_op = shenandoah_read_barrier(base_op, NULL, false);
+      }
+#endif
+
       if (offset) {
         LIR_Opr tmp = new_pointer_register();
         __ add(base_op, LIR_OprFact::intConst(offset), tmp);
         base_op = tmp;
         offset = 0;

@@ -1351,23 +1388,33 @@
   __ volatile_load_mem_reg(address, result, info);
 }
 
 void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
                                      BasicType type, bool is_volatile) {
+#if INCLUDE_ALL_GCS
+  src = shenandoah_read_barrier(src, NULL, true);
+#endif
   LIR_Address* addr = new LIR_Address(src, offset, type);
   __ load(addr, dst);
 }
 
 
 void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
                                      BasicType type, bool is_volatile) {
+#if INCLUDE_ALL_GCS
+  src = shenandoah_write_barrier(src, NULL, true);
+#endif
+
   LIR_Address* addr = new LIR_Address(src, offset, type);
   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);
+#if INCLUDE_ALL_GCS
+    data = shenandoah_read_barrier(data, NULL, true);
+#endif
     __ move(data, addr);
     assert(src->is_register(), "must be register");
     // Seems to be a precise address
     post_barrier(LIR_OprFact::address(addr), data);
   } else {

@@ -1400,18 +1447,27 @@
     LIR_Opr tmp = new_register(data->type());
     __ move(data, tmp);
     data = tmp;
   }
 
+  LIR_Opr src_op = src.result();
+
+#if INCLUDE_ALL_GCS
+  src_op = shenandoah_write_barrier(src_op, NULL, true);
+  if (is_obj) {
+    data = shenandoah_read_barrier(data, NULL, true);
+  }
+#endif
+
   LIR_Address* addr;
   if (offset->is_constant()) {
     jlong l = offset->as_jlong();
     assert((jlong)((jint)l) == l, "offset too large for constant");
     jint c = (jint)l;
-    addr = new LIR_Address(src.result(), c, type);
+    addr = new LIR_Address(src_op, c, type);
   } else {
-    addr = new LIR_Address(src.result(), offset, type);
+    addr = new LIR_Address(src_op, offset, type);
   }
 
   LIR_Opr tmp = new_register(T_INT);
   LIR_Opr ptr = LIR_OprFact::illegalOpr;
 

@@ -1419,11 +1475,11 @@
     __ xadd(LIR_OprFact::address(addr), data, dst, tmp);
   } else {
     if (is_obj) {
       // Do the pre-write barrier, if any.
       ptr = new_pointer_register();
-      __ add(src.result(), off.result(), ptr);
+      __ add(src_op, off.result(), ptr);
       pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,
                   true /* do_load */, false /* patch */, NULL);
     }
     __ xchg(LIR_OprFact::address(addr), data, dst, tmp);
     if (is_obj) {
< prev index next >