< prev index next >

src/share/vm/c1/c1_LIRGenerator.cpp

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

*** 41,50 **** --- 41,53 ---- #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,1494 **** --- 1488,1498 ---- #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,1627 **** --- 1622,1694 ---- 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 >