8220602: Shenandoah-SA: Enable best-effort implementation of heap walk
authorzgu
Thu, 14 Mar 2019 09:53:15 -0400
changeset 54388 a1acc800c87a
parent 54387 cbde3b803d93
child 54389 772f62a13376
8220602: Shenandoah-SA: Enable best-effort implementation of heap walk Reviewed-by: rkennke, cjplummer
src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
src/hotspot/share/gc/shenandoah/vmStructs_shenandoah.hpp
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahBitMap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeapRegion.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
test/hotspot/jtreg/serviceability/sa/ClhsdbJhisto.java
test/hotspot/jtreg/serviceability/sa/TestHeapDumpForLargeArray.java
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Thu Mar 14 09:53:15 2019 -0400
@@ -436,6 +436,7 @@
   _cycle_memory_manager("Shenandoah Cycles", "end of GC cycle"),
   _gc_timer(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()),
   _soft_ref_policy(),
+  _log_min_obj_alignment_in_bytes(LogMinObjAlignmentInBytes),
   _ref_processor(NULL),
   _marking_context(NULL),
   _bitmap_size(0),
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Thu Mar 14 09:53:15 2019 -0400
@@ -505,6 +505,8 @@
   ConcurrentGCTimer*           _gc_timer;
   SoftRefPolicy                _soft_ref_policy;
 
+  // For exporting to SA
+  int                          _log_min_obj_alignment_in_bytes;
 public:
   ShenandoahMonitoringSupport* monitoring_support() { return _monitoring_support;    }
   GCMemoryManager* cycle_memory_manager()           { return &_cycle_memory_manager; }
--- a/src/hotspot/share/gc/shenandoah/vmStructs_shenandoah.hpp	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/vmStructs_shenandoah.hpp	Thu Mar 14 09:53:15 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -27,13 +27,28 @@
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
 #include "gc/shenandoah/shenandoahMonitoringSupport.hpp"
 
-#define VM_STRUCTS_SHENANDOAH(nonstatic_field, volatile_nonstatic_field, static_field)  \
-  static_field(ShenandoahHeapRegion, RegionSizeBytes,        size_t)                    \
-  nonstatic_field(ShenandoahHeap, _num_regions,              size_t)                    \
-  volatile_nonstatic_field(ShenandoahHeap, _used,            size_t)                    \
-  volatile_nonstatic_field(ShenandoahHeap, _committed,       size_t)                    \
+#define VM_STRUCTS_SHENANDOAH(nonstatic_field, volatile_nonstatic_field, static_field)                \
+  nonstatic_field(ShenandoahHeap, _num_regions,                    size_t)                            \
+  nonstatic_field(ShenandoahHeap, _regions,                        ShenandoahHeapRegion**)            \
+  nonstatic_field(ShenandoahHeap, _log_min_obj_alignment_in_bytes, int)                               \
+  volatile_nonstatic_field(ShenandoahHeap, _used,                  size_t)                            \
+  volatile_nonstatic_field(ShenandoahHeap, _committed,             size_t)                            \
+  static_field(ShenandoahHeapRegion, RegionSizeBytes,              size_t)                            \
+  static_field(ShenandoahHeapRegion, RegionSizeBytesShift,         size_t)                            \
+  nonstatic_field(ShenandoahHeapRegion, _state,                    ShenandoahHeapRegion::RegionState) \
+  nonstatic_field(ShenandoahHeapRegion, _region_number,            size_t)                            \
 
-#define VM_INT_CONSTANTS_SHENANDOAH(declare_constant, declare_constant_with_value)
+#define VM_INT_CONSTANTS_SHENANDOAH(declare_constant, declare_constant_with_value) \
+  declare_constant(ShenandoahHeapRegion::_empty_uncommitted)                       \
+  declare_constant(ShenandoahHeapRegion::_empty_committed)                         \
+  declare_constant(ShenandoahHeapRegion::_regular)                                 \
+  declare_constant(ShenandoahHeapRegion::_humongous_start)                         \
+  declare_constant(ShenandoahHeapRegion::_humongous_cont)                          \
+  declare_constant(ShenandoahHeapRegion::_pinned_humongous_start)                  \
+  declare_constant(ShenandoahHeapRegion::_cset)                                    \
+  declare_constant(ShenandoahHeapRegion::_pinned)                                  \
+  declare_constant(ShenandoahHeapRegion::_pinned_cset)                             \
+  declare_constant(ShenandoahHeapRegion::_trash)                                   \
 
 #define VM_TYPES_SHENANDOAH(declare_type,                                     \
                             declare_toplevel_type,                            \
@@ -42,5 +57,6 @@
   declare_type(ShenandoahHeapRegion, ContiguousSpace)                         \
   declare_toplevel_type(ShenandoahHeap*)                                      \
   declare_toplevel_type(ShenandoahHeapRegion*)                                \
+  declare_toplevel_type(ShenandoahHeapRegion::RegionState)                    \
 
 #endif // SHARE_GC_SHENANDOAH_VMSTRUCTS_SHENANDOAH_HPP
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java	Thu Mar 14 09:53:15 2019 -0400
@@ -64,6 +64,8 @@
   public abstract long capacity();
   public abstract long used();
 
+  public long oopOffset() { return 0; }
+
   public MemRegion reservedRegion() {
     return new MemRegion(addr.addOffsetTo(reservedFieldOffset));
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahBitMap.java	Thu Mar 14 09:53:15 2019 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.gc.shenandoah;
+
+import sun.jvm.hotspot.utilities.BitMap;
+import sun.jvm.hotspot.utilities.BitMapInterface;
+
+import java.util.HashMap;
+
+public class ShenandoahBitMap implements BitMapInterface {
+    private HashMap<ShenandoahHeapRegion, BitMap> regionToBitMap = new HashMap<>();
+    private ShenandoahHeap heap;
+
+    ShenandoahBitMap(ShenandoahHeap heap) {
+        this.heap = heap;
+    }
+
+    @Override
+    public boolean at(long offset) {
+        ShenandoahHeapRegion region = heap.regionAtOffset(offset);
+        BitMap bitmap = regionToBitMap.get(region);
+        if (bitmap == null) {
+            return false;
+        } else {
+            int index = toBitMapOffset(offset, region);
+            return bitmap.at(index);
+        }
+    }
+
+    @Override
+    public void atPut(long offset, boolean value) {
+        ShenandoahHeapRegion region = heap.regionAtOffset(offset);
+        BitMap bitmap = getOrAddBitMap(region);
+        int index = toBitMapOffset(offset, region);
+        bitmap.atPut(index, value);
+    }
+
+    @Override
+    public void clear() {
+        for (BitMap bitMap : regionToBitMap.values()) {
+            bitMap.clear();
+        }
+    }
+
+    private int toBitMapOffset(long offset, ShenandoahHeapRegion region) {
+        long regionSize = ShenandoahHeapRegion.regionSizeBytes();
+        long regionOffset = region.regionNumber() * regionSize;
+        long offsetInRegion = offset - regionOffset;
+
+        if (offsetInRegion < 0 || offsetInRegion >= regionSize) {
+            throw new RuntimeException("Unexpected negative offset: " + offsetInRegion);
+        }
+        return (int)(offsetInRegion >>> heap.getLogMinObjAlignmentInBytes());
+    }
+
+    private BitMap getOrAddBitMap(ShenandoahHeapRegion region) {
+        BitMap bitMap = regionToBitMap.get(region);
+        if (bitMap == null) {
+            long regionSize = ShenandoahHeapRegion.regionSizeBytes();
+            long maxNumObjects = regionSize >>> heap.getLogMinObjAlignmentInBytes();
+
+            if (maxNumObjects > Integer.MAX_VALUE) {
+                throw new RuntimeException("int overflow");
+            }
+            int intMaxNumObjects = (int)maxNumObjects;
+
+            bitMap = new BitMap(intMaxNumObjects);
+            regionToBitMap.put(region,  bitMap);
+        }
+
+        return bitMap;
+    }
+}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeap.java	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeap.java	Thu Mar 14 09:53:15 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -28,10 +28,14 @@
 import sun.jvm.hotspot.gc.shared.LiveRegionsClosure;
 import sun.jvm.hotspot.debugger.Address;
 import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.runtime.VMObjectFactory;
+import sun.jvm.hotspot.types.AddressField;
 import sun.jvm.hotspot.types.Type;
 import sun.jvm.hotspot.types.TypeDataBase;
 import sun.jvm.hotspot.memory.MemRegion;
 import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.utilities.BitMapInterface;
+
 import java.io.PrintStream;
 import java.util.Observable;
 import java.util.Observer;
@@ -40,6 +44,11 @@
     static private CIntegerField numRegions;
     static private CIntegerField used;
     static private CIntegerField committed;
+    static private AddressField  regions;
+    static private CIntegerField logMinObjAlignmentInBytes;
+
+    static private long regionPtrFieldSize;
+    static private long brookPtrSize;
     static {
         VM.registerVMInitializedObserver(new Observer() {
             public void update(Observable o, Object data) {
@@ -53,6 +62,21 @@
         numRegions = type.getCIntegerField("_num_regions");
         used = type.getCIntegerField("_used");
         committed = type.getCIntegerField("_committed");
+        regions = type.getAddressField("_regions");
+        logMinObjAlignmentInBytes = type.getCIntegerField("_log_min_obj_alignment_in_bytes");
+
+        brookPtrSize = db.lookupIntConstant("HeapWordSize").longValue();
+        Type regionPtrType = db.lookupType("ShenandoahHeapRegion*");
+        regionPtrFieldSize = regionPtrType.getSize();
+    }
+
+    public ShenandoahHeap(Address addr) {
+        super(addr);
+    }
+
+    @Override
+    public long oopOffset() {
+        return brookPtrSize;
     }
 
     @Override
@@ -78,10 +102,35 @@
         return committed.getValue(addr);
     }
 
+    public int getLogMinObjAlignmentInBytes() {
+        return logMinObjAlignmentInBytes.getJInt(addr);
+    }
+
+    public ShenandoahHeapRegion getRegion(long index) {
+        if (index < numOfRegions()) {
+            Address arrayAddr = regions.getValue(addr);
+            Address regAddr = arrayAddr.getAddressAt(index * regionPtrFieldSize);
+            ShenandoahHeapRegion region = VMObjectFactory.newObject(ShenandoahHeapRegion.class, regAddr);
+            region.setHeap(this);
+            return region;
+        }
+        return null;
+    }
+
+    public ShenandoahHeapRegion regionAtOffset(long offset) {
+        long index = offset >>> ShenandoahHeapRegion.regionSizeBytesShift();
+        if (index < 0 || index >= numOfRegions()) {
+            throw new RuntimeException("Invalid offset: " + offset);
+        }
+        return getRegion(index);
+    }
+
     @Override
     public void liveRegionsIterate(LiveRegionsClosure closure) {
-        // Operation (currently) not supported with Shenandoah GC.
-        System.err.println("Warning: Operation not supported with Shenandoah GC");
+        for (long index = 0; index < numOfRegions(); index ++) {
+            ShenandoahHeapRegion region = getRegion(index);
+            closure.doLiveRegions(region);
+        }
     }
 
     @Override
@@ -92,7 +141,9 @@
         tty.println(" region size " + ShenandoahHeapRegion.regionSizeBytes() / 1024 + " K");
     }
 
-    public ShenandoahHeap(Address addr) {
-        super(addr);
+    @Override
+    public BitMapInterface createBitMap(long bits) {
+        return new ShenandoahBitMap(this);
     }
+
 }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeapRegion.java	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shenandoah/ShenandoahHeapRegion.java	Thu Mar 14 09:53:15 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
  *
  * 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
@@ -23,19 +23,43 @@
 
 package sun.jvm.hotspot.gc.shenandoah;
 
+import sun.jvm.hotspot.debugger.OopHandle;
 import sun.jvm.hotspot.gc.shared.ContiguousSpace;
-import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.gc.shared.LiveRegionsProvider;
+import sun.jvm.hotspot.memory.MemRegion;
+import sun.jvm.hotspot.oops.Mark;
+import sun.jvm.hotspot.oops.Oop;
+import sun.jvm.hotspot.oops.UnknownOopException;
+import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.runtime.VM;
-import sun.jvm.hotspot.types.Type;
-import sun.jvm.hotspot.types.TypeDataBase;
 import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.utilities.AddressOps;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Observable;
 import java.util.Observer;
 
 
-public class ShenandoahHeapRegion extends ContiguousSpace {
-    private static CIntegerField RegionSizeBytes;
+public class ShenandoahHeapRegion extends ContiguousSpace implements LiveRegionsProvider {
+    private static int EmptyUncommitted;
+    private static int EmptyCommitted;
+    private static int Regular;
+    private static int HumongousStart;
+    private static int HumongousCont;
+    private static int PinnedHumongousStart;
+    private static int CSet;
+    private static int Pinned;
+    private static int PinnedCSet;
+    private static int Trash;
+
+    private static CIntegerField RegionSizeBytesField;
+    private static Field         RegionStateField;
+    private static CIntegerField RegionNumberField;
+    private static CIntegerField RegionSizeBytesShiftField;
+
+    private ShenandoahHeap heap;
+
     static {
         VM.registerVMInitializedObserver(new Observer() {
             public void update(Observable o, Object data) {
@@ -46,12 +70,154 @@
 
     static private synchronized void initialize(TypeDataBase db) {
         Type type = db.lookupType("ShenandoahHeapRegion");
-        RegionSizeBytes = type.getCIntegerField("RegionSizeBytes");
+        RegionSizeBytesField = type.getCIntegerField("RegionSizeBytes");
+        RegionStateField = type.getField("_state");
+        RegionNumberField = type.getCIntegerField("_region_number");
+
+        RegionSizeBytesShiftField = type.getCIntegerField("RegionSizeBytesShift");
+
+        EmptyUncommitted     = db.lookupIntConstant("ShenandoahHeapRegion::_empty_uncommitted").intValue();
+        EmptyCommitted       = db.lookupIntConstant("ShenandoahHeapRegion::_empty_committed").intValue();
+        Regular              = db.lookupIntConstant("ShenandoahHeapRegion::_regular").intValue();
+        HumongousStart       = db.lookupIntConstant("ShenandoahHeapRegion::_humongous_start").intValue();
+        HumongousCont        = db.lookupIntConstant("ShenandoahHeapRegion::_humongous_cont").intValue();
+        PinnedHumongousStart = db.lookupIntConstant("ShenandoahHeapRegion::_pinned_humongous_start").intValue();
+        CSet                 = db.lookupIntConstant("ShenandoahHeapRegion::_cset").intValue();
+        Pinned               = db.lookupIntConstant("ShenandoahHeapRegion::_pinned").intValue();
+        PinnedCSet           = db.lookupIntConstant("ShenandoahHeapRegion::_pinned_cset").intValue();
+        Trash                = db.lookupIntConstant("ShenandoahHeapRegion::_trash").intValue();
     }
 
-    public static long regionSizeBytes() { return RegionSizeBytes.getValue(); }
+    public static long regionSizeBytes() {
+        return RegionSizeBytesField.getValue();
+    }
+
+    public static int  regionSizeBytesShift() {
+        return RegionSizeBytesShiftField.getJInt();
+    }
 
     public ShenandoahHeapRegion(Address addr) {
         super(addr);
     }
+
+    public void setHeap(ShenandoahHeap heap) {
+        this.heap = heap;
+    }
+
+    @Override
+    public int hashCode() {
+        return (int)regionNumber();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other instanceof ShenandoahHeapRegion) {
+            ShenandoahHeapRegion otherRegion = (ShenandoahHeapRegion)other;
+            return otherRegion.regionNumber() == regionNumber();
+        }
+        return false;
+    }
+
+    public List<MemRegion> getLiveRegions() {
+        List<MemRegion> res = new ArrayList<>();
+        int state = regionState();
+        if (state == EmptyUncommitted || state == EmptyCommitted || state == Trash) {
+            // No live data
+        } else if (state == HumongousCont) {
+            // Handled by HumongousStart
+        } else if (state == HumongousStart || state == PinnedHumongousStart) {
+            handleHumongousRegion(res);
+        } else if (state == Regular || state == Pinned) {
+            handleRegularRegion(res);
+        } else if (state == CSet || state == PinnedCSet) {
+            // CSet
+            handleCSetRegion(res);
+        } else {
+            throw new RuntimeException("Unknown region state: " + state);
+        }
+        return res;
+    }
+
+    /*
+     * Note: RegionState is an enum on JVM side. Seems that there is not
+     *       a standard way to read enum value. We read it as an integer
+     *       from the field's offset.
+     */
+    private int regionState() {
+        long offset = RegionStateField.getOffset();
+        return addr.getJIntAt(offset);
+    }
+
+    private void handleHumongousRegion(List<MemRegion> res) {
+        long index = regionNumber();
+        Address topAddr = top();
+        ShenandoahHeapRegion region = heap.getRegion(++ index);
+        while (region.regionState() == HumongousCont) {
+            topAddr = region.top();
+            region = heap.getRegion(++ index);
+        }
+        res.add(new MemRegion(bottom(), topAddr));
+    }
+
+    private void handleRegularRegion(List<MemRegion> res) {
+        res.add(new MemRegion(bottom(), top()));
+    }
+
+    // Filter out forwarded objects, they should be counted in other regions
+    private void handleCSetRegion(List<MemRegion> res) {
+        Address end = top();
+        Address start = bottom();
+
+        Address regionStart = null;
+        Address regionEnd = null;
+        while (AddressOps.lessThan(start, end)) {
+            long size = getObjectSize(start);
+            if (hasForwardee(start)) {
+                // has to-space object, skip this one
+                if (regionEnd != null) {
+                    MemRegion mr = new MemRegion(regionStart, regionEnd);
+                    res.add(mr);
+                    regionStart = null;
+                    regionEnd = null;
+                }
+            } else {
+                if (regionStart == null) {
+                    regionStart = start;
+                } else {
+                    regionEnd = start.addOffsetTo(heap.oopOffset() + size);
+                }
+            }
+            start = start.addOffsetTo(heap.oopOffset() + size);
+        }
+
+        if (regionStart != null) {
+            MemRegion mr = new MemRegion(regionStart, top());
+            res.add(mr);
+        }
+    }
+
+    public long regionNumber() {
+        return RegionNumberField.getValue(addr);
+    }
+
+    private boolean hasForwardee(Address rawPtr) {
+        // Use Mark as a helper to read forward pointer value.
+        Mark mark = new Mark(rawPtr);
+        Address forwardee = mark.valueAsAddress();
+        return (forwardee != rawPtr.addOffsetTo(heap.oopOffset()));
+    }
+
+    private long getObjectSize(Address rawPtr) {
+        // Dealing with a raw pointer, offsets forward pointer to find real Oop.
+        OopHandle handle = rawPtr.addOffsetToAsOopHandle(heap.oopOffset());
+        Oop obj = null;
+
+        try {
+            // Best effort, may fail
+            obj = VM.getVM().getObjectHeap().newOop(handle);
+        } catch (UnknownOopException exp) {
+            throw new RuntimeException(" UnknownOopException  " + exp);
+        }
+        return obj.getObjectSize();
+    }
 }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Tue Apr 02 16:36:00 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Thu Mar 14 09:53:15 2019 -0400
@@ -255,7 +255,9 @@
         OopHandle handle = bottom.addOffsetToAsOopHandle(0);
 
         while (handle.lessThan(top)) {
-        Oop obj = null;
+          Oop obj = null;
+          // Raw pointer walk
+          handle = handle.addOffsetToAsOopHandle(heap.oopOffset());
 
           try {
             obj = newOop(handle);
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbJhisto.java	Tue Apr 02 16:36:00 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJhisto.java	Thu Mar 14 09:53:15 2019 -0400
@@ -35,7 +35,6 @@
  * @bug 8191658
  * @summary Test clhsdb jhisto command
  * @requires vm.hasSA
- * @requires vm.gc != "Shenandoah"
  * @library /test/lib
  * @run main/othervm ClhsdbJhisto
  */
--- a/test/hotspot/jtreg/serviceability/sa/TestHeapDumpForLargeArray.java	Tue Apr 02 16:36:00 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/TestHeapDumpForLargeArray.java	Thu Mar 14 09:53:15 2019 -0400
@@ -47,7 +47,6 @@
  * @library /test/lib
  * @bug 8171084
  * @requires vm.hasSAandCanAttach & (vm.bits == "64" & os.maxMemory > 8g)
- * @requires vm.gc != "Shenandoah"
  * @modules java.base/jdk.internal.misc
  *          jdk.hotspot.agent/sun.jvm.hotspot
  *          jdk.hotspot.agent/sun.jvm.hotspot.utilities