changeset 60774:7a6fa1fb094d

8242054: Shenandoah: New incremental-update mode Reviewed-by: shade
author rkennke
date Mon, 06 Apr 2020 17:08:46 +0200
parents aee5ea05a40f
children d91dac1c51a6
files src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp src/hotspot/share/gc/shenandoah/shenandoahIUMode.cpp src/hotspot/share/gc/shenandoah/shenandoahIUMode.hpp src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java test/hotspot/jtreg/gc/CriticalNativeArgs.java test/hotspot/jtreg/gc/shenandoah/TestAllocHumongousFragment.java test/hotspot/jtreg/gc/shenandoah/TestAllocIntArrays.java test/hotspot/jtreg/gc/shenandoah/TestAllocObjectArrays.java test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java test/hotspot/jtreg/gc/shenandoah/TestHeapUncommit.java test/hotspot/jtreg/gc/shenandoah/TestLotsOfCycles.java test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java test/hotspot/jtreg/gc/shenandoah/TestRefprocSanity.java test/hotspot/jtreg/gc/shenandoah/TestRegionSampling.java test/hotspot/jtreg/gc/shenandoah/TestRetainObjects.java test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java test/hotspot/jtreg/gc/shenandoah/TestStringDedup.java test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java test/hotspot/jtreg/gc/shenandoah/TestStringInternCleanup.java test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java test/hotspot/jtreg/gc/shenandoah/TestWrongArrayMember.java test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java test/hotspot/jtreg/gc/stress/CriticalNativeStress.java test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithShenandoah.java test/hotspot/jtreg/gc/stress/gcold/TestGCOldWithShenandoah.java test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithShenandoah.java
diffstat 49 files changed, 822 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -49,7 +49,7 @@
                                                        Register src, Register dst, Register count, RegSet saved_regs) {
   if (is_oop) {
     bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
-    if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) {
+    if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahStoreValEnqueueBarrier || ShenandoahLoadRefBarrier) {
 
       Label done;
 
@@ -59,7 +59,7 @@
       // Is GC active?
       Address gc_state(rthread, in_bytes(ShenandoahThreadLocalData::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);
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -53,7 +53,7 @@
 
   if (is_reference_type(type)) {
 
-    if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) {
+    if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahStoreValEnqueueBarrier || ShenandoahLoadRefBarrier) {
 #ifdef _LP64
       Register thread = r15_thread;
 #else
@@ -79,9 +79,11 @@
 
       // Avoid runtime call when not active.
       Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::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);
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -774,7 +774,7 @@
   if (!is_oop) {
     return false;
   }
-  if (tightly_coupled_alloc) {
+  if (ShenandoahSATBBarrier && tightly_coupled_alloc) {
     if (phase == Optimization) {
       return false;
     }
@@ -841,7 +841,11 @@
     debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx));
 
     Node* gc_state    = phase->transform_later(new LoadBNode(ctrl, mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered));
-    Node* stable_and  = phase->transform_later(new AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED)));
+    int flags = ShenandoahHeap::HAS_FORWARDED;
+    if (ShenandoahStoreValEnqueueBarrier) {
+      flags |= ShenandoahHeap::MARKING;
+    }
+    Node* stable_and  = phase->transform_later(new AndINode(gc_state, phase->igvn().intcon(flags)));
     Node* stable_cmp  = phase->transform_later(new CmpINode(stable_and, phase->igvn().zerocon(T_INT)));
     Node* stable_test = phase->transform_later(new BoolNode(stable_cmp, BoolTest::ne));
 
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -860,8 +860,8 @@
   inner->clear_strip_mined();
 }
 
-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 ThreadLocalNode();
   phase->register_new_node(thread, ctrl);
@@ -875,7 +875,7 @@
 
   Node* gc_state = new LoadBNode(ctrl, raw_mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered);
   phase->register_new_node(gc_state, ctrl);
-  Node* heap_stable_and = new AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED));
+  Node* heap_stable_and = new AndINode(gc_state, phase->igvn().intcon(flags));
   phase->register_new_node(heap_stable_and, ctrl);
   Node* heap_stable_cmp = new CmpINode(heap_stable_and, phase->igvn().zerocon(T_INT));
   phase->register_new_node(heap_stable_cmp, ctrl);
@@ -889,7 +889,7 @@
   ctrl = new IfTrueNode(heap_stable_iff);
   phase->register_control(ctrl, loop, heap_stable_iff);
 
-  assert(is_heap_stable_test(heap_stable_iff), "Should match the shape");
+  assert(is_heap_state_test(heap_stable_iff, flags), "Should match the shape");
 }
 
 void ShenandoahBarrierC2Support::test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase) {
@@ -1437,7 +1437,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
@@ -1608,7 +1608,7 @@
     Node* phi2 = PhiNode::make(region2, raw_mem, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     // Stable path.
-    test_heap_stable(ctrl, raw_mem, heap_stable_ctrl, phase);
+    test_heap_state(ctrl, raw_mem, heap_stable_ctrl, phase, ShenandoahHeap::MARKING);
     region->init_req(_heap_stable, heap_stable_ctrl);
     phi->init_req(_heap_stable, raw_mem);
 
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -58,8 +58,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* load_addr, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase);
   static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
   static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -46,7 +46,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);
 }
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -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);
 }
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -37,7 +37,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);
 }
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -241,7 +241,7 @@
 }
 
 void ShenandoahBarrierSet::clone_barrier_runtime(oop src) {
-  if (_heap->has_forwarded_objects()) {
+  if (_heap->has_forwarded_objects() || (ShenandoahStoreValEnqueueBarrier && _heap->is_concurrent_mark_in_progress())) {
     clone_barrier(src);
   }
 }
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -107,12 +107,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);
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -86,7 +86,7 @@
 }
 
 inline void ShenandoahBarrierSet::storeval_barrier(oop obj) {
-  if (obj != NULL && ShenandoahStoreValEnqueueBarrier) {
+  if (ShenandoahStoreValEnqueueBarrier && obj != NULL && _heap->is_concurrent_mark_in_progress()) {
     enqueue(obj);
   }
 }
@@ -291,7 +291,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) {
@@ -300,8 +300,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);
   }
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSetClone.inline.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -33,7 +33,7 @@
 #include "oops/access.hpp"
 #include "oops/compressedOops.hpp"
 
-template <bool EVAC, bool ENQUEUE>
+template <bool HAS_FWD, bool EVAC, bool ENQUEUE>
 class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure {
 private:
   ShenandoahHeap* const _heap;
@@ -46,18 +46,18 @@
     T o = RawAccess<>::oop_load(p);
     if (!CompressedOops::is_null(o)) {
       oop obj = CompressedOops::decode_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:
@@ -72,25 +72,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");
-  assert(_heap->has_forwarded_objects(), "only when heap is unstable");
-
-  // 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.
-
-  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_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);
   }
 }
 
+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
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -183,26 +183,32 @@
 class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure {
 private:
   ShenandoahSATBBufferClosure* _satb_cl;
+  OopClosure*            const _cl;
   MarkingCodeBlobClosure*      _code_cl;
   uintx _claim_token;
 
 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),
     _claim_token(Threads::thread_claim_token()) {}
 
   void do_thread(Thread* thread) {
     if (thread->claim_threads_do(true, _claim_token)) {
       ShenandoahThreadLocalData::satb_mark_queue(thread).apply_closure_and_empty(_satb_cl);
-      if (_code_cl != NULL && thread->is_Java_thread()) {
-        // 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.
-        JavaThread* jt = (JavaThread*)thread;
-        jt->nmethods_do(_code_cl);
+      if (thread->is_Java_thread()) {
+        if (_cl != NULL) {
+          ResourceMark rm;
+          thread->oops_do(_cl, _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
+          // * 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.
+          JavaThread* jt = (JavaThread*)thread;
+          jt->nmethods_do(_code_cl);
+        }
       }
     }
   }
@@ -242,21 +248,20 @@
       ShenandoahSATBBufferClosure cl(q);
       SATBMarkQueueSet& satb_mq_set = ShenandoahBarrierSet::satb_mark_queue_set();
       while (satb_mq_set.apply_closure_to_completed_buffer(&cl));
-
-      if (heap->unload_classes() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) {
-        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() && !ShenandoahConcurrentRoots::can_do_concurrent_class_unloading();
+      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);
       }
     }
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -46,6 +46,7 @@
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 #include "gc/shenandoah/shenandoahHeapRegionSet.hpp"
+#include "gc/shenandoah/shenandoahIUMode.hpp"
 #include "gc/shenandoah/shenandoahMarkCompact.hpp"
 #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
 #include "gc/shenandoah/shenandoahMemoryPool.hpp"
@@ -397,6 +398,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 {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -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);                      \
     }                                                                       \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahIUMode.cpp	Mon Apr 06 17:08:46 2020 +0200
@@ -0,0 +1,52 @@
+/*
+ * 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/shenandoah/shenandoahConcurrentRoots.hpp"
+#include "gc/shenandoah/shenandoahIUMode.hpp"
+#include "gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahAggressiveHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp"
+#include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
+#include "logging/log.hpp"
+#include "logging/logTag.hpp"
+
+void ShenandoahIUMode::initialize_flags() const {
+  if (ShenandoahConcurrentRoots::can_do_concurrent_class_unloading()) {
+    FLAG_SET_DEFAULT(ShenandoahSuspendibleWorkers, true);
+    FLAG_SET_DEFAULT(VerifyBeforeExit, false);
+  }
+
+  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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shenandoah/shenandoahIUMode.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -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/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
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Mon Apr 06 07:39:58 2020 -0700
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Mon Apr 06 17:08:46 2020 +0200
@@ -67,6 +67,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)") \
                                                                             \
   experimental(ccstr, ShenandoahGCHeuristics, "adaptive",                   \
--- a/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/compiler/c2/aarch64/TestVolatiles.java	Mon Apr 06 17:08:46 2020 +0200
@@ -38,7 +38,8 @@
  * and <testtype> in {G1,
  *                    Serial,
  *                    Parallel,
- *                    Shenandoah}
+ *                    Shenandoah,
+ *                    ShenandoahIU}
  */
 
 
@@ -93,6 +94,13 @@
             procArgs[argcount - 3] = "-XX:+UnlockExperimentalVMOptions";
             procArgs[argcount - 2] = "-XX:+UseShenandoahGC";
             break;
+        case "ShenandoahIU":
+            argcount = 11;
+            procArgs = new String[argcount];
+            procArgs[argcount - 4] = "-XX:+UnlockExperimentalVMOptions";
+            procArgs[argcount - 3] = "-XX:+UseShenandoahGC";
+            procArgs[argcount - 2] = "-XX:ShenandoahGCMode=iu";
+            break;
         default:
             throw new RuntimeException("unexpected test type " + testType);
         }
@@ -323,6 +331,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                  // Shenandoah generates normal object graphs for
                  // volatile stores
                 matches = new String[] {
@@ -401,6 +410,7 @@
                 break;
 
             case "Shenandoah":
+            case "ShenandoahIU":
                  // Shenandoah generates normal object graphs for
                  // volatile stores
                 matches = new String[] {
@@ -490,6 +500,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                 // For volatile CAS, Shenanodoah generates normal
                 // graphs with a shenandoah-specific cmpxchg
                 matches = new String[] {
@@ -567,6 +578,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                 // For volatile CAS, Shenanodoah generates normal
                 // graphs with a shenandoah-specific cmpxchg
                 matches = new String[] {
@@ -672,6 +684,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                 // For volatile CAS, Shenanodoah generates normal
                 // graphs with a shenandoah-specific cmpxchg
                 matches = new String[] {
@@ -749,6 +762,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                 // For volatile CAS, Shenanodoah generates normal
                 // graphs with a shenandoah-specific cmpxchg
                 matches = new String[] {
@@ -834,6 +848,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                 matches = new String[] {
                     "membar_release \\(elided\\)",
                     useCompressedOops ? "atomic_xchgw?_acq" : "atomic_xchg_acq",
@@ -909,6 +924,7 @@
                 };
                 break;
             case "Shenandoah":
+            case "ShenandoahIU":
                 matches = new String[] {
                     "membar_release",
                     "dmb ish",
--- a/test/hotspot/jtreg/gc/CriticalNativeArgs.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/CriticalNativeArgs.java	Mon Apr 06 17:08:46 2020 +0200
@@ -47,6 +47,8 @@
  * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
  *
  * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC                                                                        -Xcomp -Xmx256M -XX:+CriticalJNINatives gc.CriticalNativeArgs
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=iu        -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UnlockExperimentalVMOptions -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.CriticalNativeArgs
  */
 public class CriticalNativeArgs {
     public static void main(String[] args) {
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocHumongousFragment.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocHumongousFragment.java	Mon Apr 06 17:08:46 2020 +0200
@@ -93,6 +93,42 @@
  *      TestAllocHumongousFragment
  */
 
+/*
+ * @test TestAllocHumongousFragment
+ * @summary Make sure Shenandoah can recover from humongous allocation fragmentation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @run main/othervm -Xlog: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 -Xlog: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 -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -XX:+ShenandoahOOMDuringEvacALot
+ *      TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -XX:+ShenandoahAllocFailureALot
+ *      TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      -XX:+ShenandoahVerify
+ *      TestAllocHumongousFragment
+ *
+ * @run main/othervm -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -Xmx1g -Xms1g -XX:ShenandoahTargetNumRegions=2048
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      TestAllocHumongousFragment
+ */
+
 import java.util.*;
 import java.util.concurrent.*;
 
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocIntArrays.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocIntArrays.java	Mon Apr 06 17:08:46 2020 +0200
@@ -102,6 +102,46 @@
  *      TestAllocIntArrays
  */
 
+/*
+ * @test TestAllocIntArrays
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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 {
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocObjectArrays.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocObjectArrays.java	Mon Apr 06 17:08:46 2020 +0200
@@ -101,6 +101,46 @@
  *      TestAllocObjectArrays
  */
 
+/*
+ * @test TestAllocObjectArrays
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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 {
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java	Mon Apr 06 17:08:46 2020 +0200
@@ -117,6 +117,51 @@
  *      TestAllocObjects
  */
 
+/*
+ * @test TestAllocObjects
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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
+ *
+ * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      -XX:+ShenandoahSuspendibleWorkers
+ *      TestAllocObjects
+ */
+
 import java.util.Random;
 
 public class TestAllocObjects {
--- a/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java	Mon Apr 06 17:08:46 2020 +0200
@@ -78,6 +78,25 @@
  *      TestGCThreadGroups
  */
 
+/**
+ * @test TestGCThreadGroups
+ * @summary Test Shenandoah GC uses concurrent/parallel threads correctly
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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
--- a/test/hotspot/jtreg/gc/shenandoah/TestHeapUncommit.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestHeapUncommit.java	Mon Apr 06 17:08:46 2020 +0200
@@ -84,6 +84,26 @@
 
 /*
  * @test TestHeapUncommit
+ * @summary Acceptance tests: collector can withstand allocation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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.gc.Shenandoah & !vm.graal.enabled & (vm.bits == "64")
  *
--- a/test/hotspot/jtreg/gc/shenandoah/TestLotsOfCycles.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestLotsOfCycles.java	Mon Apr 06 17:08:46 2020 +0200
@@ -78,6 +78,34 @@
  *     TestLotsOfCycles
  */
 
+/*
+ * @test TestLotsOfCycles
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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
--- a/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestObjItrWithHeapDump.java	Mon Apr 06 17:08:46 2020 +0200
@@ -57,8 +57,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) {
--- a/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestPeriodicGC.java	Mon Apr 06 17:08:46 2020 +0200
@@ -99,6 +99,36 @@
             );
         }
 
+        testWith("Zero interval with iu mode",
+                 false,
+                 "-Xlog:gc",
+                 "-XX:+UnlockDiagnosticVMOptions",
+                 "-XX:+UnlockExperimentalVMOptions",
+                 "-XX:+UseShenandoahGC",
+                 "-XX:ShenandoahGCMode=iu",
+                 "-XX:ShenandoahGuaranteedGCInterval=0"
+        );
+
+        testWith("Short interval with iu mode",
+                 true,
+                 "-Xlog:gc",
+                 "-XX:+UnlockDiagnosticVMOptions",
+                 "-XX:+UnlockExperimentalVMOptions",
+                 "-XX:+UseShenandoahGC",
+                 "-XX:ShenandoahGCMode=iu",
+                 "-XX:ShenandoahGuaranteedGCInterval=1000"
+        );
+
+        testWith("Long interval with iu mode",
+                 false,
+                 "-Xlog:gc",
+                 "-XX:+UnlockDiagnosticVMOptions",
+                 "-XX:+UnlockExperimentalVMOptions",
+                 "-XX:+UseShenandoahGC",
+                 "-XX:ShenandoahGCMode=iu",
+                 "-XX:ShenandoahGuaranteedGCInterval=100000" // deliberately too long
+        );
+
         testWith("Short interval with aggressive",
                  false,
                  "-Xlog:gc",
--- a/test/hotspot/jtreg/gc/shenandoah/TestRefprocSanity.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestRefprocSanity.java	Mon Apr 06 17:08:46 2020 +0200
@@ -42,6 +42,26 @@
  *      TestRefprocSanity
  */
 
+/*
+ * @test TestRefprocSanity
+ * @summary Test that null references/referents work fine
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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 {
--- a/test/hotspot/jtreg/gc/shenandoah/TestRegionSampling.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestRegionSampling.java	Mon Apr 06 17:08:46 2020 +0200
@@ -58,6 +58,20 @@
  *      TestRegionSampling
  */
 
+/*
+ * @test TestRegionSampling
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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
--- a/test/hotspot/jtreg/gc/shenandoah/TestRetainObjects.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestRetainObjects.java	Mon Apr 06 17:08:46 2020 +0200
@@ -92,6 +92,36 @@
  *      TestRetainObjects
  */
 
+/*
+ * @test TestRetainObjects
+ * @summary Acceptance tests: collector can deal with retained objects
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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;
--- a/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java	Mon Apr 06 17:08:46 2020 +0200
@@ -92,6 +92,36 @@
  *      TestSieveObjects
  */
 
+/*
+ * @test TestSieveObjects
+ * @summary Acceptance tests: collector can deal with retained objects
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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 {
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringDedup.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringDedup.java	Mon Apr 06 17:08:46 2020 +0200
@@ -66,6 +66,25 @@
  *      TestStringDedup
  */
 
+/*
+ * @test TestStringDedup
+ * @summary Test Shenandoah string deduplication implementation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc:open
+ * @modules java.base/java.lang:open
+ *          java.management
+ *
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      TestStringDedup
+ *
+ * @run main/othervm -Xmx256m -Xlog:gc+stats -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      TestStringDedup
+ */
+
 import java.lang.reflect.*;
 import java.util.*;
 
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java	Mon Apr 06 17:08:46 2020 +0200
@@ -74,6 +74,38 @@
  *      TestStringDedupStress
  */
 
+ /*
+ * @test TestStringDedupStress
+ * @summary Test Shenandoah string deduplication implementation
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc:open
+ * @modules java.base/java.lang:open
+ *          java.management
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -DtargetStrings=2000000
+ *      TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseStringDeduplication
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      -XX:+ShenandoahOOMDuringEvacALot
+ *      -DtargetStrings=2000000
+ *      TestStringDedupStress
+ *
+ * @run main/othervm -Xmx1g -Xlog:gc+stats -Xlog: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.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringInternCleanup.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringInternCleanup.java	Mon Apr 06 17:08:46 2020 +0200
@@ -77,6 +77,27 @@
  *      TestStringInternCleanup
  */
 
+/*
+ * @test TestStringInternCleanup
+ * @summary Check that Shenandoah cleans up interned strings
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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;
--- a/test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestVerifyJCStress.java	Mon Apr 06 17:08:46 2020 +0200
@@ -60,6 +60,20 @@
  *      TestVerifyJCStress
  */
 
+/*
+ * @test TestVerifyJCStress
+ * @summary Tests that we pass at least one jcstress-like test with all verification turned on
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ *
+ * @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.*;
--- a/test/hotspot/jtreg/gc/shenandoah/TestWrongArrayMember.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/TestWrongArrayMember.java	Mon Apr 06 17:08:46 2020 +0200
@@ -27,7 +27,8 @@
  * @key gc
  * @requires vm.gc.Shenandoah & !vm.graal.enabled
  *
- * @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 {
--- a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestChurnNotifications.java	Mon Apr 06 17:08:46 2020 +0200
@@ -64,6 +64,22 @@
  *      TestChurnNotifications
  */
 
+/*
+ * @test TestChurnNotifications
+ * @summary Check that MX notifications are reported for all cycles
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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.*;
--- a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java	Mon Apr 06 17:08:46 2020 +0200
@@ -62,6 +62,21 @@
  *      TestPauseNotifications
  */
 
+/*
+ * @test TestPauseNotifications
+ * @summary Check that MX notifications are reported for all cycles
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ *
+ * @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.*;
--- a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java	Mon Apr 06 17:08:46 2020 +0200
@@ -126,8 +126,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) {
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestExplicitGC.java	Mon Apr 06 17:08:46 2020 +0200
@@ -126,5 +126,23 @@
                 output.shouldNotContain(p);
             }
         }
+
+        {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                    "-XX:+UnlockExperimentalVMOptions",
+                    "-XX:+UseShenandoahGC",
+                    "-Xlog: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);
+            }
+         }
     }
 }
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java	Mon Apr 06 17:08:46 2020 +0200
@@ -49,6 +49,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:ShenandoahGCHeuristics=passive", Mode.DIAGNOSTIC);
     }
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestSelectiveBarrierFlags.java	Mon Apr 06 17:08:46 2020 +0200
@@ -44,7 +44,7 @@
     public static void main(String[] args) throws Exception {
         String[][] opts = {
                 new String[] { "ShenandoahLoadRefBarrier" },
-                new String[] { "ShenandoahSATBBarrier" },
+                new String[] { "ShenandoahSATBBarrier", "ShenandoahStoreValEnqueueBarrier" },
                 new String[] { "ShenandoahCASBarrier" },
                 new String[] { "ShenandoahCloneBarrier" },
         };
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestWrongBarrierDisable.java	Mon Apr 06 17:08:46 2020 +0200
@@ -40,16 +40,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 {
--- a/test/hotspot/jtreg/gc/stress/CriticalNativeStress.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/stress/CriticalNativeStress.java	Mon Apr 06 17:08:46 2020 +0200
@@ -49,6 +49,8 @@
  *
  * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
  * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC                                       -Xcomp -Xmx256M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu        -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
+ * @run main/othervm/native -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive -Xcomp -Xmx512M -XX:+CriticalJNINatives gc.stress.CriticalNativeStress
  */
 public class CriticalNativeStress {
     private static Random rand = new Random();
--- a/test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithShenandoah.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/stress/gcbasher/TestGCBasherWithShenandoah.java	Mon Apr 06 17:08:46 2020 +0200
@@ -92,6 +92,49 @@
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
  *      gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
  */
+
+/*
+ * @test TestGCBasherWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -XX:+ShenandoahOOMDuringEvacALot
+ *      gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -XX:+ShenandoahAllocFailureALot
+ *      gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ */
+
+/*
+ * @test TestGCBasherWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @requires vm.flavor == "server" & !vm.emulatedClient & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      -XX:+ShenandoahVerify
+ *      gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ *
+ * @run main/othervm/timeout=200 -Xlog:gc*=info -Xmx1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      gc.stress.gcbasher.TestGCBasherWithShenandoah 120000
+ */
 public class TestGCBasherWithShenandoah {
     public static void main(String[] args) throws IOException {
         TestGCBasher.main(args);
--- a/test/hotspot/jtreg/gc/stress/gcold/TestGCOldWithShenandoah.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/stress/gcold/TestGCOldWithShenandoah.java	Mon Apr 06 17:08:46 2020 +0200
@@ -88,6 +88,38 @@
  *      gc.stress.gcold.TestGCOld 50 1 20 10 10000
  */
 
+/*
+ * @test TestGCOldWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @summary Stress the GC by trying to make old objects more likely to be garbage than young objects.
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -XX:+ShenandoahOOMDuringEvacALot
+ *      gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      -XX:+ShenandoahAllocFailureALot
+ *      gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu -XX:ShenandoahGCHeuristics=aggressive
+ *      gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm/timeout=600 -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      -XX:+ShenandoahVerify
+ *      gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ *
+ * @run main/othervm -Xmx384M -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      gc.stress.gcold.TestGCOld 50 1 20 10 10000
+ */
+
 public class TestGCOldWithShenandoah {
 
     public static void main(String[] args) {
--- a/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithShenandoah.java	Mon Apr 06 07:39:58 2020 -0700
+++ b/test/hotspot/jtreg/gc/stress/systemgc/TestSystemGCWithShenandoah.java	Mon Apr 06 17:08:46 2020 +0200
@@ -41,6 +41,21 @@
  *      -XX:+UseShenandoahGC
  *      gc.stress.systemgc.TestSystemGCWithShenandoah 270
  */
+
+/*
+ * @test TestSystemGCWithShenandoah
+ * @key gc
+ * @key stress
+ * @library /
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @summary Stress the Shenandoah GC full GC by allocating objects of different lifetimes concurrently with System.gc().
+ *
+ * @run main/othervm/timeout=300 -Xlog:gc*=info -Xmx512m -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions
+ *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=iu
+ *      -XX:+ShenandoahVerify
+ *      gc.stress.systemgc.TestSystemGCWithShenandoah 270
+ *
+ */
 public class TestSystemGCWithShenandoah {
     public static void main(String[] args) throws Exception {
         TestSystemGC.main(args);