--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-05-10 10:58:28.942388044 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-05-10 10:58:28.630390074 -0400
@@ -66,6 +66,9 @@
#include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
#include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
#include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
+#if INCLUDE_JFR
+#include "gc/shenandoah/shenandoahJfrSupport.hpp"
+#endif
#include "memory/metaspace.hpp"
#include "oops/compressedOops.inline.hpp"
#include "runtime/globals.hpp"
@@ -583,6 +586,8 @@
ref_processing_init();
_heuristics->initialize();
+
+ JFR_ONLY(ShenandoahJFRSupport::register_jfr_type_serializers());
}
size_t ShenandoahHeap::used() const {
--- old/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp 2019-05-10 10:58:29.551384080 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp 2019-05-10 10:58:29.239386111 -0400
@@ -30,6 +30,7 @@
#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
#include "gc/shenandoah/shenandoahTraversalGC.hpp"
#include "gc/shared/space.inline.hpp"
+#include "jfr/jfrEvents.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
@@ -93,7 +94,7 @@
case _empty_uncommitted:
do_commit();
case _empty_committed:
- _state = _regular;
+ set_state(_regular);
case _regular:
case _pinned:
return;
@@ -114,10 +115,10 @@
case _cset:
case _humongous_start:
case _humongous_cont:
- _state = _regular;
+ set_state(_regular);
return;
case _pinned_cset:
- _state = _pinned;
+ set_state(_pinned);
return;
case _regular:
case _pinned:
@@ -133,7 +134,7 @@
case _empty_uncommitted:
do_commit();
case _empty_committed:
- _state = _humongous_start;
+ set_state(_humongous_start);
return;
default:
report_illegal_transition("humongous start allocation");
@@ -149,7 +150,7 @@
case _regular:
case _humongous_start:
case _humongous_cont:
- _state = _humongous_start;
+ set_state(_humongous_start);
return;
default:
report_illegal_transition("humongous start bypass");
@@ -162,7 +163,7 @@
case _empty_uncommitted:
do_commit();
case _empty_committed:
- _state = _humongous_cont;
+ set_state(_humongous_cont);
return;
default:
report_illegal_transition("humongous continuation allocation");
@@ -178,7 +179,7 @@
case _regular:
case _humongous_start:
case _humongous_cont:
- _state = _humongous_cont;
+ set_state(_humongous_cont);
return;
default:
report_illegal_transition("humongous continuation bypass");
@@ -190,14 +191,14 @@
switch (_state) {
case _regular:
assert (_critical_pins == 0, "sanity");
- _state = _pinned;
+ set_state(_pinned);
case _pinned_cset:
case _pinned:
_critical_pins++;
return;
case _humongous_start:
assert (_critical_pins == 0, "sanity");
- _state = _pinned_humongous_start;
+ set_state(_pinned_humongous_start);
case _pinned_humongous_start:
_critical_pins++;
return;
@@ -219,7 +220,7 @@
assert (_critical_pins > 0, "sanity");
_critical_pins--;
if (_critical_pins == 0) {
- _state = _regular;
+ set_state(_regular);
}
return;
case _regular:
@@ -231,14 +232,14 @@
assert (_critical_pins > 0, "sanity");
_critical_pins--;
if (_critical_pins == 0) {
- _state = _cset;
+ set_state(_cset);
}
return;
case _pinned_humongous_start:
assert (_critical_pins > 0, "sanity");
_critical_pins--;
if (_critical_pins == 0) {
- _state = _humongous_start;
+ set_state(_humongous_start);
}
return;
default:
@@ -250,7 +251,7 @@
_heap->assert_heaplock_owned_by_current_thread();
switch (_state) {
case _regular:
- _state = _cset;
+ set_state(_cset);
case _cset:
return;
default:
@@ -268,7 +269,7 @@
// Reclaiming humongous regions
case _regular:
// Immediate region reclaim
- _state = _trash;
+ set_state(_trash);
return;
default:
report_illegal_transition("trashing");
@@ -287,7 +288,7 @@
_heap->assert_heaplock_owned_by_current_thread();
switch (_state) {
case _trash:
- _state = _empty_committed;
+ set_state(_empty_committed);
_empty_time = os::elapsedTime();
return;
default:
@@ -300,7 +301,7 @@
switch (_state) {
case _empty_committed:
do_uncommit();
- _state = _empty_uncommitted;
+ set_state(_empty_uncommitted);
return;
default:
report_illegal_transition("uncommiting");
@@ -314,7 +315,7 @@
switch (_state) {
case _empty_uncommitted:
do_commit();
- _state = _empty_committed;
+ set_state(_empty_committed);
return;
default:
report_illegal_transition("commit bypass");
@@ -679,3 +680,16 @@
}
_heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
}
+
+void ShenandoahHeapRegion::set_state(RegionState to) {
+ EventShenandoahHeapRegionStateChange evt;
+ if (evt.should_commit()){
+ evt.set_index(region_number());
+ evt.set_start((uintptr_t)bottom());
+ evt.set_used(used());
+ evt.set_from(_state);
+ evt.set_to(to);
+ evt.commit();
+ }
+ _state = to;
+}
--- old/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp 2019-05-10 10:58:30.136380273 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp 2019-05-10 10:58:29.826382291 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -32,9 +32,11 @@
#include "utilities/sizes.hpp"
class VMStructs;
+class ShenandoahHeapRegionStateConstant;
class ShenandoahHeapRegion : public ContiguousSpace {
friend class VMStructs;
+ friend class ShenandoahHeapRegionStateConstant;
private:
/*
Region state is described by a state machine. Transitions are guarded by
@@ -115,9 +117,10 @@
_pinned, // region is pinned
_pinned_cset, // region is pinned and in cset (evac failure path)
_trash, // region contains only trash
+ _REGION_STATES_NUM, // last
};
- const char* region_state_to_string(RegionState s) const {
+ static const char* region_state_to_string(RegionState s) {
switch (s) {
case _empty_uncommitted: return "Empty Uncommitted";
case _empty_committed: return "Empty Committed";
@@ -157,6 +160,10 @@
void report_illegal_transition(const char* method);
public:
+ static const int region_states_num() {
+ return _REGION_STATES_NUM;
+ }
+
// Allowed transitions from the outside code:
void make_regular_allocation();
void make_regular_bypass();
@@ -424,6 +431,8 @@
void oop_iterate_humongous(OopIterateClosure* cl);
inline void internal_increase_live_data(size_t s);
+
+ void set_state(RegionState to);
};
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
--- old/src/hotspot/share/jfr/metadata/metadata.xml 2019-05-10 10:58:30.719376479 -0400
+++ new/src/hotspot/share/jfr/metadata/metadata.xml 2019-05-10 10:58:30.406378516 -0400
@@ -979,6 +979,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- old/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp 2019-05-10 10:58:31.327372522 -0400
+++ new/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp 2019-05-10 10:58:31.011374579 -0400
@@ -65,7 +65,9 @@
#include "services/threadService.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/globalDefinitions.hpp"
-
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/shenandoahJfrSupport.hpp"
+#endif
/**
* JfrPeriodic class
* Implementation of declarations in
@@ -620,3 +622,14 @@
event.set_flushingEnabled(UseCodeCacheFlushing);
event.commit();
}
+
+
+TRACE_REQUEST_FUNC(ShenandoahHeapRegionInformation) {
+#if INCLUDE_SHENANDOAHGC
+ if (UseShenandoahGC) {
+ VM_ShenandoahSendHeapRegionInfoEvents op;
+ VMThread::execute(&op);
+ }
+#endif
+}
+
--- old/src/jdk.jfr/share/conf/jfr/default.jfc 2019-05-10 10:58:31.910368728 -0400
+++ new/src/jdk.jfr/share/conf/jfr/default.jfc 2019-05-10 10:58:31.602370733 -0400
@@ -444,6 +444,15 @@
false
+
+
+ false
+ everyChunk
+
+
+
+ false
+
true
--- old/src/jdk.jfr/share/conf/jfr/profile.jfc 2019-05-10 10:58:32.496364914 -0400
+++ new/src/jdk.jfr/share/conf/jfr/profile.jfc 2019-05-10 10:58:32.187366926 -0400
@@ -445,6 +445,15 @@
false
+
+ false
+ everyChunk
+
+
+
+ false
+
+
true
true
--- old/test/lib/jdk/test/lib/jfr/EventNames.java 2019-05-10 10:58:33.075361146 -0400
+++ new/test/lib/jdk/test/lib/jfr/EventNames.java 2019-05-10 10:58:32.767363151 -0400
@@ -101,6 +101,8 @@
public final static String G1HeapSummary = PREFIX + "G1HeapSummary";
public final static String G1HeapRegionInformation = PREFIX + "G1HeapRegionInformation";
public final static String G1HeapRegionTypeChange = PREFIX + "G1HeapRegionTypeChange";
+ public final static String ShenandoahHeapRegionInformation = PREFIX + "ShenandoahHeapRegionInformation";
+ public final static String ShenandoahHeapRegionStateChange = PREFIX + "ShenandoahHeapRegionStateChange";
public final static String TenuringDistribution = PREFIX + "TenuringDistribution";
public final static String GarbageCollection = PREFIX + "GarbageCollection";
public final static String ParallelOldGarbageCollection = PREFIX + "ParallelOldGarbageCollection";
--- old/test/lib/jdk/test/lib/jfr/GCHelper.java 2019-05-10 10:58:33.659357346 -0400
+++ new/test/lib/jdk/test/lib/jfr/GCHelper.java 2019-05-10 10:58:33.348359370 -0400
@@ -80,6 +80,7 @@
public static final String pauseLevelEvent = "GCPhasePauseLevel";
private static final List g1HeapRegionTypes;
+ private static final List shenandoahHeapRegionStates;
private static PrintStream defaultErrorLog = null;
public static int getGcId(RecordedEvent event) {
@@ -207,6 +208,21 @@
};
g1HeapRegionTypes = Collections.unmodifiableList(Arrays.asList(g1HeapRegionTypeLiterals));
+
+ String[] shenandoahHeapRegionStateLiterals = new String[] {
+ "Empty Uncommitted",
+ "Empty Committed",
+ "Regular",
+ "Humongous Start",
+ "Humongous Continuation",
+ "Humonguous Start, Pinned",
+ "Collection Set",
+ "Pinned",
+ "Collection Set, Pinned",
+ "Trash"
+ };
+
+ shenandoahHeapRegionStates = Collections.unmodifiableList(Arrays.asList(shenandoahHeapRegionStateLiterals));
}
/**
@@ -443,6 +459,10 @@
return g1HeapRegionTypes.contains(type);
}
+ public static boolean isValidShenandoahHeapRegionState(final String state) {
+ return shenandoahHeapRegionStates.contains(state);
+ }
+
/**
* Helper function to align heap size up.
*
--- /dev/null 2019-05-06 12:15:55.902439824 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp 2019-05-10 10:58:33.936355543 -0400
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeapRegion.hpp"
+#include "gc/shenandoah/shenandoahJfrSupport.hpp"
+#include "jfr/jfrEvents.hpp"
+#if INCLUDE_JFR
+#include "jfr/metadata/jfrSerializer.hpp"
+#endif
+
+#if INCLUDE_JFR
+
+class ShenandoahHeapRegionStateConstant : public JfrSerializer {
+ friend class ShenandoahHeapRegion;
+public:
+ virtual void serialize(JfrCheckpointWriter& writer) {
+ static const u4 nof_entries = ShenandoahHeapRegion::region_states_num();
+ writer.write_count(nof_entries);
+ for (u4 i = 0; i < nof_entries; ++i) {
+ writer.write_key(i);
+ writer.write(ShenandoahHeapRegion::region_state_to_string((ShenandoahHeapRegion::RegionState)i));
+ }
+ }
+};
+
+void ShenandoahJFRSupport::register_jfr_type_serializers() {
+ JfrSerializer::register_serializer(TYPE_SHENANDOAHHEAPREGIONSTATE,
+ false,
+ true,
+ new ShenandoahHeapRegionStateConstant());
+}
+#endif
+
+class ShenandoahDumpHeapRegionInfoClosure : public ShenandoahHeapRegionClosure {
+public:
+ virtual void heap_region_do(ShenandoahHeapRegion* r) {
+ EventShenandoahHeapRegionInformation evt;
+ evt.set_index(r->region_number());
+ evt.set_state((u8)r->state());
+ evt.set_start((uintptr_t)r->bottom());
+ evt.set_used(r->used());
+ evt.commit();
+ }
+};
+
+void VM_ShenandoahSendHeapRegionInfoEvents::doit() {
+ ShenandoahDumpHeapRegionInfoClosure c;
+ ShenandoahHeap::heap()->heap_region_iterate(&c);
+}
--- /dev/null 2019-05-06 12:15:55.902439824 -0400
+++ new/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.hpp 2019-05-10 10:58:34.533351658 -0400
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
+#define SHARE_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
+
+#include "runtime/vmOperations.hpp"
+
+class VM_ShenandoahSendHeapRegionInfoEvents : public VM_Operation {
+public:
+ virtual void doit();
+ virtual VMOp_Type type() const { return VMOp_HeapIterateOperation; }
+};
+
+class ShenandoahJFRSupport {
+public:
+ static void register_jfr_type_serializers();
+};
+
+#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
--- /dev/null 2019-05-06 12:15:55.902439824 -0400
+++ new/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionInformationEvent.java 2019-05-10 10:58:35.133347754 -0400
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.jfr.event.gc.detailed;
+
+import java.nio.file.Paths;
+import java.util.List;
+
+import jdk.jfr.EventType;
+import jdk.jfr.FlightRecorder;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+import jdk.test.lib.jfr.GCHelper;
+
+/**
+ * @test
+ * @bug 8221507
+ * @requires vm.hasJFR
+ * @requires vm.gc == "Shenandoah" | vm.gc == null
+ * @key jfr
+ * @library /test/lib /test/jdk
+ * @run main/othervm -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionStateChangeEvent
+ */
+
+
+public class TestShenandoahHeapRegionInformationEvent {
+ private final static String EVENT_NAME = EventNames.ShenandoahHeapRegionInformation;
+ public static void main(String[] args) throws Exception {
+ Recording recording = null;
+ try {
+ recording = new Recording();
+ // activate the event we are interested in and start recording
+ for (EventType t : FlightRecorder.getFlightRecorder().getEventTypes()) {
+ System.out.println(t.getName());
+ }
+ recording.enable(EVENT_NAME);
+ recording.start();
+ recording.stop();
+
+ // Verify recording
+ List events = Events.fromRecording(recording);
+ Events.hasEvents(events);
+
+ for (RecordedEvent event : events) {
+ Events.assertField(event, "index").notEqual(-1);
+ Asserts.assertTrue(GCHelper.isValidShenandoahHeapRegionState(Events.assertField(event, "type").getValue()));
+ Events.assertField(event, "used").atMost(1L*1024*1024);
+ }
+
+ } catch (Throwable t) {
+ if (recording != null) {
+ recording.dump(Paths.get("TestShenandoahHeapRegionInformationEvent.jfr"));
+ }
+ throw t;
+ } finally {
+ if (recording != null) {
+ recording.close();
+ }
+ }
+ }
+}
--- /dev/null 2019-05-06 12:15:55.902439824 -0400
+++ new/test/jdk/jdk/jfr/event/gc/detailed/TestShenandoahHeapRegionStateChangeEvent.java 2019-05-10 10:58:35.732343855 -0400
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, 2018, Oracle and/or its affiliates. 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.jfr.event.gc.detailed;
+
+import java.nio.file.Paths;
+import java.time.Duration;
+import java.util.List;
+
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+import jdk.test.lib.jfr.Events;
+import jdk.test.lib.jfr.GCHelper;
+
+/**
+ * @test
+ * @bug 8221507
+ * @requires vm.hasJFR
+ * @requires vm.gc == "Shenandoah" | vm.gc == null
+ * @key jfr
+ * @library /test/lib /test/jdk
+ * @run main/othervm -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionStateChangeEvent
+ */
+
+public class TestShenandoahHeapRegionStateChangeEvent {
+ private final static String EVENT_NAME = EventNames.ShenandoahHeapRegionStateChange;
+
+ public static void main(String[] args) throws Exception {
+ Recording recording = null;
+ try {
+ recording = new Recording();
+ // activate the event we are interested in and start recording
+ recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(0));
+ recording.start();
+
+ // Setting NewSize and MaxNewSize will limit eden, so
+ // allocating 1024 20k byte arrays should trigger at
+ // least a few Young GCs.
+ byte[][] array = new byte[1024][];
+ for (int i = 0; i < array.length; i++) {
+ array[i] = new byte[20 * 1024];
+ }
+ recording.stop();
+
+ // Verify recording
+ List events = Events.fromRecording(recording);
+ Asserts.assertFalse(events.isEmpty(), "No events found");
+
+ for (RecordedEvent event : events) {
+ Events.assertField(event, "index").notEqual(-1);
+ Asserts.assertTrue(GCHelper.isValidShenandoahHeapRegionState(Events.assertField(event, "from").getValue()));
+ Asserts.assertTrue(GCHelper.isValidShenandoahHeapRegionState(Events.assertField(event, "to").getValue()));
+ Events.assertField(event, "used").atMost(1L*1024*1024);
+ }
+ } catch (Throwable t) {
+ if (recording != null) {
+ recording.dump(Paths.get("TestShenandoahHeapRegionStateChangeEvent.jfr"));
+ }
+ throw t;
+ } finally {
+ if (recording != null) {
+ recording.close();
+ }
+ }
+ }
+}