< prev index next >

src/share/vm/c1/c1_LIRGenerator.cpp

Print this page
rev 8961 : [mq]: diff-shenandoah.patch

*** 245,262 **** } void LIRItem::load_item_force(LIR_Opr reg) { LIR_Opr r = result(); if (r != reg) { #if !defined(ARM) && !defined(E500V2) ! if (r->type() != reg->type()) { // moves between different types need an intervening spill slot ! r = _gen->force_to_spill(r, reg->type()); } #endif ! __ move(r, reg); ! _result = reg; } } ciObject* LIRItem::get_jobject_constant() const { ObjectType* oc = type()->as_ObjectType(); --- 245,270 ---- } void LIRItem::load_item_force(LIR_Opr reg) { LIR_Opr r = result(); if (r != reg) { + _result = _gen->force_opr_to(r, reg); + } + } + + LIR_Opr LIRGenerator::force_opr_to(LIR_Opr op, LIR_Opr reg) { + if (op != reg) { #if !defined(ARM) && !defined(E500V2) ! if (op->type() != reg->type()) { // moves between different types need an intervening spill slot ! op = force_to_spill(op, reg->type()); } #endif ! __ move(op, reg); ! return reg; ! } else { ! return op; } } ciObject* LIRItem::get_jobject_constant() const { ObjectType* oc = type()->as_ObjectType();
*** 1420,1429 **** --- 1428,1438 ---- bool do_load, bool patch, CodeEmitInfo* info) { // Do the pre-write barrier, if any. switch (_bs->kind()) { #if INCLUDE_ALL_GCS case BarrierSet::G1SATBCTLogging: + case BarrierSet::ShenandoahBarrierSet: G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info); break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableForRS: case BarrierSet::CardTableExtension:
*** 1442,1451 **** --- 1451,1462 ---- switch (_bs->kind()) { #if INCLUDE_ALL_GCS case BarrierSet::G1SATBCTLogging: G1SATBCardTableModRef_post_barrier(addr, new_val); break; + case BarrierSet::ShenandoahBarrierSet: + break; #endif // INCLUDE_ALL_GCS case BarrierSet::CardTableForRS: case BarrierSet::CardTableExtension: CardTableModRef_post_barrier(addr, new_val); break;
*** 1712,1737 **** tty->print_cr(" ###class not loaded at store_%s bci %d", x->is_static() ? "static" : "field", x->printable_bci()); } #endif if (x->needs_null_check() && (needs_patching || MacroAssembler::needs_explicit_null_check(x->offset()))) { // emit an explicit null check because the offset is too large ! __ null_check(object.result(), new CodeEmitInfo(info)); } LIR_Address* address; if (needs_patching) { // we need to patch the offset in the instruction so don't allow // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. ! address = new LIR_Address(object.result(), PATCHED_ADDR, field_type); } else { ! address = generate_address(object.result(), x->offset(), field_type); } if (is_volatile && os::is_MP()) { __ membar_release(); } --- 1723,1760 ---- tty->print_cr(" ###class not loaded at store_%s bci %d", x->is_static() ? "static" : "field", x->printable_bci()); } #endif + LIR_Opr obj = object.result(); + if (x->needs_null_check() && (needs_patching || MacroAssembler::needs_explicit_null_check(x->offset()))) { // emit an explicit null check because the offset is too large ! __ null_check(obj, new CodeEmitInfo(info)); ! } ! ! obj = shenandoah_write_barrier(obj, info, x->needs_null_check()); ! LIR_Opr val = value.result(); ! if (is_oop && UseShenandoahGC) { ! if (! val->is_register()) { ! assert(val->is_constant(), "expect constant"); ! } else { ! val = shenandoah_read_barrier(val, NULL, true); ! } } LIR_Address* address; if (needs_patching) { // we need to patch the offset in the instruction so don't allow // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. ! address = new LIR_Address(obj, PATCHED_ADDR, field_type); } else { ! address = generate_address(obj, x->offset(), field_type); } if (is_volatile && os::is_MP()) { __ membar_release(); }
*** 1745,1763 **** (info ? new CodeEmitInfo(info) : NULL)); } bool needs_atomic_access = is_volatile || AlwaysAtomicAccesses; if (needs_atomic_access && !needs_patching) { ! volatile_field_store(value.result(), address, info); } else { LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; ! __ store(value.result(), address, info, patch_code); } if (is_oop) { // Store to object so mark the card of the header ! post_barrier(object.result(), value.result()); } if (is_volatile && os::is_MP()) { __ membar(); } --- 1768,1786 ---- (info ? new CodeEmitInfo(info) : NULL)); } bool needs_atomic_access = is_volatile || AlwaysAtomicAccesses; if (needs_atomic_access && !needs_patching) { ! volatile_field_store(val, address, info); } else { LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; ! __ store(val, address, info, patch_code); } if (is_oop) { // Store to object so mark the card of the header ! post_barrier(obj, val); } if (is_volatile && os::is_MP()) { __ membar(); }
*** 1791,1824 **** tty->print_cr(" ###class not loaded at load_%s bci %d", x->is_static() ? "static" : "field", x->printable_bci()); } #endif bool stress_deopt = StressLoopInvariantCodeMotion && info && info->deoptimize_on_exception(); if (x->needs_null_check() && (needs_patching || MacroAssembler::needs_explicit_null_check(x->offset()) || stress_deopt)) { - LIR_Opr obj = object.result(); if (stress_deopt) { obj = new_register(T_OBJECT); __ move(LIR_OprFact::oopConst(NULL), obj); } // emit an explicit null check because the offset is too large __ null_check(obj, new CodeEmitInfo(info)); } LIR_Opr reg = rlock_result(x, field_type); LIR_Address* address; if (needs_patching) { // we need to patch the offset in the instruction so don't allow // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. ! address = new LIR_Address(object.result(), PATCHED_ADDR, field_type); } else { ! address = generate_address(object.result(), x->offset(), field_type); } bool needs_atomic_access = is_volatile || AlwaysAtomicAccesses; if (needs_atomic_access && !needs_patching) { volatile_field_load(address, reg, info); --- 1814,1848 ---- tty->print_cr(" ###class not loaded at load_%s bci %d", x->is_static() ? "static" : "field", x->printable_bci()); } #endif + LIR_Opr obj = object.result(); bool stress_deopt = StressLoopInvariantCodeMotion && info && info->deoptimize_on_exception(); if (x->needs_null_check() && (needs_patching || MacroAssembler::needs_explicit_null_check(x->offset()) || stress_deopt)) { if (stress_deopt) { obj = new_register(T_OBJECT); __ move(LIR_OprFact::oopConst(NULL), obj); } // emit an explicit null check because the offset is too large __ null_check(obj, new CodeEmitInfo(info)); } + obj = shenandoah_read_barrier(obj, info, x->needs_null_check() && x->explicit_null_check() != NULL); LIR_Opr reg = rlock_result(x, field_type); LIR_Address* address; if (needs_patching) { // we need to patch the offset in the instruction so don't allow // generate_address to try to be smart about emitting the -1. // Otherwise the patching code won't know how to find the // instruction to patch. ! address = new LIR_Address(obj, PATCHED_ADDR, field_type); } else { ! address = generate_address(obj, x->offset(), field_type); } bool needs_atomic_access = is_volatile || AlwaysAtomicAccesses; if (needs_atomic_access && !needs_patching) { volatile_field_load(address, reg, info);
*** 1830,1839 **** --- 1854,1896 ---- if (is_volatile && os::is_MP()) { __ membar_acquire(); } } + LIR_Opr LIRGenerator::shenandoah_read_barrier(LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) { + if (UseShenandoahGC) { + + LabelObj* done = new LabelObj(); + LIR_Opr result = new_register(T_OBJECT); + __ move(obj, result); + if (need_null_check) { + __ cmp(lir_cond_equal, result, LIR_OprFact::oopConst(NULL)); + __ branch(lir_cond_equal, T_LONG, done->label()); + } + LIR_Address* brooks_ptr_address = generate_address(result, -8, T_ADDRESS); + __ load(brooks_ptr_address, result, info ? new CodeEmitInfo(info) : NULL, lir_patch_none); + + __ branch_destination(done->label()); + return result; + } else { + return obj; + } + } + + LIR_Opr LIRGenerator::shenandoah_write_barrier(LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) { + if (UseShenandoahGC) { + + LIR_Opr result = new_register(T_OBJECT); + LIR_Opr tmp1 = new_register(T_INT); + LIR_Opr tmp2 = new_register(T_INT); + __ shenandoah_wb(obj, result, tmp1, tmp2, info ? new CodeEmitInfo(info) : NULL, need_null_check); + return result; + + } else { + return obj; + } + } //------------------------java.nio.Buffer.checkIndex------------------------ // int java.nio.Buffer.checkIndex(int) void LIRGenerator::do_NIOCheckIndex(Intrinsic* x) {
*** 1926,1948 **** __ move(LIR_OprFact::oopConst(NULL), obj); __ null_check(obj, new CodeEmitInfo(null_check_info)); } } // emit array address setup early so it schedules better ! LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false); if (GenerateRangeChecks && needs_range_check) { if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) { __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result())); } else if (use_length) { // TODO: use a (modified) version of array_range_check that does not require a // constant length to be loaded to a register __ cmp(lir_cond_belowEqual, length.result(), index.result()); __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); } else { ! array_range_check(array.result(), index.result(), null_check_info, range_check_info); // The range check performs the null check, so clear it out for the load null_check_info = NULL; } } --- 1983,2008 ---- __ move(LIR_OprFact::oopConst(NULL), obj); __ null_check(obj, new CodeEmitInfo(null_check_info)); } } + LIR_Opr ary = array.result(); + ary = shenandoah_read_barrier(ary, null_check_info, null_check_info != NULL); + // emit array address setup early so it schedules better ! LIR_Address* array_addr = emit_array_address(ary, index.result(), x->elt_type(), false); if (GenerateRangeChecks && needs_range_check) { if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) { __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result())); } else if (use_length) { // TODO: use a (modified) version of array_range_check that does not require a // constant length to be loaded to a register __ cmp(lir_cond_belowEqual, length.result(), index.result()); __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result())); } else { ! array_range_check(ary, index.result(), null_check_info, range_check_info); // The range check performs the null check, so clear it out for the load null_check_info = NULL; } }
*** 2251,2261 **** // pre_barrier(..., value, ...); // } // } // } ! if (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. --- 2311,2321 ---- // pre_barrier(..., value, ...); // } // } // } ! 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.
*** 2793,2802 **** --- 2853,2863 ---- if (method()->is_synchronized() && GenerateSynchronizationCode) { LIR_Opr lock = new_register(T_INT); __ load_stack_address_monitor(0, lock); CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, x->check_flag(Instruction::DeoptimizeOnException)); + obj = shenandoah_write_barrier(obj, info, false); CodeStub* slow_path = new MonitorEnterStub(obj, lock, info); // receiver is guaranteed non-NULL so don't need CodeEmitInfo __ lock_object(syncTempOpr(), obj, lock, new_register(T_OBJECT), slow_path, NULL); }
*** 3013,3025 **** // Code for : x->x() {x->cond()} x->y() ? x->tval() : x->fval() void LIRGenerator::do_IfOp(IfOp* x) { #ifdef ASSERT { - ValueTag xtag = x->x()->type()->tag(); ValueTag ttag = x->tval()->type()->tag(); assert(xtag == intTag || xtag == objectTag, "cannot handle others"); assert(ttag == addressTag || ttag == intTag || ttag == objectTag || ttag == longTag, "cannot handle others"); assert(ttag == x->fval()->type()->tag(), "cannot handle others"); } --- 3074,3086 ---- // Code for : x->x() {x->cond()} x->y() ? x->tval() : x->fval() void LIRGenerator::do_IfOp(IfOp* x) { + ValueTag xtag = x->x()->type()->tag(); #ifdef ASSERT { ValueTag ttag = x->tval()->type()->tag(); assert(xtag == intTag || xtag == objectTag, "cannot handle others"); assert(ttag == addressTag || ttag == intTag || ttag == objectTag || ttag == longTag, "cannot handle others"); assert(ttag == x->fval()->type()->tag(), "cannot handle others"); }
*** 3038,3048 **** LIRItem f_val(x->fval(), this); t_val.dont_load_item(); f_val.dont_load_item(); LIR_Opr reg = rlock_result(x); ! __ cmp(lir_cond(x->cond()), left.result(), right.result()); __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type())); } void LIRGenerator::do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x) { assert(x->number_of_arguments() == expected_arguments, "wrong type"); --- 3099,3116 ---- LIRItem f_val(x->fval(), this); t_val.dont_load_item(); f_val.dont_load_item(); LIR_Opr reg = rlock_result(x); ! LIR_Opr left_opr = left.result(); ! LIR_Opr right_opr = right.result(); ! if (xtag == objectTag && UseShenandoahGC && x->y()->type() != objectNull) { // Don't need to resolve for ifnull. ! left_opr = shenandoah_write_barrier(left_opr, NULL, true); ! right_opr = shenandoah_read_barrier(right_opr, NULL, true); ! } ! ! __ cmp(lir_cond(x->cond()), left_opr, right_opr); __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type())); } void LIRGenerator::do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x) { assert(x->number_of_arguments() == expected_arguments, "wrong type");
< prev index next >