# HG changeset patch # User zgu # Date 1582650095 18000 # Tue Feb 25 12:01:35 2020 -0500 # Node ID df62c177841eeb85dcb91ec744487fe90cdfd7be # Parent ce1281b3e5aa0e7c2bedc5a62d44a2450c649606 [backport] 8239926: Shenandoah: Shenandoah needs to mark nmethod's metadata Reviewed-by: rkennke, shade diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp @@ -215,14 +215,15 @@ } }; -class ShenandoahSATBThreadsClosure : public ThreadClosure { +class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure { private: ShenandoahSATBBufferClosure* _satb_cl; + MarkingCodeBlobClosure* _code_cl; int _thread_parity; public: - ShenandoahSATBThreadsClosure(ShenandoahSATBBufferClosure* satb_cl) : - _satb_cl(satb_cl), + ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, MarkingCodeBlobClosure* code_cl) : + _satb_cl(satb_cl), _code_cl(code_cl), _thread_parity(SharedHeap::heap()->strong_roots_parity()) {} void do_thread(Thread* thread) { @@ -230,6 +231,15 @@ if (thread->claim_oops_do(true, _thread_parity)) { JavaThread* jt = (JavaThread*)thread; jt->satb_mark_queue().apply_closure_and_empty(_satb_cl); + if (_code_cl != NULL) { + // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking + // however the liveness of oops reachable from nmethods have very complex lifecycles: + // * Alive if on the stack of an executing method + // * Weakly reachable otherwise + // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be + // live by the SATB invariant but other oops recorded in nmethods may behave differently. + jt->nmethods_do(_code_cl); + } } } else if (thread->is_VM_thread()) { if (thread->claim_oops_do(true, _thread_parity)) { @@ -253,6 +263,14 @@ void work(uint worker_id) { ShenandoahHeap* heap = ShenandoahHeap::heap(); + ReferenceProcessor* rp; + if (heap->process_references()) { + rp = heap->ref_processor(); + shenandoah_assert_rp_isalive_installed(); + } else { + rp = NULL; + } + // First drain remaining SATB buffers. // Notice that this is not strictly necessary for mark-compact. But since // it requires a StrongRootsScope around the task, we need to claim the @@ -267,16 +285,22 @@ ShenandoahSATBBufferClosure cl(q, dq); SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); while (satb_mq_set.apply_closure_to_completed_buffer(&cl)); - ShenandoahSATBThreadsClosure tc(&cl); - Threads::threads_do(&tc); - } - - ReferenceProcessor* rp; - if (heap->process_references()) { - rp = heap->ref_processor(); - shenandoah_assert_rp_isalive_installed(); - } else { - rp = NULL; + if (heap->unload_classes()) { + if (heap->has_forwarded_objects()) { + ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp); + MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations); + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, &blobsCl); + Threads::threads_do(&tc); + } else { + ShenandoahMarkRefsClosure mark_cl(q, rp); + MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations); + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, &blobsCl); + Threads::threads_do(&tc); + } + } else { + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, NULL); + Threads::threads_do(&tc); + } } if (heap->is_degenerated_gc_in_progress()) { # HG changeset patch # User roland # Date 1585042297 -3600 # Tue Mar 24 10:31:37 2020 +0100 # Node ID c30b6a2e27c434134a1c2821ee7896aacc5fcc89 # Parent df62c177841eeb85dcb91ec744487fe90cdfd7be [backport] 8241675: Shenandoah: assert(n->outcnt() > 0) at shenandoahSupport.cpp:2858 with java/util/Collections/FindSubList.java Reviewed-by: rkennke diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp @@ -2306,41 +2306,6 @@ bool create_phi = true; if (_phase->is_dominator(new_ctrl, u)) { create_phi = false; - } else if (!_phase->C->has_irreducible_loop()) { - IdealLoopTree* loop = _phase->get_loop(ctrl); - bool do_check = true; - IdealLoopTree* l = loop; - create_phi = false; - while (l != _phase->ltree_root()) { - Node* head = l->_head; - if (head->in(0) == NULL) { - head = _phase->get_ctrl(head); - } - if (_phase->is_dominator(head, u) && _phase->is_dominator(_phase->idom(u), head)) { - create_phi = true; - do_check = false; - break; - } - l = l->_parent; - } - - if (do_check) { - assert(!create_phi, ""); - IdealLoopTree* u_loop = _phase->get_loop(u); - if (u_loop != _phase->ltree_root() && u_loop->is_member(loop)) { - Node* c = ctrl; - while (!_phase->is_dominator(c, u_loop->tail())) { - c = _phase->idom(c); - } - if (!_phase->is_dominator(c, u)) { - do_check = false; - } - } - } - - if (do_check && _phase->is_dominator(_phase->idom(u), new_ctrl)) { - create_phi = true; - } } if (create_phi) { Node* phi = new (_phase->C) PhiNode(u, Type::MEMORY, _phase->C->get_adr_type(_alias)); # HG changeset patch # User rkennke # Date 1585309656 -3600 # Fri Mar 27 12:47:36 2020 +0100 # Node ID f33666b9f05e3adddb0779412bb4fcf41fc6c571 # Parent c30b6a2e27c434134a1c2821ee7896aacc5fcc89 [backport] 8241700: Shenandoah: Fold ShenandoahKeepAliveBarrier flag into ShenandoahSATBBarrier Reviewed-by: shade diff --git a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp --- a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp +++ b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp @@ -1944,7 +1944,7 @@ __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value)); __ verify_oop(r0); #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { __ g1_write_barrier_pre(noreg /* obj */, r0 /* pre_val */, rthread /* thread */, diff --git a/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp b/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp --- a/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp +++ b/src/cpu/aarch64/vm/templateInterpreter_aarch64.cpp @@ -693,7 +693,7 @@ const int referent_offset = java_lang_ref_Reference::referent_offset; guarantee(referent_offset > 0, "referent offset not initialized"); - if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { Label slow_path; const Register local_0 = c_rarg0; // Check if local 0 != NULL @@ -1187,7 +1187,7 @@ // Resolve jweak. __ ldr(r0, Address(r0, -JNIHandles::weak_tag_value)); #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { __ enter(); // Barrier may call runtime. __ g1_write_barrier_pre(noreg /* obj */, r0 /* pre_val */, diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -863,7 +863,7 @@ // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. - if (!UseShenandoahGC || ShenandoahKeepAliveBarrier) { + if (!UseShenandoahGC || ShenandoahSATBBarrier) { __ get_thread(rcx); __ g1_write_barrier_pre(noreg /* obj */, rax /* pre_val */, diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -815,7 +815,7 @@ // Generate the G1 pre-barrier code to log the value of // the referent field in an SATB buffer. - if (!UseShenandoahGC || ShenandoahKeepAliveBarrier) { + if (!UseShenandoahGC || ShenandoahSATBBarrier) { if (UseShenandoahGC) __ push_IU_state(); __ g1_write_barrier_pre(noreg /* obj */, rax /* pre_val */, diff --git a/src/share/vm/classfile/symbolTable.cpp b/src/share/vm/classfile/symbolTable.cpp --- a/src/share/vm/classfile/symbolTable.cpp +++ b/src/share/vm/classfile/symbolTable.cpp @@ -721,7 +721,7 @@ // considered dead. The SATB part of G1 needs to get notified about this // potential resurrection, otherwise the marking might not find the object. #if INCLUDE_ALL_GCS - if ((UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) && string != NULL) { + if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && string != NULL) { G1SATBCardTableModRefBS::enqueue(string); } #endif diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -45,7 +45,6 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -44,7 +44,6 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp @@ -37,7 +37,6 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp @@ -217,12 +217,6 @@ } } -void ShenandoahBarrierSet::keep_alive_barrier(oop obj) { - if (ShenandoahKeepAliveBarrier && _heap->is_concurrent_mark_in_progress()) { - enqueue(obj); - } -} - void ShenandoahBarrierSet::enqueue(oop obj) { assert(JavaThread::satb_mark_queue_set().shared_satb_queue()->is_active(), "only get here when SATB active"); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp @@ -111,7 +111,6 @@ static inline oop resolve_forwarded(oop p); void storeval_barrier(oop obj); - void keep_alive_barrier(oop obj); oop load_reference_barrier(oop obj); oop load_reference_barrier_mutator(oop obj); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp @@ -35,7 +35,6 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahKeepAliveBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.cpp @@ -42,7 +42,6 @@ // Disable known barriers by default. SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahLoadRefBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahSATBBarrier); - SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahKeepAliveBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStoreValEnqueueBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCASBarrier); SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp @@ -316,9 +316,6 @@ diagnostic(bool, ShenandoahSATBBarrier, true, \ "Turn on/off SATB barriers in Shenandoah") \ \ - diagnostic(bool, ShenandoahKeepAliveBarrier, true, \ - "Turn on/off keep alive barriers in Shenandoah") \ - \ diagnostic(bool, ShenandoahStoreValEnqueueBarrier, false, \ "Turn on/off enqueuing of oops for storeval barriers") \ \ diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp +++ b/src/share/vm/prims/jni.cpp @@ -2630,7 +2630,7 @@ // If G1 is enabled and we are accessing the value of the referent // field in a reference object then we need to register a non-null // referent with the SATB barrier. - if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { bool needs_barrier = false; if (ret != NULL && diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp +++ b/src/share/vm/prims/jvm.cpp @@ -589,7 +589,7 @@ // If G1 is enabled then we need to register a non-null referent // with the SATB barrier. #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { oop referent = java_lang_ref_Reference::referent(clone); if (referent != NULL) { G1SATBCardTableModRefBS::enqueue(referent); diff --git a/src/share/vm/prims/jvmtiGetLoadedClasses.cpp b/src/share/vm/prims/jvmtiGetLoadedClasses.cpp --- a/src/share/vm/prims/jvmtiGetLoadedClasses.cpp +++ b/src/share/vm/prims/jvmtiGetLoadedClasses.cpp @@ -46,7 +46,7 @@ // to get notified about this potential resurrection, otherwise the marking // might not find the object. #if INCLUDE_ALL_GCS - if ((o != NULL) && (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier))) { + if ((o != NULL) && (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier))) { G1SATBCardTableModRefBS::enqueue(o); } #endif diff --git a/src/share/vm/prims/jvmtiTagMap.cpp b/src/share/vm/prims/jvmtiTagMap.cpp --- a/src/share/vm/prims/jvmtiTagMap.cpp +++ b/src/share/vm/prims/jvmtiTagMap.cpp @@ -1521,7 +1521,7 @@ oop o = entry->object(); assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); #if INCLUDE_ALL_GCS - if (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) { + if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) { // The reference in this tag map could be the only (implicitly weak) // reference to that object. If we hand it out, we need to keep it live wrt // SATB marking similar to other j.l.ref.Reference referents. diff --git a/src/share/vm/prims/unsafe.cpp b/src/share/vm/prims/unsafe.cpp --- a/src/share/vm/prims/unsafe.cpp +++ b/src/share/vm/prims/unsafe.cpp @@ -218,7 +218,7 @@ static void ensure_satb_referent_alive(oop o, jlong offset, oop v) { #if INCLUDE_ALL_GCS - if ((UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) { + if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && v != NULL && is_java_lang_ref_Reference_access(o, offset)) { G1SATBCardTableModRefBS::enqueue(v); } #endif diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp +++ b/src/share/vm/runtime/arguments.cpp @@ -1733,7 +1733,6 @@ FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false); FLAG_SET_DEFAULT(ShenandoahLoadRefBarrier, false); - FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false); FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, false); FLAG_SET_DEFAULT(ShenandoahCASBarrier, false); FLAG_SET_DEFAULT(ShenandoahCloneBarrier, false); @@ -1846,7 +1845,6 @@ if (ShenandoahVerifyOptoBarriers && (!FLAG_IS_DEFAULT(ShenandoahSATBBarrier) || !FLAG_IS_DEFAULT(ShenandoahLoadRefBarrier) || - !FLAG_IS_DEFAULT(ShenandoahKeepAliveBarrier) || !FLAG_IS_DEFAULT(ShenandoahStoreValEnqueueBarrier) || !FLAG_IS_DEFAULT(ShenandoahCASBarrier) || !FLAG_IS_DEFAULT(ShenandoahCloneBarrier) diff --git a/src/share/vm/runtime/jniHandles.cpp b/src/share/vm/runtime/jniHandles.cpp --- a/src/share/vm/runtime/jniHandles.cpp +++ b/src/share/vm/runtime/jniHandles.cpp @@ -116,7 +116,7 @@ oop result = jweak_ref(handle); result = guard_value<external_guard>(result); #if INCLUDE_ALL_GCS - if (result != NULL && (UseG1GC || (UseShenandoahGC && ShenandoahKeepAliveBarrier))) { + if (result != NULL && (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier))) { G1SATBCardTableModRefBS::enqueue(result); } #endif // INCLUDE_ALL_GCS diff --git a/test/gc/shenandoah/options/TestWrongBarrierDisable.java b/test/gc/shenandoah/options/TestWrongBarrierDisable.java --- a/test/gc/shenandoah/options/TestWrongBarrierDisable.java +++ b/test/gc/shenandoah/options/TestWrongBarrierDisable.java @@ -40,7 +40,6 @@ "ShenandoahCASBarrier", "ShenandoahCloneBarrier", "ShenandoahSATBBarrier", - "ShenandoahKeepAliveBarrier", }; shouldFailAll("-XX:ShenandoahGCHeuristics=adaptive", concurrent); # HG changeset patch # User rkennke # Date 1586173527 -7200 # Mon Apr 06 13:45:27 2020 +0200 # Node ID fcf19e0cd2c176e1f2f95e4a880cebfa0650e954 # Parent f33666b9f05e3adddb0779412bb4fcf41fc6c571 [backport] 8242130: Shenandoah: Simplify arraycopy-barrier dispatching Reviewed-by: shade diff --git a/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp b/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp --- a/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp @@ -49,7 +49,7 @@ // Avoid calling runtime if count == 0 __ cbz(count, done); - // Is marking active? + // Is GC active? Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset())); __ ldrb(rscratch1, gc_state); if (dest_uninitialized) { @@ -62,17 +62,9 @@ __ push_call_clobbered_registers(); if (UseCompressedOops) { - if (dest_uninitialized) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry), src, dst, count); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), src, dst, count); - } + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry), src, dst, count); } else { - if (dest_uninitialized) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry), src, dst, count); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), src, dst, count); - } + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), src, dst, count); } __ pop_call_clobbered_registers(); __ bind(done); diff --git a/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp b/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp --- a/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp @@ -67,7 +67,7 @@ __ testptr(count, count); __ jcc(Assembler::zero, done); - // Avoid runtime call when not marking. + // Avoid runtime call when not active. Address gc_state(thread, in_bytes(JavaThread::gc_state_offset())); int flags = ShenandoahHeap::HAS_FORWARDED; if (!dest_uninitialized) { @@ -77,6 +77,7 @@ __ jcc(Assembler::zero, done); __ pusha(); // push registers + #ifdef _LP64 assert(src == rdi, "expected"); assert(dst == rsi, "expected"); @@ -84,20 +85,15 @@ // register into right place. // assert(count == rdx, "expected"); if (UseCompressedOops) { - if (dest_uninitialized) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry), src, dst, count); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry), src, dst, count); - } + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry), + src, dst, count); } else #endif - { - if (dest_uninitialized) { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry), src, dst, count); - } else { - __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_array_pre_oop_entry), src, dst, count); - } - } + { + __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop_entry), + src, dst, count); + } + __ popa(); __ bind(done); NOT_LP64(__ pop(thread);) diff --git a/src/share/vm/c1/c1_Runtime1.cpp b/src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp +++ b/src/share/vm/c1/c1_Runtime1.cpp @@ -1313,7 +1313,7 @@ #if INCLUDE_ALL_GCS if (UseShenandoahGC) { - ShenandoahBarrierSet::barrier_set()->arraycopy_pre(src_addr, dst_addr, length); + ShenandoahBarrierSet::barrier_set()->arraycopy_barrier(src_addr, dst_addr, length); } #endif diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp @@ -39,7 +39,7 @@ ShenandoahBarrierSetC1* const _bsc1; ShenandoahBarrierSetC2* const _bsc2; - inline bool skip_bulk_update(HeapWord* dst); + inline bool need_bulk_update(HeapWord* dst); public: ShenandoahBarrierSet(ShenandoahHeap* heap); @@ -85,13 +85,8 @@ void write_ref_array_work(MemRegion mr) {} - template <class T> void - write_ref_array_pre_work(T* src, T* dst, size_t count, bool dest_uninitialized); - - inline void arraycopy_pre(oop* src, oop* dst, size_t count); - inline void arraycopy_pre(narrowOop* src, narrowOop* dst, size_t count); - inline void arraycopy_update(oop* src, size_t count); - inline void arraycopy_update(narrowOop* src, size_t count); + template <class T> + inline void arraycopy_barrier(T* src, T* dst, size_t count); inline void clone_barrier(oop src); void clone_barrier_runtime(oop src); @@ -122,11 +117,14 @@ private: template <class T> - inline void arraycopy_pre_work(T* src, T* dst, size_t count); + inline void arraycopy_marking(T* ary, size_t count); + template <class T> + inline void arraycopy_evacuation(T* src, size_t count); + template <class T> + inline void arraycopy_update(T* src, size_t count); + template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE> inline void arraycopy_work(T* src, size_t count); - template <class T> - inline void arraycopy_update_impl(T* src, size_t count); oop load_reference_barrier_impl(oop obj); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp @@ -74,46 +74,47 @@ } template <class T> -void ShenandoahBarrierSet::arraycopy_pre_work(T* src, T* dst, size_t count) { - if (_heap->is_concurrent_mark_in_progress() && - !_heap->marking_context()->allocated_after_mark_start(reinterpret_cast<HeapWord*>(dst))) { - arraycopy_work<T, false, false, true>(dst, count); +void ShenandoahBarrierSet::arraycopy_barrier(T* src, T* dst, size_t count) { + if (count == 0) { + return; } - - if (_heap->has_forwarded_objects()) { - arraycopy_update_impl(src, count); + int gc_state = _heap->gc_state(); + if ((gc_state & ShenandoahHeap::MARKING) != 0) { + arraycopy_marking(dst, count); + } else if ((gc_state & ShenandoahHeap::EVACUATION) != 0) { + arraycopy_evacuation(src, count); + } else if ((gc_state & ShenandoahHeap::UPDATEREFS) != 0) { + arraycopy_update(src, count); } } -void ShenandoahBarrierSet::arraycopy_pre(oop* src, oop* dst, size_t count) { - arraycopy_pre_work(src, dst, count); +template <class T> +void ShenandoahBarrierSet::arraycopy_marking(T* array, size_t count) { + assert(_heap->is_concurrent_mark_in_progress(), "only during marking"); + if (!_heap->marking_context()->allocated_after_mark_start(reinterpret_cast<HeapWord*>(array))) { + arraycopy_work<T, false, false, true>(array, count); + } } -void ShenandoahBarrierSet::arraycopy_pre(narrowOop* src, narrowOop* dst, size_t count) { - arraycopy_pre_work(src, dst, count); -} - -inline bool ShenandoahBarrierSet::skip_bulk_update(HeapWord* dst) { - return dst >= _heap->heap_region_containing(dst)->get_update_watermark(); +inline bool ShenandoahBarrierSet::need_bulk_update(HeapWord* ary) { + return ary < _heap->heap_region_containing(ary)->get_update_watermark(); } template <class T> -void ShenandoahBarrierSet::arraycopy_update_impl(T* src, size_t count) { - if (skip_bulk_update(reinterpret_cast<HeapWord*>(src))) return; - if (_heap->is_evacuation_in_progress()) { +void ShenandoahBarrierSet::arraycopy_evacuation(T* src, size_t count) { + assert(_heap->is_evacuation_in_progress(), "only during evacuation"); + if (need_bulk_update(reinterpret_cast<HeapWord*>(src))) { ShenandoahEvacOOMScope oom_evac; arraycopy_work<T, true, true, false>(src, count); - } else if (_heap->has_forwarded_objects()) { + } +} + +template <class T> +void ShenandoahBarrierSet::arraycopy_update(T* src, size_t count) { + assert(_heap->is_update_refs_in_progress(), "only during update-refs"); + if (need_bulk_update(reinterpret_cast<HeapWord*>(src))) { arraycopy_work<T, true, false, false>(src, count); } } -void ShenandoahBarrierSet::arraycopy_update(oop* src, size_t count) { - arraycopy_update_impl(src, count); -} - -void ShenandoahBarrierSet::arraycopy_update(narrowOop* src, size_t count) { - arraycopy_update_impl(src, count); -} - #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp @@ -80,7 +80,7 @@ // that potentially need to be updated. shenandoah_assert_correct(NULL, obj); - if (skip_bulk_update(cast_from_oop<HeapWord*>(obj))) return; + if (!need_bulk_update(cast_from_oop<HeapWord*>(obj))) return; if (_heap->is_evacuation_in_progress()) { ShenandoahEvacOOMScope evac_scope; ShenandoahUpdateRefsForOopClosure</* evac = */ true, /* enqueue */ false> cl; diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp @@ -28,24 +28,14 @@ #include "runtime/interfaceSupport.hpp" #include "oops/oop.inline.hpp" -void ShenandoahRuntime::write_ref_array_pre_oop_entry(oop* src, oop* dst, size_t length) { +void ShenandoahRuntime::arraycopy_barrier_oop_entry(oop* src, oop* dst, size_t length) { ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); - bs->arraycopy_pre(src, dst, length); + bs->arraycopy_barrier(src, dst, length); } -void ShenandoahRuntime::write_ref_array_pre_narrow_oop_entry(narrowOop* src, narrowOop* dst, size_t length) { - ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); - bs->arraycopy_pre(src, dst, length); -} - -void ShenandoahRuntime::write_ref_array_pre_duinit_oop_entry(oop* src, oop* dst, size_t length) { +void ShenandoahRuntime::arraycopy_barrier_narrow_oop_entry(narrowOop* src, narrowOop* dst, size_t length) { ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); - bs->arraycopy_update(src, length); -} - -void ShenandoahRuntime::write_ref_array_pre_duinit_narrow_oop_entry(narrowOop* src, narrowOop* dst, size_t length) { - ShenandoahBarrierSet *bs = ShenandoahBarrierSet::barrier_set(); - bs->arraycopy_update(src, length); + bs->arraycopy_barrier(src, dst, length); } // Shenandoah pre write barrier slowpath diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.hpp @@ -33,10 +33,9 @@ class ShenandoahRuntime : public AllStatic { public: - static void write_ref_array_pre_oop_entry(oop* src, oop* dst, size_t length); - static void write_ref_array_pre_narrow_oop_entry(narrowOop* src, narrowOop* dst, size_t length); - static void write_ref_array_pre_duinit_oop_entry(oop* src, oop* dst, size_t length); - static void write_ref_array_pre_duinit_narrow_oop_entry(narrowOop* src, narrowOop* dst, size_t length); + static void arraycopy_barrier_oop_entry(oop* src, oop* dst, size_t length); + static void arraycopy_barrier_narrow_oop_entry(narrowOop* src, narrowOop* dst, size_t length); + static void write_ref_field_pre_entry(oopDesc* orig, JavaThread* thread); static oopDesc* load_reference_barrier(oopDesc* src); diff --git a/src/share/vm/oops/objArrayKlass.cpp b/src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp +++ b/src/share/vm/oops/objArrayKlass.cpp @@ -247,7 +247,7 @@ #if INCLUDE_ALL_GCS if (UseShenandoahGC) { - ShenandoahBarrierSet::barrier_set()->arraycopy_pre(src, dst, length); + ShenandoahBarrierSet::barrier_set()->arraycopy_barrier(src, dst, length); } #endif # HG changeset patch # User rkennke # Date 1586183344 -7200 # Mon Apr 06 16:29:04 2020 +0200 # Node ID fb9ff8b01d3ac331309e9cee05e02e0f75284366 # Parent fcf19e0cd2c176e1f2f95e4a880cebfa0650e954 [backport] 8242217: Shenandoah: Enable GC mode to be diagnostic/experimental and have a name Reviewed-by: shade diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp @@ -397,6 +397,19 @@ ShouldNotReachHere(); } _gc_mode->initialize_flags(); + if (_gc_mode->is_diagnostic() && !UnlockDiagnosticVMOptions) { + vm_exit_during_initialization( + err_msg("GC mode \"%s\" is diagnostic, and must be enabled via -XX:+UnlockDiagnosticVMOptions.", + _gc_mode->name())); + } + if (_gc_mode->is_experimental() && !UnlockExperimentalVMOptions) { + vm_exit_during_initialization( + err_msg("GC mode \"%s\" is experimental, and must be enabled via -XX:+UnlockExperimentalVMOptions.", + _gc_mode->name())); + } + log_info(gc, init)("Shenandoah GC mode: %s", + _gc_mode->name()); + _heuristics = _gc_mode->initialize_heuristics(); if (_heuristics->is_diagnostic() && !UnlockDiagnosticVMOptions) { diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp @@ -32,6 +32,9 @@ public: virtual void initialize_flags() const = 0; virtual ShenandoahHeuristics* initialize_heuristics() const = 0; + virtual const char* name() = 0; + virtual bool is_diagnostic() = 0; + virtual bool is_experimental() = 0; }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHMODE_HPP diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.hpp @@ -32,6 +32,9 @@ public: virtual void initialize_flags() const; virtual ShenandoahHeuristics* initialize_heuristics() const; + virtual const char* name() { return "Normal"; } + virtual bool is_diagnostic() { return false; } + virtual bool is_experimental() { return false; } }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahPassiveMode.hpp @@ -30,6 +30,10 @@ public: virtual void initialize_flags() const; virtual ShenandoahHeuristics* initialize_heuristics() const; + + virtual const char* name() { return "Passive"; } + virtual bool is_diagnostic() { return true; } + virtual bool is_experimental() { return false; } }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHNORMALMODE_HPP # HG changeset patch # User rkennke # Date 1586185726 -7200 # Mon Apr 06 17:08:46 2020 +0200 # Node ID a222813e5654b4a6809ad0233238300f862565c2 # Parent fb9ff8b01d3ac331309e9cee05e02e0f75284366 [backport] 8242054: Shenandoah: New incremental-update mode Reviewed-by: shade diff --git a/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp b/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp --- a/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp +++ b/src/cpu/aarch64/vm/shenandoahBarrierSetAssembler_aarch64.cpp @@ -42,7 +42,7 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, bool dest_uninitialized, Register src, Register dst, Register count) { - if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) { + if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahStoreValEnqueueBarrier || ShenandoahLoadRefBarrier) { Label done; @@ -52,7 +52,7 @@ // Is GC active? Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset())); __ ldrb(rscratch1, gc_state); - if (dest_uninitialized) { + if (ShenandoahSATBBarrier && dest_uninitialized) { __ tbz(rscratch1, ShenandoahHeap::HAS_FORWARDED_BITPOS, done); } else { __ mov(rscratch2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING); diff --git a/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp b/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp --- a/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp +++ b/src/cpu/x86/vm/shenandoahBarrierSetAssembler_x86.cpp @@ -43,7 +43,7 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, bool dest_uninitialized, Register src, Register dst, Register count) { - if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) { + if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahStoreValEnqueueBarrier || ShenandoahLoadRefBarrier) { #ifdef _LP64 Register thread = r15_thread; #else @@ -69,9 +69,11 @@ // Avoid runtime call when not active. Address gc_state(thread, in_bytes(JavaThread::gc_state_offset())); - int flags = ShenandoahHeap::HAS_FORWARDED; - if (!dest_uninitialized) { - flags |= ShenandoahHeap::MARKING; + int flags; + if (ShenandoahSATBBarrier && dest_uninitialized) { + flags = ShenandoahHeap::HAS_FORWARDED; + } else { + flags = ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::MARKING; } __ testb(gc_state, flags); __ jcc(Assembler::zero, done); diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -44,7 +44,7 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier || ShenandoahStoreValEnqueueBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -43,7 +43,7 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier || ShenandoahStoreValEnqueueBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp @@ -36,7 +36,7 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier || ShenandoahStoreValEnqueueBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp @@ -212,7 +212,7 @@ } void ShenandoahBarrierSet::storeval_barrier(oop obj) { - if (ShenandoahStoreValEnqueueBarrier && !oopDesc::is_null(obj)) { + if (ShenandoahStoreValEnqueueBarrier && !oopDesc::is_null(obj) && _heap->is_concurrent_mark_in_progress()) { enqueue(obj); } } @@ -271,5 +271,7 @@ } void ShenandoahBarrierSet::clone_barrier_runtime(oop src) { - clone_barrier(src); + if (_heap->has_forwarded_objects() || (ShenandoahStoreValEnqueueBarrier && _heap->is_concurrent_mark_in_progress())) { + clone_barrier(src); + } } diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp @@ -117,12 +117,16 @@ private: template <class T> - inline void arraycopy_marking(T* ary, size_t count); + inline void arraycopy_marking(T* src, T* dst, size_t count); template <class T> inline void arraycopy_evacuation(T* src, size_t count); template <class T> inline void arraycopy_update(T* src, size_t count); + inline void clone_marking(oop src); + inline void clone_evacuation(oop src); + inline void clone_update(oop src); + template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE> inline void arraycopy_work(T* src, size_t count); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp @@ -80,7 +80,7 @@ } int gc_state = _heap->gc_state(); if ((gc_state & ShenandoahHeap::MARKING) != 0) { - arraycopy_marking(dst, count); + arraycopy_marking(src, dst, count); } else if ((gc_state & ShenandoahHeap::EVACUATION) != 0) { arraycopy_evacuation(src, count); } else if ((gc_state & ShenandoahHeap::UPDATEREFS) != 0) { @@ -89,8 +89,9 @@ } template <class T> -void ShenandoahBarrierSet::arraycopy_marking(T* array, size_t count) { +void ShenandoahBarrierSet::arraycopy_marking(T* src, T* dst, size_t count) { assert(_heap->is_concurrent_mark_in_progress(), "only during marking"); + T* array = ShenandoahSATBBarrier ? dst : src; if (!_heap->marking_context()->allocated_after_mark_start(reinterpret_cast<HeapWord*>(array))) { arraycopy_work<T, false, false, true>(array, count); } diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSetClone.inline.hpp @@ -31,7 +31,7 @@ #include "memory/iterator.hpp" #include "oops/oop.inline.hpp" -template <bool EVAC, bool ENQUEUE> +template <bool HAS_FWD, bool EVAC, bool ENQUEUE> class ShenandoahUpdateRefsForOopClosure: public ExtendedOopClosure { private: ShenandoahHeap* const _heap; @@ -44,18 +44,18 @@ T o = oopDesc::load_heap_oop(p); if (!oopDesc::is_null(o)) { oop obj = oopDesc::decode_heap_oop_not_null(o); - if (_cset->is_in(obj)) { + if (HAS_FWD && _cset->is_in(obj)) { oop fwd = _bs->resolve_forwarded_not_null(obj); if (EVAC && obj == fwd) { fwd = _heap->evacuate_object(obj, _thread); } - if (ENQUEUE) { - _bs->enqueue(fwd); - } assert(obj != fwd || _heap->cancelled_gc(), "must be forwarded"); ShenandoahHeap::cas_oop(fwd, p, o); + obj = fwd; } - + if (ENQUEUE) { + _bs->enqueue(obj); + } } } public: @@ -70,25 +70,44 @@ virtual void do_oop(narrowOop* p) { do_oop_work(p); } }; -void ShenandoahBarrierSet::clone_barrier(oop obj) { - assert(ShenandoahCloneBarrier, "only get here with clone barriers enabled"); - if (!_heap->has_forwarded_objects()) return; - - // This is called for cloning an object (see jvm.cpp) after the clone - // has been made. We are not interested in any 'previous value' because - // it would be NULL in any case. But we *are* interested in any oop* - // that potentially need to be updated. +void ShenandoahBarrierSet::clone_marking(oop obj) { + assert(_heap->is_concurrent_mark_in_progress(), "only during marking"); + assert(ShenandoahStoreValEnqueueBarrier, "only with incremental-update"); + if (!_heap->marking_context()->allocated_after_mark_start(obj)) { + ShenandoahUpdateRefsForOopClosure</* has_fwd = */ false, /* evac = */ false, /* enqueue */ true> cl; + obj->oop_iterate(&cl); + } +} - shenandoah_assert_correct(NULL, obj); - if (!need_bulk_update(cast_from_oop<HeapWord*>(obj))) return; - if (_heap->is_evacuation_in_progress()) { - ShenandoahEvacOOMScope evac_scope; - ShenandoahUpdateRefsForOopClosure</* evac = */ true, /* enqueue */ false> cl; - obj->oop_iterate(&cl); - } else { - ShenandoahUpdateRefsForOopClosure</* evac = */ false, /* enqueue */ false> cl; +void ShenandoahBarrierSet::clone_evacuation(oop obj) { + assert(_heap->is_evacuation_in_progress(), "only during evacuation"); + if (need_bulk_update(cast_from_oop<HeapWord*>(obj))) { + ShenandoahEvacOOMScope oom_evac_scope; + ShenandoahUpdateRefsForOopClosure</* has_fwd = */ true, /* evac = */ true, /* enqueue */ false> cl; + obj->oop_iterate(&cl); + } +} + +void ShenandoahBarrierSet::clone_update(oop obj) { + assert(_heap->is_update_refs_in_progress(), "only during update-refs"); + if (need_bulk_update(cast_from_oop<HeapWord*>(obj))) { + ShenandoahUpdateRefsForOopClosure</* has_fwd = */ true, /* evac = */ false, /* enqueue */ false> cl; obj->oop_iterate(&cl); } } +void ShenandoahBarrierSet::clone_barrier(oop obj) { + assert(ShenandoahCloneBarrier, "only get here with clone barriers enabled"); + shenandoah_assert_correct(NULL, obj); + + int gc_state = _heap->gc_state(); + if ((gc_state & ShenandoahHeap::MARKING) != 0) { + clone_marking(obj); + } else if ((gc_state & ShenandoahHeap::EVACUATION) != 0) { + clone_evacuation(obj); + } else { + clone_update(obj); + } +} + #endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSETCLONE_INLINE_HPP diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahConcurrentMark.cpp @@ -218,12 +218,13 @@ class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure { private: ShenandoahSATBBufferClosure* _satb_cl; - MarkingCodeBlobClosure* _code_cl; + OopClosure* const _cl; + MarkingCodeBlobClosure* _code_cl; int _thread_parity; public: - ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, MarkingCodeBlobClosure* code_cl) : - _satb_cl(satb_cl), _code_cl(code_cl), + ShenandoahSATBAndRemarkCodeRootsThreadsClosure(ShenandoahSATBBufferClosure* satb_cl, OopClosure* cl, MarkingCodeBlobClosure* code_cl) : + _satb_cl(satb_cl), _cl(cl), _code_cl(code_cl), _thread_parity(SharedHeap::heap()->strong_roots_parity()) {} void do_thread(Thread* thread) { @@ -231,7 +232,10 @@ if (thread->claim_oops_do(true, _thread_parity)) { JavaThread* jt = (JavaThread*)thread; jt->satb_mark_queue().apply_closure_and_empty(_satb_cl); - if (_code_cl != NULL) { + if (_cl != NULL) { + ResourceMark rm; + jt->oops_do(_cl, NULL, _code_cl); + } else if (_code_cl != NULL) { // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking // however the liveness of oops reachable from nmethods have very complex lifecycles: // * Alive if on the stack of an executing method @@ -285,20 +289,20 @@ ShenandoahSATBBufferClosure cl(q, dq); SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); while (satb_mq_set.apply_closure_to_completed_buffer(&cl)); - if (heap->unload_classes()) { - if (heap->has_forwarded_objects()) { - ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp); - MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations); - ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, &blobsCl); - Threads::threads_do(&tc); - } else { - ShenandoahMarkRefsClosure mark_cl(q, rp); - MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations); - ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, &blobsCl); - Threads::threads_do(&tc); - } + bool do_nmethods = heap->unload_classes(); + if (heap->has_forwarded_objects()) { + ShenandoahMarkResolveRefsClosure resolve_mark_cl(q, rp); + MarkingCodeBlobClosure blobsCl(&resolve_mark_cl, !CodeBlobToOopClosure::FixRelocations); + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, + ShenandoahStoreValEnqueueBarrier ? &resolve_mark_cl : NULL, + do_nmethods ? &blobsCl : NULL); + Threads::threads_do(&tc); } else { - ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, NULL); + ShenandoahMarkRefsClosure mark_cl(q, rp); + MarkingCodeBlobClosure blobsCl(&mark_cl, !CodeBlobToOopClosure::FixRelocations); + ShenandoahSATBAndRemarkCodeRootsThreadsClosure tc(&cl, + ShenandoahStoreValEnqueueBarrier ? &mark_cl : NULL, + do_nmethods ? &blobsCl : NULL); Threads::threads_do(&tc); } } diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp @@ -40,6 +40,7 @@ #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp" #include "gc_implementation/shenandoah/shenandoahHeapRegionSet.hpp" #include "gc_implementation/shenandoah/shenandoahHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahIUMode.hpp" #include "gc_implementation/shenandoah/shenandoahMarkCompact.hpp" #include "gc_implementation/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc_implementation/shenandoah/shenandoahMonitoringSupport.hpp" @@ -388,6 +389,8 @@ if (ShenandoahGCMode != NULL) { if (strcmp(ShenandoahGCMode, "normal") == 0) { _gc_mode = new ShenandoahNormalMode(); + } else if (strcmp(ShenandoahGCMode, "iu") == 0) { + _gc_mode = new ShenandoahIUMode(); } else if (strcmp(ShenandoahGCMode, "passive") == 0) { _gc_mode = new ShenandoahPassiveMode(); } else { diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp @@ -57,7 +57,7 @@ #define SHENANDOAH_CHECK_FLAG_SET(name) \ do { \ - if (!name) { \ + if (!(name)) { \ err_msg message("Heuristics needs -XX:+" #name " to work correctly"); \ vm_exit_during_initialization("Error", message); \ } \ diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shenandoah/shenandoahIUMode.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" +#include "gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" +#include "gc_implementation/shenandoah/shenandoahLogging.hpp" + +void ShenandoahIUMode::initialize_flags() const { + FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true); + FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false); + + SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); + SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); + + // Final configuration checks + SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahStoreValEnqueueBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); + SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); +} diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHIUMODE_HPP +#define SHARE_GC_SHENANDOAH_SHENANDOAHIUMODE_HPP + +#include "gc_implementation/shenandoah/shenandoahNormalMode.hpp" + +class ShenandoahHeuristics; + +class ShenandoahIUMode : public ShenandoahNormalMode { +public: + virtual void initialize_flags() const; + + virtual const char* name() { return "Incremental-Update"; } + virtual bool is_diagnostic() { return false; } + virtual bool is_experimental() { return true; } +}; + +#endif // SHARE_GC_SHENANDOAH_SHENANDOAHIUMODE_HPP diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp @@ -65,5 +65,5 @@ JRT_LEAF(void, ShenandoahRuntime::shenandoah_clone_barrier(oopDesc* src)) oop s = oop(src); shenandoah_assert_correct(NULL, s); - ShenandoahBarrierSet::barrier_set()->clone_barrier(s); + ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(s); JRT_END diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.cpp @@ -827,8 +827,8 @@ } } -void ShenandoahBarrierC2Support::test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, - PhaseIdealLoop* phase) { +void ShenandoahBarrierC2Support::test_heap_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, + PhaseIdealLoop* phase, int flags) { IdealLoopTree* loop = phase->get_loop(ctrl); Node* thread = new (phase->C) ThreadLocalNode(); phase->register_new_node(thread, ctrl); @@ -842,7 +842,7 @@ Node* gc_state = new (phase->C) 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 (phase->C) AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED)); + Node* heap_stable_and = new (phase->C) AndINode(gc_state, phase->igvn().intcon(flags)); phase->register_new_node(heap_stable_and, ctrl); Node* heap_stable_cmp = new (phase->C) CmpINode(heap_stable_and, phase->igvn().zerocon(T_INT)); phase->register_new_node(heap_stable_cmp, ctrl); @@ -856,7 +856,7 @@ ctrl = new (phase->C) 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, flags), "Should match the shape"); } void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase) { @@ -1364,7 +1364,7 @@ Node* raw_mem_phi = PhiNode::make(region, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM); // Stable path. - test_heap_stable(ctrl, raw_mem, heap_stable_ctrl, phase); + test_heap_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::HAS_FORWARDED); IfNode* heap_stable_iff = heap_stable_ctrl->in(0)->as_If(); // Heap stable case diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahSupport.hpp @@ -61,8 +61,8 @@ static Node* find_bottom_mem(Node* ctrl, PhaseIdealLoop* phase); 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); + static void test_heap_state(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl, + PhaseIdealLoop* phase, int flags); static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, 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, diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoah_globals.hpp @@ -62,6 +62,7 @@ "GC mode to use. Among other things, this defines which " \ "barriers are in in use. Possible values are:" \ " normal - default concurrent GC (three pass mark-evac-update);" \ + " iu - incremental-update concurrent GC (three pass mark-evac-update);" \ " passive - stop the world GC only (either degenerated or full)") \ \ product(ccstr, ShenandoahGCHeuristics, "adaptive", \ diff --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp +++ b/src/share/vm/prims/jvm.cpp @@ -648,7 +648,7 @@ #if INCLUDE_ALL_GCS if (UseShenandoahGC && ShenandoahCloneBarrier) { - ShenandoahBarrierSet::barrier_set()->clone_barrier(obj()); + ShenandoahBarrierSet::barrier_set()->clone_barrier_runtime(obj()); } #endif diff --git a/test/gc/shenandoah/TestAllocHumongousFragment.java b/test/gc/shenandoah/TestAllocHumongousFragment.java --- a/test/gc/shenandoah/TestAllocHumongousFragment.java +++ b/test/gc/shenandoah/TestAllocHumongousFragment.java @@ -90,6 +90,41 @@ * TestAllocHumongousFragment */ +/* + * @test TestAllocHumongousFragment + * @summary Make sure Shenandoah can recover from humongous allocation fragmentation + * @key gc + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify + * TestAllocHumongousFragment + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify + * TestAllocHumongousFragment + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * TestAllocHumongousFragment + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * TestAllocHumongousFragment + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestAllocHumongousFragment + * + * @run main/othervm -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestAllocHumongousFragment + */ + import java.util.*; import java.util.concurrent.*; diff --git a/test/gc/shenandoah/TestAllocIntArrays.java b/test/gc/shenandoah/TestAllocIntArrays.java --- a/test/gc/shenandoah/TestAllocIntArrays.java +++ b/test/gc/shenandoah/TestAllocIntArrays.java @@ -99,6 +99,45 @@ * TestAllocIntArrays */ +/* + * @test TestAllocIntArrays + * @summary Acceptance tests: collector can withstand allocation + * @key gc + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify + * TestAllocIntArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify + * TestAllocIntArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * TestAllocIntArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * TestAllocIntArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestAllocIntArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestAllocIntArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestAllocIntArrays + */ + import java.util.Random; public class TestAllocIntArrays { diff --git a/test/gc/shenandoah/TestAllocObjectArrays.java b/test/gc/shenandoah/TestAllocObjectArrays.java --- a/test/gc/shenandoah/TestAllocObjectArrays.java +++ b/test/gc/shenandoah/TestAllocObjectArrays.java @@ -98,6 +98,45 @@ * TestAllocObjectArrays */ +/* + * @test TestAllocObjectArrays + * @summary Acceptance tests: collector can withstand allocation + * @key gc + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify + * TestAllocObjectArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify + * TestAllocObjectArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * TestAllocObjectArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * TestAllocObjectArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestAllocObjectArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestAllocObjectArrays + * + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestAllocObjectArrays + */ + import java.util.Random; public class TestAllocObjectArrays { diff --git a/test/gc/shenandoah/TestAllocObjects.java b/test/gc/shenandoah/TestAllocObjects.java --- a/test/gc/shenandoah/TestAllocObjects.java +++ b/test/gc/shenandoah/TestAllocObjects.java @@ -94,6 +94,45 @@ * TestAllocObjects */ +/* + * @test TestAllocObjects + * @summary Acceptance tests: collector can withstand allocation + * @key gc + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify + * TestAllocObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify + * TestAllocObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * TestAllocObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * TestAllocObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestAllocObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestAllocObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestAllocObjects + */ + import java.util.Random; public class TestAllocObjects { diff --git a/test/gc/shenandoah/TestGCThreadGroups.java b/test/gc/shenandoah/TestGCThreadGroups.java --- a/test/gc/shenandoah/TestGCThreadGroups.java +++ b/test/gc/shenandoah/TestGCThreadGroups.java @@ -81,6 +81,24 @@ * TestGCThreadGroups */ +/** + * @test TestGCThreadGroups + * @summary Test Shenandoah GC uses concurrent/parallel threads correctly + * @key gc + * + * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 + * -Dtarget=1000 + * TestGCThreadGroups + * + * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4 + * -Dtarget=1000 + * TestGCThreadGroups +*/ + public class TestGCThreadGroups { static final long TARGET_MB = Long.getLong("target", 10_000); // 10 Gb allocation, around 1K cycles to handle diff --git a/test/gc/shenandoah/TestHeapUncommit.java b/test/gc/shenandoah/TestHeapUncommit.java --- a/test/gc/shenandoah/TestHeapUncommit.java +++ b/test/gc/shenandoah/TestHeapUncommit.java @@ -81,6 +81,25 @@ /* * @test TestHeapUncommit + * @summary Acceptance tests: collector can withstand allocation + * @key gc + * + * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestHeapUncommit + * + * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestHeapUncommit + * + * @run main/othervm -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahUncommit -XX:ShenandoahUncommitDelay=0 + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestHeapUncommit + */ + +/* + * @test TestHeapUncommit * @key gc * @requires (vm.bits == "64") * diff --git a/test/gc/shenandoah/TestLotsOfCycles.java b/test/gc/shenandoah/TestLotsOfCycles.java --- a/test/gc/shenandoah/TestLotsOfCycles.java +++ b/test/gc/shenandoah/TestLotsOfCycles.java @@ -75,6 +75,33 @@ * TestLotsOfCycles */ +/* + * @test TestLotsOfCycles + * @key gc + * + * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * -Dtarget=1000 + * TestLotsOfCycles + * + * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * -Dtarget=1000 + * TestLotsOfCycles + * + * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -Dtarget=1000 + * TestLotsOfCycles + * + * @run main/othervm/timeout=480 -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -Dtarget=10000 + * TestLotsOfCycles + */ + public class TestLotsOfCycles { static final long TARGET_MB = Long.getLong("target", 10_000); // 10 Gb allocation, around 1K cycles to handle diff --git a/test/gc/shenandoah/TestPeriodicGC.java b/test/gc/shenandoah/TestPeriodicGC.java --- a/test/gc/shenandoah/TestPeriodicGC.java +++ b/test/gc/shenandoah/TestPeriodicGC.java @@ -96,6 +96,36 @@ ); } + testWith("Zero interval with iu mode", + false, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCMode=iu", + "-XX:ShenandoahGuaranteedGCInterval=0" + ); + + testWith("Short interval with iu mode", + true, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCMode=iu", + "-XX:ShenandoahGuaranteedGCInterval=1000" + ); + + testWith("Long interval with iu mode", + false, + "-verbose:gc", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-XX:ShenandoahGCMode=iu", + "-XX:ShenandoahGuaranteedGCInterval=100000" // deliberately too long + ); + testWith("Short interval with aggressive", false, "-verbose:gc", diff --git a/test/gc/shenandoah/TestRefprocSanity.java b/test/gc/shenandoah/TestRefprocSanity.java --- a/test/gc/shenandoah/TestRefprocSanity.java +++ b/test/gc/shenandoah/TestRefprocSanity.java @@ -40,6 +40,25 @@ * TestRefprocSanity */ +/* + * @test TestRefprocSanity + * @summary Test that null references/referents work fine + * @key gc + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestRefprocSanity + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestRefprocSanity + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestRefprocSanity + */ + import java.lang.ref.*; public class TestRefprocSanity { diff --git a/test/gc/shenandoah/TestRegionSampling.java b/test/gc/shenandoah/TestRegionSampling.java --- a/test/gc/shenandoah/TestRegionSampling.java +++ b/test/gc/shenandoah/TestRegionSampling.java @@ -57,6 +57,19 @@ * TestRegionSampling */ +/* + * @test TestRegionSampling + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestRegionSampling + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ShenandoahRegionSampling + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestRegionSampling + * + */ + public class TestRegionSampling { static final long TARGET_MB = Long.getLong("target", 2_000); // 2 Gb allocation diff --git a/test/gc/shenandoah/TestRetainObjects.java b/test/gc/shenandoah/TestRetainObjects.java --- a/test/gc/shenandoah/TestRetainObjects.java +++ b/test/gc/shenandoah/TestRetainObjects.java @@ -89,6 +89,35 @@ * TestRetainObjects */ +/* + * @test TestRetainObjects + * @summary Acceptance tests: collector can deal with retained objects + * @key gc + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * TestRetainObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * TestRetainObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestRetainObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestRetainObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestRetainObjects + */ + public class TestRetainObjects { static final int COUNT = 10_000_000; diff --git a/test/gc/shenandoah/TestSieveObjects.java b/test/gc/shenandoah/TestSieveObjects.java --- a/test/gc/shenandoah/TestSieveObjects.java +++ b/test/gc/shenandoah/TestSieveObjects.java @@ -89,6 +89,35 @@ * TestSieveObjects */ +/* + * @test TestSieveObjects + * @summary Acceptance tests: collector can deal with retained objects + * @key gc + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * TestSieveObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahAllocFailureALot + * TestSieveObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestSieveObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestSieveObjects + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestSieveObjects + */ + import java.util.concurrent.ThreadLocalRandom; public class TestSieveObjects { diff --git a/test/gc/shenandoah/TestStringDedup.java b/test/gc/shenandoah/TestStringDedup.java --- a/test/gc/shenandoah/TestStringDedup.java +++ b/test/gc/shenandoah/TestStringDedup.java @@ -58,6 +58,20 @@ * TestStringDedup */ +/* + * @test TestStringDedup + * @summary Test Shenandoah string deduplication implementation + * @key gc + * + * @run main/othervm -Xmx256m -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestStringDedup + * + * @run main/othervm -Xmx256m -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestStringDedup + */ + import java.lang.reflect.*; import java.util.*; diff --git a/test/gc/shenandoah/TestStringDedupStress.java b/test/gc/shenandoah/TestStringDedupStress.java --- a/test/gc/shenandoah/TestStringDedupStress.java +++ b/test/gc/shenandoah/TestStringDedupStress.java @@ -63,6 +63,33 @@ * TestStringDedupStress */ + /* + * @test TestStringDedupStress + * @summary Test Shenandoah string deduplication implementation + * @key gc + * + * @run main/othervm -Xmx1g -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestStringDedupStress + * + * @run main/othervm -Xmx1g -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -DtargetStrings=2000000 + * TestStringDedupStress + * + * @run main/othervm -Xmx1g -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahOOMDuringEvacALot + * -DtargetStrings=2000000 + * TestStringDedupStress + * + * @run main/othervm -Xmx1g -verbose:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahOOMDuringEvacALot + * -DtargetStrings=2000000 + * TestStringDedupStress + */ + import java.lang.management.*; import java.lang.reflect.*; import java.util.*; diff --git a/test/gc/shenandoah/TestStringInternCleanup.java b/test/gc/shenandoah/TestStringInternCleanup.java --- a/test/gc/shenandoah/TestStringInternCleanup.java +++ b/test/gc/shenandoah/TestStringInternCleanup.java @@ -74,6 +74,26 @@ * TestStringInternCleanup */ +/* + * @test TestStringInternCleanup + * @summary Check that Shenandoah cleans up interned strings + * @key gc + * + * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify + * TestStringInternCleanup + * + * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -XX:+ShenandoahVerify + * TestStringInternCleanup + * + * @run main/othervm -Xmx64m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+ClassUnloadingWithConcurrentMark + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestStringInternCleanup + */ + public class TestStringInternCleanup { static final int COUNT = 1_000_000; diff --git a/test/gc/shenandoah/TestVerifyJCStress.java b/test/gc/shenandoah/TestVerifyJCStress.java --- a/test/gc/shenandoah/TestVerifyJCStress.java +++ b/test/gc/shenandoah/TestVerifyJCStress.java @@ -53,6 +53,17 @@ * TestVerifyJCStress */ +/* + * @test TestVerifyJCStress + * @summary Tests that we pass at least one jcstress-like test with all verification turned on + * @key gc + * + * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -XX:+ShenandoahVerify -XX:+IgnoreUnrecognizedVMOptions -XX:+ShenandoahVerifyOptoBarriers + * TestVerifyJCStress + */ + import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.*; diff --git a/test/gc/shenandoah/TestWrongArrayMember.java b/test/gc/shenandoah/TestWrongArrayMember.java --- a/test/gc/shenandoah/TestWrongArrayMember.java +++ b/test/gc/shenandoah/TestWrongArrayMember.java @@ -25,7 +25,8 @@ * @test TestWrongArrayMember * @key gc * - * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestWrongArrayMember + * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC TestWrongArrayMember + * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu TestWrongArrayMember */ public class TestWrongArrayMember { diff --git a/test/gc/shenandoah/mxbeans/TestChurnNotifications.java b/test/gc/shenandoah/mxbeans/TestChurnNotifications.java --- a/test/gc/shenandoah/mxbeans/TestChurnNotifications.java +++ b/test/gc/shenandoah/mxbeans/TestChurnNotifications.java @@ -62,6 +62,21 @@ * TestChurnNotifications */ +/* + * @test TestChurnNotifications + * @summary Check that MX notifications are reported for all cycles + * + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * -Dprecise=false + * TestChurnNotifications + * + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * -Dprecise=false + * TestChurnNotifications + */ + import java.util.*; import java.util.concurrent.atomic.*; import javax.management.*; diff --git a/test/gc/shenandoah/mxbeans/TestPauseNotifications.java b/test/gc/shenandoah/mxbeans/TestPauseNotifications.java --- a/test/gc/shenandoah/mxbeans/TestPauseNotifications.java +++ b/test/gc/shenandoah/mxbeans/TestPauseNotifications.java @@ -59,6 +59,20 @@ * TestPauseNotifications */ +/* + * @test TestPauseNotifications + * @summary Check that MX notifications are reported for all cycles + * @key gc + * + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive + * TestPauseNotifications + * + * @run main/othervm -Xmx128m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu + * TestPauseNotifications + */ + import java.util.*; import java.util.concurrent.atomic.*; import javax.management.*; diff --git a/test/gc/shenandoah/oom/TestClassLoaderLeak.java b/test/gc/shenandoah/oom/TestClassLoaderLeak.java --- a/test/gc/shenandoah/oom/TestClassLoaderLeak.java +++ b/test/gc/shenandoah/oom/TestClassLoaderLeak.java @@ -123,8 +123,9 @@ } String[][][] modeHeuristics = new String[][][] { - {{"normal"}, {"adaptive", "compact", "static", "aggressive"}}, - {{"passive"}, {"passive"}} + {{"normal"}, {"adaptive", "compact", "static", "aggressive"}}, + {{"iu"}, {"adaptive", "aggressive"}}, + {{"passive"}, {"passive"}} }; for (String[][] mh : modeHeuristics) { diff --git a/test/gc/shenandoah/options/TestExplicitGC.java b/test/gc/shenandoah/options/TestExplicitGC.java --- a/test/gc/shenandoah/options/TestExplicitGC.java +++ b/test/gc/shenandoah/options/TestExplicitGC.java @@ -122,5 +122,23 @@ output.shouldNotContain(p); } } + + { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + "-verbose:gc", + "-XX:+ExplicitGCInvokesConcurrent", + "-XX:ShenandoahGCMode=iu", + TestExplicitGC.class.getName(), + "test"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + for (String p : full) { + output.shouldNotContain(p); + } + for (String p : concNormal) { + output.shouldContain(p); + } + } } } diff --git a/test/gc/shenandoah/options/TestHeuristicsUnlock.java b/test/gc/shenandoah/options/TestHeuristicsUnlock.java --- a/test/gc/shenandoah/options/TestHeuristicsUnlock.java +++ b/test/gc/shenandoah/options/TestHeuristicsUnlock.java @@ -45,6 +45,8 @@ testWith("-XX:ShenandoahGCHeuristics=static", Mode.PRODUCT); testWith("-XX:ShenandoahGCHeuristics=compact", Mode.PRODUCT); + testWith("-XX:ShenandoahGCMode=iu", Mode.EXPERIMENTAL); + testWith("-XX:ShenandoahGCHeuristics=aggressive", Mode.DIAGNOSTIC); testWith("-XX:ShenandoahGCMode=passive", Mode.DIAGNOSTIC); } diff --git a/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java b/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java --- a/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java +++ b/test/gc/shenandoah/options/TestSelectiveBarrierFlags.java @@ -40,8 +40,8 @@ public static void main(String[] args) throws Exception { String[][] opts = { - new String[]{ "ShenandoahSATBBarrier" }, new String[]{ "ShenandoahLoadRefBarrier" }, + new String[] { "ShenandoahSATBBarrier", "ShenandoahStoreValEnqueueBarrier" }, new String[]{ "ShenandoahCASBarrier" }, new String[]{ "ShenandoahCloneBarrier" }, }; diff --git a/test/gc/shenandoah/options/TestWrongBarrierDisable.java b/test/gc/shenandoah/options/TestWrongBarrierDisable.java --- a/test/gc/shenandoah/options/TestWrongBarrierDisable.java +++ b/test/gc/shenandoah/options/TestWrongBarrierDisable.java @@ -37,16 +37,23 @@ public static void main(String[] args) throws Exception { String[] concurrent = { "ShenandoahLoadRefBarrier", + "ShenandoahSATBBarrier", "ShenandoahCASBarrier", "ShenandoahCloneBarrier", - "ShenandoahSATBBarrier", + }; + String[] iu = { + "ShenandoahLoadRefBarrier", + "ShenandoahCASBarrier", + "ShenandoahCloneBarrier", }; shouldFailAll("-XX:ShenandoahGCHeuristics=adaptive", concurrent); shouldFailAll("-XX:ShenandoahGCHeuristics=static", concurrent); shouldFailAll("-XX:ShenandoahGCHeuristics=compact", concurrent); shouldFailAll("-XX:ShenandoahGCHeuristics=aggressive", concurrent); + shouldFailAll("-XX:ShenandoahGCMode=iu", iu); shouldPassAll("-XX:ShenandoahGCMode=passive", concurrent); + shouldPassAll("-XX:ShenandoahGCMode=passive", iu); } private static void shouldFailAll(String h, String[] barriers) throws Exception { # HG changeset patch # User shade # Date 1586258326 -7200 # Tue Apr 07 13:18:46 2020 +0200 # Node ID fbbd9bde2c7858883a2edc3aaa5fee1328ff365d # Parent a222813e5654b4a6809ad0233238300f862565c2 [backport] 8242271: Shenandoah: add test to verify GC mode unlock Reviewed-by: rkennke diff --git a/test/gc/shenandoah/options/TestModeUnlock.java b/test/gc/shenandoah/options/TestModeUnlock.java new file mode 100644 --- /dev/null +++ b/test/gc/shenandoah/options/TestModeUnlock.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test TestModeUnlock + * @summary Test that Shenandoah modes are unlocked properly + * @key gc + * @library /testlibrary + * @run driver TestModeUnlock + */ + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestModeUnlock { + + enum Mode { + PRODUCT, + DIAGNOSTIC, + EXPERIMENTAL, + } + + public static void main(String[] args) throws Exception { + testWith("-XX:ShenandoahGCMode=normal", Mode.PRODUCT); + testWith("-XX:ShenandoahGCMode=iu", Mode.EXPERIMENTAL); + testWith("-XX:ShenandoahGCMode=passive", Mode.DIAGNOSTIC); + } + + private static void testWith(String h, Mode mode) throws Exception { + if (false) { // When ShenandoahGC is experimental flag, this makes no sense to test + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:-UnlockDiagnosticVMOptions", + "-XX:-UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + h, + "-version" + ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + switch (mode) { + case PRODUCT: + output.shouldHaveExitValue(0); + break; + case DIAGNOSTIC: + case EXPERIMENTAL: + output.shouldNotHaveExitValue(0); + break; + } + } + + if (false) { // When ShenandoahGC is experimental flag, this makes no sense to test + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:-UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + h, + "-version" + ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + switch (mode) { + case PRODUCT: + case DIAGNOSTIC: + output.shouldHaveExitValue(0); + break; + case EXPERIMENTAL: + output.shouldNotHaveExitValue(0); + break; + } + } + + { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:-UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + h, + "-version" + ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + switch (mode) { + case PRODUCT: + case EXPERIMENTAL: + output.shouldHaveExitValue(0); + break; + case DIAGNOSTIC: + output.shouldNotHaveExitValue(0); + break; + } + } + } + +} # HG changeset patch # User shade # Date 1586258327 -7200 # Tue Apr 07 13:18:47 2020 +0200 # Node ID 34a6d550f96f2af30b8987f280eae97b7792e838 # Parent fbbd9bde2c7858883a2edc3aaa5fee1328ff365d [backport] 8242273: Shenandoah: accept either SATB or IU barriers, but not both Reviewed-by: rkennke diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp @@ -41,12 +41,6 @@ if (ClassUnloading) { SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUnloadClassesFrequency, 1); } - - // Final configuration checks - SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier || ShenandoahStoreValEnqueueBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } void ShenandoahAggressiveHeuristics::choose_collection_set_from_regiondata(ShenandoahCollectionSet* cset, diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -40,12 +40,6 @@ SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahUncommitDelay, 1000); SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahGuaranteedGCInterval, 30000); SHENANDOAH_ERGO_OVERRIDE_DEFAULT(ShenandoahGarbageThreshold, 10); - - // Final configuration checks - SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier || ShenandoahStoreValEnqueueBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } bool ShenandoahCompactHeuristics::should_start_gc() const { diff --git a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp --- a/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp +++ b/src/share/vm/gc_implementation/shenandoah/heuristics/shenandoahStaticHeuristics.cpp @@ -33,12 +33,6 @@ ShenandoahStaticHeuristics::ShenandoahStaticHeuristics() : ShenandoahHeuristics() { SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); - - // Final configuration checks - SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier || ShenandoahStoreValEnqueueBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); - SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); } ShenandoahStaticHeuristics::~ShenandoahStaticHeuristics() {} diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeuristics.hpp @@ -55,14 +55,6 @@ } \ } while (0) -#define SHENANDOAH_CHECK_FLAG_SET(name) \ - do { \ - if (!(name)) { \ - err_msg message("Heuristics needs -XX:+" #name " to work correctly"); \ - vm_exit_during_initialization("Error", message); \ - } \ - } while (0) - class ShenandoahCollectionSet; class ShenandoahHeapRegion; diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahIUMode.cpp @@ -31,14 +31,19 @@ #include "gc_implementation/shenandoah/shenandoahLogging.hpp" void ShenandoahIUMode::initialize_flags() const { - FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true); - FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false); + if (FLAG_IS_DEFAULT(ShenandoahStoreValEnqueueBarrier)) { + FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, true); + } + if (FLAG_IS_DEFAULT(ShenandoahSATBBarrier)) { + FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false); + } SHENANDOAH_ERGO_ENABLE_FLAG(ExplicitGCInvokesConcurrent); SHENANDOAH_ERGO_ENABLE_FLAG(ShenandoahImplicitGCInvokesConcurrent); // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); + SHENANDOAH_CHECK_FLAG_UNSET(ShenandoahSATBBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahStoreValEnqueueBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahMode.hpp @@ -28,6 +28,22 @@ class ShenandoahHeuristics; +#define SHENANDOAH_CHECK_FLAG_SET(name) \ + do { \ + if (!(name)) { \ + err_msg message("GC mode needs -XX:+" #name " to work correctly"); \ + vm_exit_during_initialization("Error", message); \ + } \ + } while (0) + +#define SHENANDOAH_CHECK_FLAG_UNSET(name) \ + do { \ + if ((name)) { \ + err_msg message("GC mode needs -XX:-" #name " to work correctly"); \ + vm_exit_during_initialization("Error", message); \ + } \ + } while (0) + class ShenandoahMode : public CHeapObj<mtGC> { public: virtual void initialize_flags() const = 0; diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahNormalMode.cpp @@ -34,6 +34,7 @@ // Final configuration checks SHENANDOAH_CHECK_FLAG_SET(ShenandoahLoadRefBarrier); + SHENANDOAH_CHECK_FLAG_UNSET(ShenandoahStoreValEnqueueBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahSATBBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCASBarrier); SHENANDOAH_CHECK_FLAG_SET(ShenandoahCloneBarrier); diff --git a/test/gc/shenandoah/options/TestWrongBarrierDisable.java b/test/gc/shenandoah/options/TestWrongBarrierDisable.java --- a/test/gc/shenandoah/options/TestWrongBarrierDisable.java +++ b/test/gc/shenandoah/options/TestWrongBarrierDisable.java @@ -43,6 +43,7 @@ }; String[] iu = { "ShenandoahLoadRefBarrier", + "ShenandoahStoreValEnqueueBarrier", "ShenandoahCASBarrier", "ShenandoahCloneBarrier", }; @@ -68,7 +69,7 @@ ); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(1); - output.shouldContain("Heuristics needs "); + output.shouldContain("GC mode needs "); output.shouldContain("to work correctly"); } } diff --git a/test/gc/shenandoah/options/TestWrongBarrierEnable.java b/test/gc/shenandoah/options/TestWrongBarrierEnable.java new file mode 100644 --- /dev/null +++ b/test/gc/shenandoah/options/TestWrongBarrierEnable.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, Red Hat, Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* @test TestWrongBarrierEnable + * @summary Test that disabling wrong barriers fails early + * @key gc + * @library /testlibrary + * @run main/othervm TestWrongBarrierEnable + */ + +import java.util.*; + +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +public class TestWrongBarrierEnable { + + public static void main(String[] args) throws Exception { + String[] concurrent = { + "ShenandoahStoreValEnqueueBarrier", + }; + String[] iu = { + "ShenandoahSATBBarrier", + }; + + shouldFailAll("-XX:ShenandoahGCHeuristics=adaptive", concurrent); + shouldFailAll("-XX:ShenandoahGCHeuristics=static", concurrent); + shouldFailAll("-XX:ShenandoahGCHeuristics=compact", concurrent); + shouldFailAll("-XX:ShenandoahGCHeuristics=aggressive", concurrent); + shouldFailAll("-XX:ShenandoahGCMode=iu", iu); + shouldPassAll("-XX:ShenandoahGCMode=passive", concurrent); + shouldPassAll("-XX:ShenandoahGCMode=passive", iu); + } + + private static void shouldFailAll(String h, String[] barriers) throws Exception { + for (String b : barriers) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + h, + "-XX:+" + b, + "-version" + ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotHaveExitValue(0); + output.shouldContain("GC mode needs "); + output.shouldContain("to work correctly"); + } + } + + private static void shouldPassAll(String h, String[] barriers) throws Exception { + for (String b : barriers) { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+UnlockExperimentalVMOptions", + "-XX:+UseShenandoahGC", + h, + "-XX:+" + b, + "-version" + ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } + } + +} # HG changeset patch # User rkennke # Date 1586291478 -7200 # Tue Apr 07 22:31:18 2020 +0200 # Node ID dbba6ebc3a08a0a1779b580282163b97d26aaecd # Parent 34a6d550f96f2af30b8987f280eae97b7792e838 [backport] 8242301: Shenandoah: Inline LRB runtime call Reviewed-by: zgu diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.cpp @@ -180,19 +180,6 @@ } -oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj) { - assert(ShenandoahLoadRefBarrier, "should be enabled"); - assert(_heap->is_evacuation_in_progress(), "evac should be in progress"); - shenandoah_assert_in_cset(NULL, obj); - - oop fwd = resolve_forwarded_not_null(obj); - if (obj == fwd) { - ShenandoahEvacOOMScope scope; - return _heap->evacuate_object(obj, Thread::current()); - } - return fwd; -} - oop ShenandoahBarrierSet::load_reference_barrier_impl(oop obj) { assert(ShenandoahLoadRefBarrier, "should be enabled"); if (!oopDesc::is_null(obj)) { diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.hpp @@ -108,8 +108,8 @@ void storeval_barrier(oop obj); oop load_reference_barrier(oop obj); - oop load_reference_barrier_mutator(oop obj); oop load_reference_barrier_not_null(oop obj); + inline oop load_reference_barrier_mutator(oop obj); oop oop_atomic_cmpxchg_in_heap(oop new_value, volatile HeapWord* dest, oop compare_value); diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahBarrierSet.inline.hpp @@ -44,6 +44,21 @@ } } +inline oop ShenandoahBarrierSet::load_reference_barrier_mutator(oop obj) { + assert(ShenandoahLoadRefBarrier, "should be enabled"); + shenandoah_assert_in_cset(NULL, obj); + + oop fwd = resolve_forwarded_not_null(obj); + if (obj == fwd) { + assert(_heap->is_evacuation_in_progress(), + "evac should be in progress"); + ShenandoahEvacOOMScope scope; + fwd = _heap->evacuate_object(obj, Thread::current()); + } + + return fwd; +} + template <class T, bool HAS_FWD, bool EVAC, bool ENQUEUE> void ShenandoahBarrierSet::arraycopy_work(T* src, size_t count) { assert(HAS_FWD == _heap->has_forwarded_objects(), "Forwarded object status is sane"); # HG changeset patch # User rkennke # Date 1586338009 -7200 # Wed Apr 08 11:26:49 2020 +0200 # Node ID 1ec8b9e0dfa6a7a28e0231698c5c9dbef00ab191 # Parent dbba6ebc3a08a0a1779b580282163b97d26aaecd [backport] 8242316: Shenandoah: Turn NULL-check into assert in SATB slow-path entry Reviewed-by: zgu, shade diff --git a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp --- a/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp +++ b/src/share/vm/gc_implementation/shenandoah/shenandoahRuntime.cpp @@ -40,10 +40,7 @@ // Shenandoah pre write barrier slowpath JRT_LEAF(void, ShenandoahRuntime::write_ref_field_pre_entry(oopDesc* orig, JavaThread *thread)) - if (orig == NULL) { - assert(false, "should be optimized out"); - return; - } + assert(orig != NULL, "should be optimized out"); shenandoah_assert_correct(NULL, orig); // store the original value that was in the field reference assert(thread->satb_mark_queue().is_active(), "Shouldn't be here otherwise");