< prev index next >

src/share/vm/c1/c1_LIRGenerator.cpp

Print this page
rev 13055 : Implement barriers for maintaining connection matrix.

@@ -41,10 +41,13 @@
 #include "runtime/vm_version.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/macros.hpp"
 #if INCLUDE_ALL_GCS
 #include "gc/g1/heapRegion.hpp"
+#include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
+#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeapRegion.hpp"
 #endif // INCLUDE_ALL_GCS
 #ifdef TRACE_HAVE_INTRINSICS
 #include "trace/traceMacros.hpp"
 #endif
 

@@ -1485,10 +1488,11 @@
 #if INCLUDE_ALL_GCS
     case BarrierSet::G1SATBCTLogging:
       G1SATBCardTableModRef_post_barrier(addr,  new_val);
       break;
     case BarrierSet::ShenandoahBarrierSet:
+      Shenandoah_post_barrier(addr,  new_val);
       break;
 #endif // INCLUDE_ALL_GCS
     case BarrierSet::CardTableForRS:
     case BarrierSet::CardTableExtension:
       CardTableModRef_post_barrier(addr,  new_val);

@@ -1618,10 +1622,73 @@
   CodeStub* slow = new G1PostBarrierStub(addr, new_val);
   __ branch(lir_cond_notEqual, LP64_ONLY(T_LONG) NOT_LP64(T_INT), slow);
   __ branch_destination(slow->continuation());
 }
 
+void LIRGenerator::Shenandoah_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
+  if (! UseShenandoahMatrix) {
+    // No need for that barrier if not using matrix.
+    return;
+  }
+
+  // If the "new_val" is a constant NULL, no barrier is necessary.
+  if (new_val->is_constant() &&
+      new_val->as_constant_ptr()->as_jobject() == NULL) return;
+
+  if (!new_val->is_register()) {
+    LIR_Opr new_val_reg = new_register(T_OBJECT);
+    if (new_val->is_constant()) {
+      __ move(new_val, new_val_reg);
+    } else {
+      __ leal(new_val, new_val_reg);
+    }
+    new_val = new_val_reg;
+  }
+  assert(new_val->is_register(), "must be a register at this point");
+
+  if (addr->is_address()) {
+    LIR_Address* address = addr->as_address_ptr();
+    LIR_Opr ptr = new_pointer_register();
+    if (!address->index()->is_valid() && address->disp() == 0) {
+      __ move(address->base(), ptr);
+    } else {
+      assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
+      __ leal(addr, ptr);
+    }
+    addr = ptr;
+  }
+  assert(addr->is_register(), "must be a register at this point");
+
+  LabelObj* L_done = new LabelObj();
+  __ cmp(lir_cond_equal, new_val, LIR_OprFact::oopConst(NULL_WORD));
+  __ branch(lir_cond_equal, T_OBJECT, L_done->label());
+
+  ShenandoahConnectionMatrix* matrix = ShenandoahHeap::heap()->connection_matrix();
+
+  LIR_Opr tmp1 = new_pointer_register();
+  //LIR_Address* first_region_bottom = new LIR_Address(LIR_OprDesc::illegalOpr(), (intx) , T_ADDRESS);
+  __ move(addr, tmp1);
+  __ sub(tmp1, LIR_OprFact::intptrConst(ShenandoahHeap::heap()->first_region_bottom()), tmp1);
+  __ unsigned_shift_right(tmp1, LIR_OprFact::intConst(ShenandoahHeapRegion::RegionSizeShift), tmp1, LIR_OprDesc::illegalOpr());
+
+  LIR_Opr tmp2 = new_pointer_register();
+  __ move(new_val, tmp2);
+  __ sub(tmp2, LIR_OprFact::intptrConst(ShenandoahHeap::heap()->first_region_bottom()), tmp2);
+  __ unsigned_shift_right(tmp2, LIR_OprFact::intConst(ShenandoahHeapRegion::RegionSizeShift), tmp2, LIR_OprDesc::illegalOpr());
+
+  LIR_Opr tmp3 = new_pointer_register();
+  __ move(LIR_OprFact::longConst(matrix->stride()), tmp3);
+  __ mul(tmp1, tmp3, tmp1);
+  __ add(tmp1, tmp2, tmp1);
+
+  LIR_Opr tmp4 = new_pointer_register();
+  __ move(LIR_OprFact::intptrConst((intptr_t) matrix->matrix_addr()), tmp4);
+  LIR_Address* matrix_elem_addr = new LIR_Address(tmp4, tmp1, T_BOOLEAN);
+  __ move(LIR_OprFact::intConst((int) true), matrix_elem_addr);
+  __ branch_destination(L_done->label());
+}
+
 #endif // INCLUDE_ALL_GCS
 ////////////////////////////////////////////////////////////////////////
 
 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
   CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(_bs);
< prev index next >