# HG changeset patch # Parent de9088d16202c36fa1eca4ed09fe4ff558efe2ec diff -r de9088d16202 src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Wed Feb 26 14:15:31 2020 +0100 @@ -473,18 +473,18 @@ // 2: load a reference from src location and apply LRB if needed if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) { Register result_dst = dst; - bool use_tmp1_for_dst = false; + //bool use_tmp1_for_dst = false; // Preserve src location for LRB if (dst == src.base() || dst == src.index()) { // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at() - if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) { - dst = tmp1; - use_tmp1_for_dst = true; - } else { + //if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) { + // dst = tmp1; + // use_tmp1_for_dst = true; + //} else { dst = rdi; __ push(dst); - } + //} assert_different_registers(dst, src.base(), src.index()); } @@ -500,9 +500,9 @@ if (dst != result_dst) { __ movptr(result_dst, dst); - if (!use_tmp1_for_dst) { + //if (!use_tmp1_for_dst) { __ pop(dst); - } + //} dst = result_dst; } @@ -511,7 +511,7 @@ } // 3: apply keep-alive barrier if needed - if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) { + //if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) { __ push_IU_state(); // That path can be reached from the c2i adapter with live fp // arguments in registers. @@ -527,10 +527,14 @@ __ movdbl(Address(rsp, 56), xmm7); Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread); - assert_different_registers(dst, tmp1, tmp_thread); if (!thread->is_valid()) { thread = rdx; } + if (!tmp1->is_valid()) { + tmp1 = rscratch1; + } + assert_different_registers(dst, tmp1, thread); + NOT_LP64(__ get_thread(thread)); // Generate the SATB pre-barrier code to log the value of // the referent field in an SATB buffer. @@ -551,7 +555,7 @@ __ movdbl(xmm7, Address(rsp, 56)); __ addptr(rsp, 64); __ pop_IU_state(); - } + //} } void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, @@ -583,7 +587,7 @@ imasm->save_bcp(); #endif - if (needs_pre_barrier) { + if (false && needs_pre_barrier) { shenandoah_write_barrier_pre(masm /*masm*/, tmp1 /* obj */, tmp2 /* pre_val */, diff -r de9088d16202 src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Wed Feb 26 14:15:31 2020 +0100 @@ -182,7 +182,7 @@ void ShenandoahBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { if (access.is_oop()) { - if (ShenandoahSATBBarrier) { + if (false && ShenandoahSATBBarrier) { pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */); } value = storeval_barrier(access.gen(), value, access.access_emit_info(), access.decorators()); @@ -221,27 +221,27 @@ } // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set - if (ShenandoahKeepAliveBarrier) { + if (true || ShenandoahKeepAliveBarrier) { bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0; bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0; bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; - if ((is_weak || is_phantom || is_anonymous) && keep_alive) { + //if ((is_weak || is_phantom || is_anonymous) && keep_alive) { // Register the value in the referent field with the pre-barrier - LabelObj *Lcont_anonymous; - if (is_anonymous) { - Lcont_anonymous = new LabelObj(); - generate_referent_check(access, Lcont_anonymous); - } +// LabelObj *Lcont_anonymous; +// if (is_anonymous) { +// Lcont_anonymous = new LabelObj(); +// generate_referent_check(access, Lcont_anonymous); +// } pre_barrier(gen, access.access_emit_info(), decorators, LIR_OprFact::illegalOpr /* addr_opr */, result /* pre_val */); - if (is_anonymous) { - __ branch_destination(Lcont_anonymous->label()); - } - } - } +// if (is_anonymous) { +// __ branch_destination(Lcont_anonymous->label()); +// } + //} + } } class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure { diff -r de9088d16202 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Wed Feb 26 14:15:31 2020 +0100 @@ -496,45 +496,6 @@ return TypeFunc::make(domain, range); } -Node* ShenandoahBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const { - DecoratorSet decorators = access.decorators(); - - const TypePtr* adr_type = access.addr().type(); - Node* adr = access.addr().node(); - - bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0; - bool on_heap = (decorators & IN_HEAP) != 0; - - if (!access.is_oop() || (!on_heap && !anonymous)) { - return BarrierSetC2::store_at_resolved(access, val); - } - - if (access.is_parse_access()) { - C2ParseAccess& parse_access = static_cast(access); - GraphKit* kit = parse_access.kit(); - - uint adr_idx = kit->C->get_alias_index(adr_type); - assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" ); - Node* value = val.node(); - value = shenandoah_storeval_barrier(kit, value); - val.set_node(value); - shenandoah_write_barrier_pre(kit, true /* do_load */, /*kit->control(),*/ access.base(), adr, adr_idx, val.node(), - static_cast(val.type()), NULL /* pre_val */, access.type()); - } else { - assert(access.is_opt_access(), "only for optimization passes"); - assert(((decorators & C2_TIGHTLY_COUPLED_ALLOC) != 0 || !ShenandoahSATBBarrier) && (decorators & C2_ARRAY_COPY) != 0, "unexpected caller of this code"); - C2OptAccess& opt_access = static_cast(access); - PhaseGVN& gvn = opt_access.gvn(); - MergeMemNode* mm = opt_access.mem(); - - if (ShenandoahStoreValEnqueueBarrier) { - Node* enqueue = gvn.transform(new ShenandoahEnqueueBarrierNode(val.node())); - val.set_node(enqueue); - } - } - return BarrierSetC2::store_at_resolved(access, val); -} - Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const { // 1: non-reference load, no additional barrier is needed if (!access.is_oop()) { @@ -552,8 +513,11 @@ ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)); if (access.is_parse_access()) { load = static_cast(access).kit()->gvn().transform(load); + load = shenandoah_enqueue_barrier(static_cast(access).kit(), load); } else { load = static_cast(access).gvn().transform(load); + load = new ShenandoahEnqueueBarrierNode(load); + load = static_cast(access).gvn().transform(load); } } @@ -587,11 +551,8 @@ bool in_native = (decorators & IN_NATIVE) != 0; bool need_cpu_mem_bar = !is_unordered || mismatched || in_native; + // Use the pre-barrier to record the value in the referent field if (on_weak_ref) { - // Use the pre-barrier to record the value in the referent field - satb_write_barrier_pre(kit, false /* do_load */, - NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, - load /* pre_val */, T_OBJECT); // Add memory barrier to prevent commoning reads from this field // across safepoint since GC can change its value. kit->insert_mem_bar(Op_MemBarCPUOrder); @@ -609,11 +570,6 @@ Node* new_val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { - new_val = shenandoah_storeval_barrier(kit, new_val); - shenandoah_write_barrier_pre(kit, false /* do_load */, - NULL, NULL, max_juint, NULL, NULL, - expected_val /* pre_val */, T_OBJECT); - MemNode::MemOrd mo = access.mem_node_mo(); Node* mem = access.memory(); Node* adr = access.addr().node(); @@ -648,6 +604,7 @@ } #endif load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, false)); + load_store = shenandoah_enqueue_barrier(kit, load_store); return load_store; } return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); @@ -657,10 +614,6 @@ Node* new_val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { - new_val = shenandoah_storeval_barrier(kit, new_val); - shenandoah_write_barrier_pre(kit, false /* do_load */, - NULL, NULL, max_juint, NULL, NULL, - expected_val /* pre_val */, T_OBJECT); DecoratorSet decorators = access.decorators(); MemNode::MemOrd mo = access.mem_node_mo(); Node* mem = access.memory(); @@ -716,9 +669,7 @@ Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type); if (access.is_oop()) { result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, false)); - shenandoah_write_barrier_pre(kit, false /* do_load */, - NULL, NULL, max_juint, NULL, NULL, - result /* pre_val */, T_OBJECT); + result = shenandoah_enqueue_barrier(kit, result); } return result; } @@ -726,6 +677,7 @@ // Support for GC barriers emitted during parsing bool ShenandoahBarrierSetC2::is_gc_barrier_node(Node* node) const { if (node->Opcode() == Op_ShenandoahLoadReferenceBarrier) return true; + if (node->Opcode() == Op_ShenandoahEnqueueBarrier) return true; if (node->Opcode() != Op_CallLeaf && node->Opcode() != Op_CallLeafNoFP) { return false; } diff -r de9088d16202 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp Wed Feb 26 14:15:31 2020 +0100 @@ -83,7 +83,6 @@ protected: virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const; - virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const; virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val, Node* new_val, const Type* val_type) const; virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val, diff -r de9088d16202 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Wed Feb 26 14:15:31 2020 +0100 @@ -886,7 +886,7 @@ } void ShenandoahBarrierC2Support::test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, - PhaseIdealLoop* phase) { + PhaseIdealLoop* phase, jint flag) { IdealLoopTree* loop = phase->get_loop(ctrl); Node* thread = new ThreadLocalNode(); phase->register_new_node(thread, ctrl); @@ -900,7 +900,7 @@ Node* gc_state = new LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered); phase->register_new_node(gc_state, ctrl); - Node* heap_stable_and = new AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED)); + Node* heap_stable_and = new AndINode(gc_state, phase->igvn().intcon(flag)); phase->register_new_node(heap_stable_and, ctrl); Node* heap_stable_cmp = new CmpINode(heap_stable_and, phase->igvn().zerocon(T_INT)); phase->register_new_node(heap_stable_cmp, ctrl); @@ -914,7 +914,7 @@ ctrl = new IfTrueNode(heap_stable_iff); phase->register_control(ctrl, loop, heap_stable_iff); - assert(is_heap_stable_test(heap_stable_iff), "Should match the shape"); + assert(is_heap_state_test(heap_stable_iff, flag), "Should match the shape"); } void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase) { @@ -1633,7 +1633,7 @@ Node* phi2 = PhiNode::make(region2, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); // Stable path. - test_heap_stable(ctrl, raw_mem, heap_stable_ctrl, phase); + test_heap_stable(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::MARKING | ShenandoahHeap::TRAVERSAL); region->init_req(_heap_stable, heap_stable_ctrl); phi->init_req(_heap_stable, raw_mem); @@ -2174,95 +2174,166 @@ return t->is_oopptr(); } -int ShenandoahEnqueueBarrierNode::needed(Node* n) { - if (n == NULL || - n->is_Allocate() || - n->Opcode() == Op_ShenandoahEnqueueBarrier || - n->bottom_type() == TypePtr::NULL_PTR || - (n->bottom_type()->make_oopptr() != NULL && n->bottom_type()->make_oopptr()->const_oop() != NULL)) { - return NotNeeded; - } - if (n->is_Phi() || - n->is_CMove()) { - return MaybeNeeded; - } - return Needed; +bool ShenandoahEnqueueBarrierNode::needs_barrier(PhaseGVN* phase, Node* n) { + Unique_Node_List visited; + return needs_barrier_impl(phase, n, visited); } -Node* ShenandoahEnqueueBarrierNode::next(Node* n) { - for (;;) { - if (n == NULL) { - return n; - } else if (n->bottom_type() == TypePtr::NULL_PTR) { - return n; - } else if (n->bottom_type()->make_oopptr() != NULL && n->bottom_type()->make_oopptr()->const_oop() != NULL) { - return n; - } else if (n->is_ConstraintCast() || - n->Opcode() == Op_DecodeN || - n->Opcode() == Op_EncodeP) { - n = n->in(1); - } else if (n->is_Proj()) { - n = n->in(0); - } else { - return n; +bool ShenandoahEnqueueBarrierNode::needs_barrier_impl(PhaseGVN* phase, Node* n, Unique_Node_List &visited) { + if (n == NULL) return false; + if (visited.member(n)) { + return false; // Been there. + } + visited.push(n); + + if (n->is_Allocate()) { + // tty->print_cr("optimize barrier on alloc"); + return false; + } + if (n->is_Call()) { + // tty->print_cr("optimize barrier on call"); + return false; + } + + const Type* type = phase->type(n); + if (type == Type::TOP) { + return false; + } + if (type->make_ptr()->higher_equal(TypePtr::NULL_PTR)) { + // tty->print_cr("optimize barrier on null"); + return false; + } + if (type->make_oopptr() && type->make_oopptr()->const_oop() != NULL) { + // tty->print_cr("optimize barrier on constant"); + return false; // Needed, apparently + } + + switch (n->Opcode()) { + case Op_ShenandoahEnqueueBarrier: + return false; + case Op_Parm: + return false; + case Op_LoadN: + case Op_LoadP: + case Op_GetAndSetP: + case Op_GetAndSetN: + case Op_CompareAndExchangeP: + case Op_CompareAndExchangeN: + return true; + case Op_Proj: + return needs_barrier_impl(phase, n->in(0), visited); + case Op_DecodeN: + case Op_EncodeP: + case Op_CheckCastPP: + case Op_CastPP: + return needs_barrier_impl(phase, n->in(1), visited); + case Op_ShenandoahLoadReferenceBarrier: + return needs_barrier_impl(phase, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), visited); + case Op_CMoveN: + case Op_CMoveP: + return needs_barrier_impl(phase, n->in(2), visited) || + needs_barrier_impl(phase, n->in(3), visited); + case Op_Phi: { + for (uint i = 1; i < n->req(); i++) { + if (needs_barrier_impl(phase, n->in(i), visited)) return true; + } + return false; + } + default: + break; + } +#ifdef ASSERT + tty->print("need enqueue barrier on?: "); + tty->print_cr("ins:"); + n->dump(2); + tty->print_cr("outs:"); + n->dump(-2); + ShouldNotReachHere(); +#endif + return true; +} + +bool ShenandoahEnqueueBarrierNode::is_useful() { + Unique_Node_List visited; + Node_Stack stack(0); + stack.push(this, 0); + + bool useful = false; + while (!useful && stack.size() > 0) { + Node* n = stack.node(); + if (visited.member(n)) { + stack.pop(); + continue; + } + visited.push(n); + bool visit_users = false; + switch (n->Opcode()) { + case Op_CallDynamicJava: + case Op_CallStaticJava: + case Op_CompareAndExchangeN: + case Op_CompareAndExchangeP: + case Op_CompareAndSwapN: + case Op_CompareAndSwapP: + case Op_GetAndSetN: + case Op_GetAndSetP: + case Op_Return: + case Op_StoreN: + case Op_StoreP: + useful = true; + break; + case Op_AddP: + case Op_Allocate: + case Op_AllocateArray: + case Op_ArrayCopy: + case Op_CmpP: + case Op_LoadL: + case Op_SafePoint: + case Op_SubTypeCheck: + // useful = false; + break; + case Op_CastPP: + case Op_CheckCastPP: + case Op_CMoveN: + case Op_CMoveP: + case Op_EncodeP: + case Op_Phi: + case Op_ShenandoahEnqueueBarrier: + visit_users = true; + break; + default: { +#ifdef ASSERT + //fatal("Unknown node in get_barrier_strength: %s", NodeClassNames[n->Opcode()]); + useful = true; +#else + // Default to strong: better to have excess barriers, rather than miss some. + useful = true; +#endif + } + } + + stack.pop(); + if (visit_users) { + for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { + Node* user = n->fast_out(i); + if (user != NULL) { + stack.push(user, 0); + } + } } } - ShouldNotReachHere(); - return NULL; + return useful; } Node* ShenandoahEnqueueBarrierNode::Identity(PhaseGVN* phase) { PhaseIterGVN* igvn = phase->is_IterGVN(); - - Node* n = next(in(1)); - - int cont = needed(n); - - if (cont == NotNeeded) { - return in(1); - } else if (cont == MaybeNeeded) { - if (igvn == NULL) { - phase->record_for_igvn(this); - return this; - } else { - ResourceMark rm; - Unique_Node_List wq; - uint wq_i = 0; - - for (;;) { - if (n->is_Phi()) { - for (uint i = 1; i < n->req(); i++) { - Node* m = n->in(i); - if (m != NULL) { - wq.push(m); - } - } - } else { - assert(n->is_CMove(), "nothing else here"); - Node* m = n->in(CMoveNode::IfFalse); - wq.push(m); - m = n->in(CMoveNode::IfTrue); - wq.push(m); - } - Node* orig_n = NULL; - do { - if (wq_i >= wq.size()) { - return in(1); - } - n = wq.at(wq_i); - wq_i++; - orig_n = n; - n = next(n); - cont = needed(n); - if (cont == Needed) { - return this; - } - } while (cont != MaybeNeeded || (orig_n != n && wq.member(n))); - } - } + Node* value = in(1); + if (!needs_barrier(phase, value)) { + return value; + } else if (phase->is_IterGVN() && !is_useful()) { + return value; + } else { + return this; } - - return this; } #ifdef ASSERT @@ -3286,7 +3357,6 @@ case Op_GetAndAddI: case Op_GetAndAddB: case Op_GetAndAddS: - case Op_ShenandoahEnqueueBarrier: case Op_FastLock: case Op_FastUnlock: case Op_Rethrow: @@ -3364,6 +3434,7 @@ case Op_CMoveP: case Op_Phi: case Op_ShenandoahLoadReferenceBarrier: + case Op_ShenandoahEnqueueBarrier: // Whether or not these need the barriers depends on their users visit_users = true; break; diff -r de9088d16202 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Wed Feb 26 14:15:31 2020 +0100 @@ -60,7 +60,7 @@ static void follow_barrier_uses(Node* n, Node* ctrl, Unique_Node_List& uses, PhaseIdealLoop* phase); static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase); static void test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, - PhaseIdealLoop* phase); + PhaseIdealLoop* phase, jint flag = ShenandoahHeap::HAS_FORWARDED); static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase); static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase); static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses, @@ -102,8 +102,9 @@ private: enum { Needed, NotNeeded, MaybeNeeded }; - static int needed(Node* n); - static Node* next(Node* n); + bool needs_barrier(PhaseGVN* phase, Node* n); + bool needs_barrier_impl(PhaseGVN* phase, Node* n, Unique_Node_List &visited); + bool is_useful(); }; class MemoryGraphFixer : public ResourceObj { diff -r de9088d16202 src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Wed Feb 26 14:15:31 2020 +0100 @@ -106,11 +106,7 @@ template inline void ShenandoahBarrierSet::keep_alive_if_weak(oop value) { - assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known"); - if (!HasDecorator::value && - !HasDecorator::value) { - keep_alive_barrier(value); - } + keep_alive_barrier(value); } template @@ -157,7 +153,7 @@ shenandoah_assert_marked_if(NULL, value, !CompressedOops::is_null(value) && ShenandoahHeap::heap()->is_evacuation_in_progress()); ShenandoahBarrierSet* const bs = ShenandoahBarrierSet::barrier_set(); bs->storeval_barrier(value); - bs->satb_barrier(addr); + //bs->satb_barrier(addr); Raw::oop_store(addr, value); } diff -r de9088d16202 src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Tue Feb 18 17:20:04 2020 +0100 +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Wed Feb 26 14:15:31 2020 +0100 @@ -186,15 +186,20 @@ private: ShenandoahSATBBufferClosure* _satb_cl; uintx _claim_token; + OopClosure* const _cl; + CodeBlobClosure* const _code_cl; public: - ShenandoahSATBThreadsClosure(ShenandoahSATBBufferClosure* satb_cl) : + ShenandoahSATBThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, OopClosure* cl, CodeBlobClosure* code_cl) : _satb_cl(satb_cl), - _claim_token(Threads::thread_claim_token()) {} + _claim_token(Threads::thread_claim_token()), + _cl(cl), _code_cl(code_cl) {} void do_thread(Thread* thread) { if (thread->claim_threads_do(true, _claim_token)) { ShenandoahThreadLocalData::satb_mark_queue(thread).apply_closure_and_empty(_satb_cl); + ResourceMark rm; + thread->oops_do(_cl, _code_cl); } } }; @@ -221,11 +226,21 @@ // full-gc. { ShenandoahObjToScanQueue* q = _cm->get_queue(worker_id); - ShenandoahSATBBufferClosure cl(q); + ShenandoahSATBBufferClosure buf_cl(q); SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set(); - while (satb_mq_set.apply_closure_to_completed_buffer(&cl)); - ShenandoahSATBThreadsClosure tc(&cl); - Threads::threads_do(&tc); + while (satb_mq_set.apply_closure_to_completed_buffer(&buf_cl)); + ReferenceProcessor* rp = heap->ref_processor(); + if (heap->has_forwarded_objects()) { + ShenandoahMarkResolveRefsClosure cl(q, rp); + CodeBlobToOopClosure code_cl(&cl, false); + ShenandoahSATBThreadsClosure tc(&buf_cl, &cl, &code_cl); + Threads::threads_do(&tc); + } else { + ShenandoahMarkRefsClosure cl(q, rp); + CodeBlobToOopClosure code_cl(&cl, false); + ShenandoahSATBThreadsClosure tc(&buf_cl, &cl, &code_cl); + Threads::threads_do(&tc); + } } ReferenceProcessor* rp;