< 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 >