< 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,19 @@
   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);
+    LIR_Opr addr = ShenandoahBarrierSet::barrier_set()->bsc1()->resolve_address(this, referent_field_adr, T_OBJECT, NULL);
+    __ load(addr->as_address_ptr(), tmp, info);
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, addr);
+    __ 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 +1431,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 +1458,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;

@@ -1808,20 +1827,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);
+    LIR_Opr addr = ShenandoahBarrierSet::barrier_set()->bsc1()->resolve_address(this, address, field_type, needs_patching ? info : NULL);
+    if (is_volatile) {
+      volatile_field_load(addr->as_address_ptr(), tmp, info);
+    } else {
+      __ load(addr->as_address_ptr(), tmp, info);
+    }
+    if (is_volatile && os::is_MP()) {
+      __ membar_acquire();
+    }
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, addr);
+    __ 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------------------------
 

@@ -1934,11 +1970,23 @@
       // 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);
+    LIR_Opr addr = ShenandoahBarrierSet::barrier_set()->bsc1()->resolve_address(this, array_addr, x->elt_type(), NULL);
+    __ move(addr->as_address_ptr(), tmp, null_check_info);
+    tmp = ShenandoahBarrierSet::barrier_set()->bsc1()->load_reference_barrier(this, tmp, addr);
+    __ move(tmp, result);
+  } else
+#endif
+  __ move(array_addr, result, null_check_info);
+
 }
 
 
 void LIRGenerator::do_NullCheck(NullCheck* x) {
   if (x->can_trap()) {

@@ -2223,10 +2271,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, LIR_OprFact::addressConst(0));
+    __ 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

@@ -2241,11 +2297,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 >