< prev index next >

src/share/vm/c1/c1_LIRGenerator.cpp

Print this page

        

@@ -31,10 +31,12 @@
 #include "c1/c1_LIRGenerator.hpp"
 #include "c1/c1_ValueStack.hpp"
 #include "ci/ciArrayKlass.hpp"
 #include "ci/ciInstance.hpp"
 #include "ci/ciObjArray.hpp"
+#include "gc_implementation/shenandoah/shenandoahHeap.hpp"
+#include "gc_implementation/shenandoah/c1/shenandoahBarrierSetC1.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_ALL_GCS

@@ -1227,10 +1229,18 @@
   LIR_Address* referent_field_adr =
     new LIR_Address(reference.result(), referent_offset, T_OBJECT);
 
   LIR_Opr result = rlock_result(x);
 
+#if INCLUDE_ALL_GCS
+  if (UseShenandoahGC) {
+    LIR_Opr tmp = new_register(T_OBJECT);
+    __ load(referent_field_adr, tmp, info);
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp);
+    __ move(tmp, result);
+  } else
+#endif
   __ load(referent_field_adr, result, info);
 
   // Register the value in the referent field with the pre-barrier
   pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */,
               result /* pre_val */,

@@ -1420,10 +1430,15 @@
 #if INCLUDE_ALL_GCS
     case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
       break;
+    case BarrierSet::ShenandoahBarrierSet:
+      if (ShenandoahSATBBarrier) {
+        G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
+      }
+      break;
 #endif // INCLUDE_ALL_GCS
     case BarrierSet::CardTableModRef:
     case BarrierSet::CardTableExtension:
       // No pre barriers
       break;

@@ -1442,10 +1457,13 @@
 #if INCLUDE_ALL_GCS
     case BarrierSet::G1SATBCT:
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_post_barrier(addr,  new_val);
       break;
+    case BarrierSet::ShenandoahBarrierSet:
+      ShenandoahBarrierSetC1::bsc1()->storeval_barrier(this, new_val, NULL, false);
+      break;
 #endif // INCLUDE_ALL_GCS
     case BarrierSet::CardTableModRef:
     case BarrierSet::CardTableExtension:
       CardTableModRef_post_barrier(addr,  new_val);
       break;

@@ -1605,10 +1623,15 @@
     __ move(addr, tmp);
     __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
   } else {
     __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
   }
+
+  if (UseConcMarkSweepGC && CMSPrecleaningEnabled) {
+    __ membar_storestore();
+  }
+
   if (can_inline_as_constant(card_table_base)) {
     __ move(LIR_OprFact::intConst(0),
               new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE));
   } else {
     __ move(LIR_OprFact::intConst(0),

@@ -1803,20 +1826,37 @@
     address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
   } else {
     address = generate_address(object.result(), x->offset(), field_type);
   }
 
+#if INCLUDE_ALL_GCS
+  if (UseShenandoahGC && (field_type == T_OBJECT || field_type == T_ARRAY)) {
+    LIR_Opr tmp = new_register(T_OBJECT);
+    if (is_volatile && !needs_patching) {
+      volatile_field_load(address, tmp, info);
+    } else {
+      LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
+      __ load(address, tmp, info, patch_code);
+    }
+    if (is_volatile && os::is_MP()) {
+      __ membar_acquire();
+    }
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp);
+    __ move(tmp, reg);
+  } else
+#endif
+  {
   if (is_volatile && !needs_patching) {
     volatile_field_load(address, reg, info);
   } else {
     LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
     __ load(address, reg, info, patch_code);
   }
-
   if (is_volatile && os::is_MP()) {
     __ membar_acquire();
   }
+  }
 }
 
 
 //------------------------java.nio.Buffer.checkIndex------------------------
 

@@ -1929,11 +1969,22 @@
       // The range check performs the null check, so clear it out for the load
       null_check_info = NULL;
     }
   }
 
-  __ move(array_addr, rlock_result(x, x->elt_type()), null_check_info);
+  LIR_Opr result = rlock_result(x, x->elt_type());
+
+#if INCLUDE_ALL_GCS
+  if (UseShenandoahGC && (x->elt_type() == T_OBJECT || x->elt_type() == T_ARRAY)) {
+    LIR_Opr tmp = new_register(T_OBJECT);
+    __ move(array_addr, tmp, null_check_info);
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp);
+    __ move(tmp, result);
+  } else
+#endif
+  __ move(array_addr, result, null_check_info);
+
 }
 
 
 void LIRGenerator::do_NullCheck(NullCheck* x) {
   if (x->can_trap()) {

@@ -2103,11 +2154,11 @@
   if (index_op->is_constant()) {
     assert(log2_scale == 0, "must not have a scale");
     assert(index_op->type() == T_INT, "only int constants supported");
     addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
   } else {
-#ifdef X86
+#if defined(X86) || defined(AARCH64)
     addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
 #elif defined(GENERATE_ADDRESS_IS_PREFERRED)
     addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
 #else
     if (index_op->is_illegal() || log2_scale == 0) {

@@ -2218,10 +2269,18 @@
   off.load_item();
   src.load_item();
 
   LIR_Opr value = rlock_result(x, x->basic_type());
 
+#if INCLUDE_ALL_GCS
+  if (UseShenandoahGC && (type == T_OBJECT || type == T_ARRAY)) {
+    LIR_Opr tmp = new_register(T_OBJECT);
+    get_Object_unsafe(tmp, src.result(), off.result(), type, x->is_volatile());
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp);
+    __ move(tmp, value);
+  } else
+#endif
   get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile());
 
 #if INCLUDE_ALL_GCS
   // We might be reading the value of the referent field of a
   // Reference object in order to attach it back to the live

@@ -2236,11 +2295,11 @@
   //       pre_barrier(..., value, ...);
   //     }
   //   }
   // }
 
-  if (UseG1GC && type == T_OBJECT) {
+  if ((UseShenandoahGC || UseG1GC) && type == T_OBJECT) {
     bool gen_pre_barrier = true;     // Assume we need to generate pre_barrier.
     bool gen_offset_check = true;    // Assume we need to generate the offset guard.
     bool gen_source_check = true;    // Assume we need to check the src object for null.
     bool gen_type_check = true;      // Assume we need to check the reference_type.
 
< prev index next >