From 58899f08552ce5ba44134a0bdc08308e45a0e0e0 Mon Sep 17 00:00:00 2001 From: Robert Toyonaga Date: Mon, 28 Aug 2023 16:22:47 -0400 Subject: [PATCH 1/8] new gc events --- .../oracle/svm/core/genscavenge/GCImpl.java | 8 ++- .../genscavenge/ThreadLocalAllocation.java | 7 +- .../src/com/oracle/svm/core/jfr/JfrEvent.java | 3 + .../jfr/events/AllocationRequiringGC.java | 59 +++++++++++++++++ .../EveryChunkNativePeriodicEvents.java | 16 +++++ .../svm/core/jfr/events/SystemGCEvent.java | 62 ++++++++++++++++++ .../jfr/TestAllocationRequiringGCEvent.java | 65 +++++++++++++++++++ .../svm/test/jfr/TestSystemGCEvent.java | 52 +++++++++++++++ 8 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java create mode 100644 substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java create mode 100644 substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index 65415bf20647..cdad9a036156 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -78,6 +78,8 @@ import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.jfr.JfrGCWhen; import com.oracle.svm.core.jfr.JfrTicks; +import com.oracle.svm.core.jfr.events.AllocationRequiringGC; +import com.oracle.svm.core.jfr.events.SystemGCEvent; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.os.CommittedMemoryProvider; import com.oracle.svm.core.snippets.ImplicitExceptions; @@ -141,12 +143,14 @@ public void collect(GCCause cause) { collect(cause, false); } - public void maybeCollectOnAllocation() { + public void maybeCollectOnAllocation(UnsignedWord size) { boolean outOfMemory = false; + long startTicks = JfrTicks.elapsedTicks(); if (hasNeverCollectPolicy()) { UnsignedWord edenUsed = HeapImpl.getHeapImpl().getAccounting().getEdenUsedBytes(); outOfMemory = edenUsed.aboveThan(GCImpl.getPolicy().getMaximumHeapSize()); } else if (getPolicy().shouldCollectOnAllocation()) { + AllocationRequiringGC.emit(startTicks, getCollectionEpoch().rawValue(), size); outOfMemory = collectWithoutAllocating(GenScavengeGCCause.OnAllocation, false); } if (outOfMemory) { @@ -157,7 +161,9 @@ public void maybeCollectOnAllocation() { @Override public void maybeCauseUserRequestedCollection(GCCause cause, boolean fullGC) { if (policy.shouldCollectOnRequest(cause, fullGC)) { + long startTicks = JfrTicks.elapsedTicks(); collect(cause, fullGC); + SystemGCEvent.emit(startTicks, false); } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java index e42ad9153ec2..b0aa5bfc7af2 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java @@ -230,14 +230,15 @@ private static Object slowPathNewInstance(Word objectHeader) { private static Object slowPathNewInstanceWithoutAllocating(DynamicHub hub) { DeoptTester.disableDeoptTesting(); long startTicks = JfrTicks.elapsedTicks(); + UnsignedWord size = LayoutEncoding.getPureInstanceAllocationSize(hub.getLayoutEncoding()); try { HeapImpl.exitIfAllocationDisallowed("ThreadLocalAllocation.slowPathNewInstanceWithoutAllocating", DynamicHub.toClass(hub).getName()); - GCImpl.getGCImpl().maybeCollectOnAllocation(); + GCImpl.getGCImpl().maybeCollectOnAllocation(size); AlignedHeader newTlab = HeapImpl.getChunkProvider().produceAlignedChunk(); return allocateInstanceInNewTlab(hub, newTlab); } finally { - ObjectAllocationInNewTLABEvent.emit(startTicks, hub, LayoutEncoding.getPureInstanceAllocationSize(hub.getLayoutEncoding()), HeapParameters.getAlignedHeapChunkSize()); + ObjectAllocationInNewTLABEvent.emit(startTicks, hub, size, HeapParameters.getAlignedHeapChunkSize()); DeoptTester.enableDeoptTesting(); } } @@ -296,7 +297,7 @@ private static Object slowPathNewArrayLikeObject0(DynamicHub hub, int length, Un UnsignedWord tlabSize = HeapParameters.getAlignedHeapChunkSize(); try { HeapImpl.exitIfAllocationDisallowed("ThreadLocalAllocation.slowPathNewArrayOrPodWithoutAllocating", DynamicHub.toClass(hub).getName()); - GCImpl.getGCImpl().maybeCollectOnAllocation(); + GCImpl.getGCImpl().maybeCollectOnAllocation(size); if (size.aboveOrEqual(HeapParameters.getLargeArrayThreshold())) { /* Large arrays go into their own unaligned chunk. */ diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java index d315af251a8e..d429be4fc610 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java @@ -62,6 +62,9 @@ public final class JfrEvent { public static final JfrEvent JavaMonitorInflate = create("jdk.JavaMonitorInflate", true); public static final JfrEvent ObjectAllocationInNewTLAB = create("jdk.ObjectAllocationInNewTLAB", false); public static final JfrEvent GCHeapSummary = create("jdk.GCHeapSummary", false); + public static final JfrEvent SystemGC = create("jdk.SystemGC", true); + public static final JfrEvent GCTLABConfiguration = create("jdk.GCTLABConfiguration", false); + public static final JfrEvent AllocationRequiringGC = create("jdk.AllocationRequiringGC", false); private final long id; private final String name; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java new file mode 100644 index 000000000000..32c9627e2336 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023, 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. 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 com.oracle.svm.core.jfr.events; + +import com.oracle.svm.core.Uninterruptible; +import com.oracle.svm.core.jfr.HasJfrSupport; +import com.oracle.svm.core.jfr.JfrEvent; +import com.oracle.svm.core.jfr.JfrNativeEventWriter; +import com.oracle.svm.core.jfr.JfrNativeEventWriterData; +import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess; +import com.oracle.svm.core.jfr.SubstrateJVM; +import org.graalvm.nativeimage.StackValue; + +public class AllocationRequiringGC { + public static void emit(long startTicks, long gcId, org.graalvm.word.UnsignedWord size) { + if (HasJfrSupport.get()) { + emit0(startTicks, gcId, size); + } + } + + @Uninterruptible(reason = "Accesses a JFR buffer.") + private static void emit0(long startTicks, long gcId, org.graalvm.word.UnsignedWord size) { + if (JfrEvent.AllocationRequiringGC.shouldEmit()) { + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); + JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.AllocationRequiringGC); + JfrNativeEventWriter.putLong(data, startTicks); + JfrNativeEventWriter.putEventThread(data); + JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.AllocationRequiringGC, 0)); + JfrNativeEventWriter.putLong(data, gcId); + JfrNativeEventWriter.putLong(data, size.rawValue()); + JfrNativeEventWriter.endSmallEvent(data); + } + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java index a25144e6b2fc..d6f4e11d3f97 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java @@ -27,6 +27,7 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; +//import com.oracle.svm.core.genscavenge.HeapParameters; import org.graalvm.nativeimage.StackValue; import com.oracle.svm.core.Uninterruptible; @@ -50,6 +51,7 @@ public static void emit() { threadMXBean.getTotalStartedThreadCount(), threadMXBean.getPeakThreadCount()); emitPhysicalMemory(com.oracle.svm.core.heap.PhysicalMemory.size().rawValue(), 0); +// emitGCTLABConfiguration(); } @Uninterruptible(reason = "Accesses a JFR buffer.") @@ -81,4 +83,18 @@ private static void emitPhysicalMemory(long totalSize, long usedSize) { JfrNativeEventWriter.endSmallEvent(data); } } +// @Uninterruptible(reason = "Accesses a JFR buffer.") +// private static void emitGCTLABConfiguration() { +// if (JfrEvent.GCTLABConfiguration.shouldEmit()) { +// JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); +// JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); +// +// JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCTLABConfiguration); +// JfrNativeEventWriter.putLong(data, JfrTicks.elapsedTicks()); +// JfrNativeEventWriter.putLong(data, HeapParameters.getAlignedHeapChunkSize()); +// JfrNativeEventWriter.putLong(data, 0); +// JfrNativeEventWriter.putBoolean(data, true); +// JfrNativeEventWriter.endSmallEvent(data); +// } +// } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java new file mode 100644 index 000000000000..fa6446165029 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023, 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. 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 com.oracle.svm.core.jfr.events; + +import org.graalvm.nativeimage.StackValue; + +import com.oracle.svm.core.Uninterruptible; +import com.oracle.svm.core.jfr.HasJfrSupport; +import com.oracle.svm.core.jfr.JfrEvent; +import com.oracle.svm.core.jfr.JfrNativeEventWriter; +import com.oracle.svm.core.jfr.JfrNativeEventWriterData; +import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess; +import com.oracle.svm.core.jfr.JfrTicks; +import com.oracle.svm.core.jfr.SubstrateJVM; + +public class SystemGCEvent { + public static void emit(long startTicks, boolean invokedConcurrent) { + if (HasJfrSupport.get()) { + emit0(startTicks, invokedConcurrent); + } + } + + @Uninterruptible(reason = "Accesses a JFR buffer.") + private static void emit0(long startTicks, boolean invokedConcurrent) { + long duration = JfrTicks.duration(startTicks); + if (JfrEvent.SystemGC.shouldEmit(duration)) { + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); + JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.SystemGC); + JfrNativeEventWriter.putLong(data, startTicks); + JfrNativeEventWriter.putLong(data, duration); + JfrNativeEventWriter.putEventThread(data); + JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.SystemGC, 0)); + JfrNativeEventWriter.putBoolean(data, invokedConcurrent); + JfrNativeEventWriter.endSmallEvent(data); + } + } +} diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java new file mode 100644 index 000000000000..b797db889af4 --- /dev/null +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023, 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. 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 com.oracle.svm.test.jfr; + +import com.oracle.svm.core.NeverInline; +import com.oracle.svm.core.genscavenge.HeapParameters; +import com.oracle.svm.core.util.UnsignedUtils; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertTrue; + +public class TestAllocationRequiringGCEvent extends JfrRecordingTest { + private static final int MAX_YOUNG_SIZE = 256 * 1024 * 1024; + + @Test + public void test() throws Throwable { + String[] events = new String[]{"jdk.AllocationRequiringGC"}; + Recording recording = startRecording(events); + final int alignedHeapChunkSize = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkSize()); + + // 256MB is max eden size specified by getMaximumYoungGenerationSize() + allocateByteArray(MAX_YOUNG_SIZE); + allocateByteArray(alignedHeapChunkSize * 2); + + stopRecording(recording, TestAllocationRequiringGCEvent::validateEvents); + } + + private static void validateEvents(List events) { + assertTrue(events.size() > 0); + } + + @NeverInline("Prevent escape analysis.") + private static byte[] allocateByteArray(int length) { + return new byte[length]; + } +} diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java new file mode 100644 index 000000000000..1bc6299661f2 --- /dev/null +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023, 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. 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 com.oracle.svm.test.jfr; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; + +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class TestSystemGCEvent extends JfrRecordingTest { + @Test + public void test() throws Throwable { + String[] events = new String[]{"jdk.SystemGC"}; + Recording recording = startRecording(events); + + System.gc(); + + stopRecording(recording, TestSystemGCEvent::validateEvents); + } + + private static void validateEvents(List events) { + assertEquals(1, events.size()); + } +} From 03c3cc3cd336e75320298a1af5ee7bd5dc043a1b Mon Sep 17 00:00:00 2001 From: Robert Toyonaga Date: Mon, 28 Aug 2023 16:26:52 -0400 Subject: [PATCH 2/8] minor clean up --- .../src/com/oracle/svm/core/jfr/JfrEvent.java | 1 - .../events/EveryChunkNativePeriodicEvents.java | 16 ---------------- .../test/jfr/TestAllocationRequiringGCEvent.java | 2 +- .../oracle/svm/test/jfr/TestSystemGCEvent.java | 2 -- 4 files changed, 1 insertion(+), 20 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java index d429be4fc610..78b6151fa6e3 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrEvent.java @@ -63,7 +63,6 @@ public final class JfrEvent { public static final JfrEvent ObjectAllocationInNewTLAB = create("jdk.ObjectAllocationInNewTLAB", false); public static final JfrEvent GCHeapSummary = create("jdk.GCHeapSummary", false); public static final JfrEvent SystemGC = create("jdk.SystemGC", true); - public static final JfrEvent GCTLABConfiguration = create("jdk.GCTLABConfiguration", false); public static final JfrEvent AllocationRequiringGC = create("jdk.AllocationRequiringGC", false); private final long id; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java index d6f4e11d3f97..a25144e6b2fc 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/EveryChunkNativePeriodicEvents.java @@ -27,7 +27,6 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; -//import com.oracle.svm.core.genscavenge.HeapParameters; import org.graalvm.nativeimage.StackValue; import com.oracle.svm.core.Uninterruptible; @@ -51,7 +50,6 @@ public static void emit() { threadMXBean.getTotalStartedThreadCount(), threadMXBean.getPeakThreadCount()); emitPhysicalMemory(com.oracle.svm.core.heap.PhysicalMemory.size().rawValue(), 0); -// emitGCTLABConfiguration(); } @Uninterruptible(reason = "Accesses a JFR buffer.") @@ -83,18 +81,4 @@ private static void emitPhysicalMemory(long totalSize, long usedSize) { JfrNativeEventWriter.endSmallEvent(data); } } -// @Uninterruptible(reason = "Accesses a JFR buffer.") -// private static void emitGCTLABConfiguration() { -// if (JfrEvent.GCTLABConfiguration.shouldEmit()) { -// JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); -// JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); -// -// JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCTLABConfiguration); -// JfrNativeEventWriter.putLong(data, JfrTicks.elapsedTicks()); -// JfrNativeEventWriter.putLong(data, HeapParameters.getAlignedHeapChunkSize()); -// JfrNativeEventWriter.putLong(data, 0); -// JfrNativeEventWriter.putBoolean(data, true); -// JfrNativeEventWriter.endSmallEvent(data); -// } -// } } diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java index b797db889af4..33c10b9be240 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java @@ -47,7 +47,7 @@ public void test() throws Throwable { Recording recording = startRecording(events); final int alignedHeapChunkSize = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkSize()); - // 256MB is max eden size specified by getMaximumYoungGenerationSize() + // 256MB is the max possible eden size allocateByteArray(MAX_YOUNG_SIZE); allocateByteArray(alignedHeapChunkSize * 2); diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java index 1bc6299661f2..6606646668b4 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java @@ -40,9 +40,7 @@ public class TestSystemGCEvent extends JfrRecordingTest { public void test() throws Throwable { String[] events = new String[]{"jdk.SystemGC"}; Recording recording = startRecording(events); - System.gc(); - stopRecording(recording, TestSystemGCEvent::validateEvents); } From 471d43151e16648260931c50ef87b2a11c55f508 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 31 Aug 2023 16:56:42 +0200 Subject: [PATCH 3/8] Minor cleanups. --- substratevm/CHANGELOG.md | 4 +++ .../oracle/svm/core/genscavenge/GCImpl.java | 4 +-- .../genscavenge/ThreadLocalAllocation.java | 14 +++++----- ...C.java => AllocationRequiringGCEvent.java} | 6 +++-- .../core/jfr/events/JavaMonitorWaitEvent.java | 1 + .../ObjectAllocationInNewTLABEvent.java | 1 + .../svm/core/jfr/events/SystemGCEvent.java | 1 + .../jfr/TestAllocationRequiringGCEvent.java | 26 ++++++++++--------- .../svm/test/jfr/TestSystemGCEvent.java | 16 +++++++----- 9 files changed, 45 insertions(+), 28 deletions(-) rename substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/{AllocationRequiringGC.java => AllocationRequiringGCEvent.java} (98%) diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index d3eb9b4c42d3..52648508c19e 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -2,6 +2,10 @@ This changelog summarizes major changes to GraalVM Native Image. +## GraalVM for JDK 22 (Internal Version 24.0.0) +* (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics. +* (GR-48343) Red Hat added support for the JFR events AllocationRequiringGC and SystemGC. + ## GraalVM for JDK 21 (Internal Version 23.1.0) * (GR-35746) Lower the default aligned chunk size from 1 MB to 512 KB for the serial and epsilon GCs, reducing memory usage and image size in many cases. * (GR-45841) BellSoft added support for the JFR event ThreadCPULoad. diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index cdad9a036156..5eb1b99af4eb 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -78,7 +78,7 @@ import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.jfr.JfrGCWhen; import com.oracle.svm.core.jfr.JfrTicks; -import com.oracle.svm.core.jfr.events.AllocationRequiringGC; +import com.oracle.svm.core.jfr.events.AllocationRequiringGCEvent; import com.oracle.svm.core.jfr.events.SystemGCEvent; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.os.CommittedMemoryProvider; @@ -150,7 +150,7 @@ public void maybeCollectOnAllocation(UnsignedWord size) { UnsignedWord edenUsed = HeapImpl.getHeapImpl().getAccounting().getEdenUsedBytes(); outOfMemory = edenUsed.aboveThan(GCImpl.getPolicy().getMaximumHeapSize()); } else if (getPolicy().shouldCollectOnAllocation()) { - AllocationRequiringGC.emit(startTicks, getCollectionEpoch().rawValue(), size); + AllocationRequiringGCEvent.emit(startTicks, getCollectionEpoch().rawValue(), size); outOfMemory = collectWithoutAllocating(GenScavengeGCCause.OnAllocation, false); } if (outOfMemory) { diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java index b0aa5bfc7af2..21b2279e2989 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/ThreadLocalAllocation.java @@ -236,7 +236,7 @@ private static Object slowPathNewInstanceWithoutAllocating(DynamicHub hub) { GCImpl.getGCImpl().maybeCollectOnAllocation(size); AlignedHeader newTlab = HeapImpl.getChunkProvider().produceAlignedChunk(); - return allocateInstanceInNewTlab(hub, newTlab); + return allocateInstanceInNewTlab(hub, size, newTlab); } finally { ObjectAllocationInNewTLABEvent.emit(startTicks, hub, size, HeapParameters.getAlignedHeapChunkSize()); DeoptTester.enableDeoptTesting(); @@ -306,10 +306,12 @@ private static Object slowPathNewArrayLikeObject0(DynamicHub hub, int length, Un tlabSize = UnalignedHeapChunk.getChunkSizeForObject(size); return allocateLargeArrayLikeObjectInNewTlab(hub, length, size, newTlabChunk, needsZeroing, podReferenceMap); } - /* Small arrays go into the regular aligned chunk. */ - // We might have allocated in the caller and acquired a TLAB with enough space already - // (but we need to check in an uninterruptible method to be safe) + /* + * Small arrays go into the regular aligned chunk. We might have allocated in the caller + * and acquired a TLAB with enough space already (but we need to check in an + * uninterruptible method to be safe). + */ Object array = allocateSmallArrayLikeObjectInCurrentTlab(hub, length, size, podReferenceMap); if (array == null) { // We need a new chunk. AlignedHeader newTlabChunk = HeapImpl.getChunkProvider().produceAlignedChunk(); @@ -323,8 +325,8 @@ private static Object slowPathNewArrayLikeObject0(DynamicHub hub, int length, Un } @Uninterruptible(reason = "Holds uninitialized memory.") - private static Object allocateInstanceInNewTlab(DynamicHub hub, AlignedHeader newTlabChunk) { - UnsignedWord size = LayoutEncoding.getPureInstanceAllocationSize(hub.getLayoutEncoding()); + private static Object allocateInstanceInNewTlab(DynamicHub hub, UnsignedWord size, AlignedHeader newTlabChunk) { + assert size.equal(LayoutEncoding.getPureInstanceAllocationSize(hub.getLayoutEncoding())); Pointer memory = allocateRawMemoryInNewTlab(size, newTlabChunk); return FormatObjectNode.formatObject(memory, DynamicHub.toClass(hub), false, FillContent.WITH_ZEROES, true); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java similarity index 98% rename from substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java rename to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java index 32c9627e2336..a2d08b390ad3 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGC.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java @@ -26,6 +26,8 @@ package com.oracle.svm.core.jfr.events; +import org.graalvm.nativeimage.StackValue; + import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.jfr.HasJfrSupport; import com.oracle.svm.core.jfr.JfrEvent; @@ -33,9 +35,8 @@ import com.oracle.svm.core.jfr.JfrNativeEventWriterData; import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess; import com.oracle.svm.core.jfr.SubstrateJVM; -import org.graalvm.nativeimage.StackValue; -public class AllocationRequiringGC { +public class AllocationRequiringGCEvent { public static void emit(long startTicks, long gcId, org.graalvm.word.UnsignedWord size) { if (HasJfrSupport.get()) { emit0(startTicks, gcId, size); @@ -47,6 +48,7 @@ private static void emit0(long startTicks, long gcId, org.graalvm.word.UnsignedW if (JfrEvent.AllocationRequiringGC.shouldEmit()) { JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.AllocationRequiringGC); JfrNativeEventWriter.putLong(data, startTicks); JfrNativeEventWriter.putEventThread(data); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/JavaMonitorWaitEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/JavaMonitorWaitEvent.java index 00a66a16bd0d..b734bbf63a8e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/JavaMonitorWaitEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/JavaMonitorWaitEvent.java @@ -50,6 +50,7 @@ private static void emit0(long startTicks, Object obj, long notifier, long timeo if (JfrEvent.JavaMonitorWait.shouldEmit(duration)) { JfrNativeEventWriterData data = org.graalvm.nativeimage.StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.JavaMonitorWait); JfrNativeEventWriter.putLong(data, startTicks); JfrNativeEventWriter.putLong(data, duration); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/ObjectAllocationInNewTLABEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/ObjectAllocationInNewTLABEvent.java index 76226394d56a..dcccd614a7b4 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/ObjectAllocationInNewTLABEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/ObjectAllocationInNewTLABEvent.java @@ -50,6 +50,7 @@ private static void emit0(long startTicks, DynamicHub hub, UnsignedWord allocati if (JfrEvent.ObjectAllocationInNewTLAB.shouldEmit()) { JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.ObjectAllocationInNewTLAB); JfrNativeEventWriter.putLong(data, startTicks); JfrNativeEventWriter.putEventThread(data); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java index fa6446165029..8123b992f3ca 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/SystemGCEvent.java @@ -50,6 +50,7 @@ private static void emit0(long startTicks, boolean invokedConcurrent) { if (JfrEvent.SystemGC.shouldEmit(duration)) { JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.SystemGC); JfrNativeEventWriter.putLong(data, startTicks); JfrNativeEventWriter.putLong(data, duration); diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java index 33c10b9be240..d6474dea4169 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java @@ -26,30 +26,32 @@ package com.oracle.svm.test.jfr; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; + import com.oracle.svm.core.NeverInline; import com.oracle.svm.core.genscavenge.HeapParameters; +import com.oracle.svm.core.jfr.JfrEvent; import com.oracle.svm.core.util.UnsignedUtils; import jdk.jfr.Recording; import jdk.jfr.consumer.RecordedEvent; -import org.junit.Test; - -import java.util.List; - -import static org.junit.Assert.assertTrue; public class TestAllocationRequiringGCEvent extends JfrRecordingTest { - private static final int MAX_YOUNG_SIZE = 256 * 1024 * 1024; - @Test public void test() throws Throwable { - String[] events = new String[]{"jdk.AllocationRequiringGC"}; + String[] events = new String[]{JfrEvent.AllocationRequiringGC.getName()}; Recording recording = startRecording(events); - final int alignedHeapChunkSize = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkSize()); - // 256MB is the max possible eden size - allocateByteArray(MAX_YOUNG_SIZE); - allocateByteArray(alignedHeapChunkSize * 2); + int alignedHeapChunkSize = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkSize()); + + /* Allocate 256 arrays with 1 MB each. */ + for (int i = 0; i < 256; i++) { + allocateByteArray(1024 * 1024); + } stopRecording(recording, TestAllocationRequiringGCEvent::validateEvents); } diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java index 6606646668b4..ff3a6b074377 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java @@ -26,25 +26,29 @@ package com.oracle.svm.test.jfr; -import jdk.jfr.Recording; -import jdk.jfr.consumer.RecordedEvent; +import static org.junit.Assert.assertTrue; + +import java.util.List; import org.junit.Test; -import java.util.List; +import com.oracle.svm.core.jfr.JfrEvent; -import static org.junit.Assert.assertEquals; +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; public class TestSystemGCEvent extends JfrRecordingTest { @Test public void test() throws Throwable { - String[] events = new String[]{"jdk.SystemGC"}; + String[] events = new String[]{JfrEvent.SystemGC.getName()}; Recording recording = startRecording(events); + System.gc(); + stopRecording(recording, TestSystemGCEvent::validateEvents); } private static void validateEvents(List events) { - assertEquals(1, events.size()); + assertTrue(events.size() >= 1); } } From 7ba44a75f9fdac7474cac30b65cf2d4016376d38 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 31 Aug 2023 18:03:30 +0200 Subject: [PATCH 4/8] Simplified collection hints. --- .../genscavenge/AbstractCollectionPolicy.java | 6 ++--- .../genscavenge/BasicCollectionPolicies.java | 5 ++-- .../core/genscavenge/CollectionPolicy.java | 2 +- .../oracle/svm/core/genscavenge/GCImpl.java | 11 +++------ .../oracle/svm/core/genscavenge/HeapImpl.java | 9 +++++++- .../genscavenge/LibGraalCollectionPolicy.java | 23 ++++++++----------- .../src/com/oracle/svm/core/heap/GC.java | 10 ++++---- .../hotspot/libgraal/LibGraalFeature.java | 9 ++++---- 8 files changed, 38 insertions(+), 37 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractCollectionPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractCollectionPolicy.java index 1f8e4b4308fd..09d7bff27cc1 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractCollectionPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AbstractCollectionPolicy.java @@ -35,7 +35,6 @@ import com.oracle.svm.core.SubstrateGCOptions; import com.oracle.svm.core.Uninterruptible; -import com.oracle.svm.core.heap.GCCause; import com.oracle.svm.core.heap.PhysicalMemory; import com.oracle.svm.core.heap.ReferenceAccess; import com.oracle.svm.core.jdk.UninterruptibleUtils; @@ -96,8 +95,9 @@ public boolean shouldCollectOnAllocation() { } @Override - public boolean shouldCollectOnRequest(GCCause cause, boolean fullGC) { - return cause == GCCause.JavaLangSystemGC && !SubstrateGCOptions.DisableExplicitGC.getValue(); + public boolean shouldCollectOnHint(boolean fullGC) { + /* Collection hints are not supported. */ + return false; } @Fold diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/BasicCollectionPolicies.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/BasicCollectionPolicies.java index 150aa514aac1..286cc032ecc5 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/BasicCollectionPolicies.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/BasicCollectionPolicies.java @@ -63,8 +63,9 @@ public boolean shouldCollectOnAllocation() { } @Override - public boolean shouldCollectOnRequest(GCCause cause, boolean fullGC) { - return cause == GCCause.JavaLangSystemGC && !SubstrateGCOptions.DisableExplicitGC.getValue(); + public boolean shouldCollectOnHint(boolean fullGC) { + /* Collection hints are not supported. */ + return false; } @Override diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java index 2dd29291d6b1..968fbc475f5a 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java @@ -126,7 +126,7 @@ static boolean shouldCollectYoungGenSeparately(boolean defaultValue) { * {@link org.graalvm.compiler.serviceprovider.GraalServices#notifyLowMemoryPoint(boolean)}) * should be performed. */ - boolean shouldCollectOnRequest(GCCause cause, boolean fullGC); + boolean shouldCollectOnHint(boolean fullGC); /** * At a safepoint, decides whether to do a complete collection (returning {@code true}) or an diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index 5eb1b99af4eb..6ff6d8e1b6d4 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -78,8 +78,6 @@ import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.jfr.JfrGCWhen; import com.oracle.svm.core.jfr.JfrTicks; -import com.oracle.svm.core.jfr.events.AllocationRequiringGCEvent; -import com.oracle.svm.core.jfr.events.SystemGCEvent; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.os.CommittedMemoryProvider; import com.oracle.svm.core.snippets.ImplicitExceptions; @@ -150,7 +148,6 @@ public void maybeCollectOnAllocation(UnsignedWord size) { UnsignedWord edenUsed = HeapImpl.getHeapImpl().getAccounting().getEdenUsedBytes(); outOfMemory = edenUsed.aboveThan(GCImpl.getPolicy().getMaximumHeapSize()); } else if (getPolicy().shouldCollectOnAllocation()) { - AllocationRequiringGCEvent.emit(startTicks, getCollectionEpoch().rawValue(), size); outOfMemory = collectWithoutAllocating(GenScavengeGCCause.OnAllocation, false); } if (outOfMemory) { @@ -159,11 +156,9 @@ public void maybeCollectOnAllocation(UnsignedWord size) { } @Override - public void maybeCauseUserRequestedCollection(GCCause cause, boolean fullGC) { - if (policy.shouldCollectOnRequest(cause, fullGC)) { - long startTicks = JfrTicks.elapsedTicks(); - collect(cause, fullGC); - SystemGCEvent.emit(startTicks, false); + public void collectionHint(boolean fullGC) { + if (policy.shouldCollectOnHint(fullGC)) { + collect(GCCause.HintedGC, fullGC); } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java index 4f3b501a0dd1..6ead7372c576 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/HeapImpl.java @@ -47,6 +47,7 @@ import com.oracle.svm.core.SubstrateDiagnostics.DiagnosticThunk; import com.oracle.svm.core.SubstrateDiagnostics.DiagnosticThunkRegistry; import com.oracle.svm.core.SubstrateDiagnostics.ErrorContext; +import com.oracle.svm.core.SubstrateGCOptions; import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.Uninterruptible; @@ -72,6 +73,8 @@ import com.oracle.svm.core.heap.RuntimeCodeInfoGCSupport; import com.oracle.svm.core.hub.DynamicHub; import com.oracle.svm.core.jdk.UninterruptibleUtils.AtomicReference; +import com.oracle.svm.core.jfr.JfrTicks; +import com.oracle.svm.core.jfr.events.SystemGCEvent; import com.oracle.svm.core.locks.VMCondition; import com.oracle.svm.core.locks.VMMutex; import com.oracle.svm.core.log.Log; @@ -934,6 +937,10 @@ private long maxMemory() { @Substitute private void gc() { - GCImpl.getGCImpl().maybeCauseUserRequestedCollection(GCCause.JavaLangSystemGC, true); + if (!SubstrateGCOptions.DisableExplicitGC.getValue()) { + long startTicks = JfrTicks.elapsedTicks(); + GCImpl.getGCImpl().collectCompletely(GCCause.JavaLangSystemGC); + SystemGCEvent.emit(startTicks, false); + } } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java index ca364957b77e..73e01d2ccdd8 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java @@ -73,20 +73,17 @@ public static final class Options { * size is lower but the hinted GC is more often. */ @Override - public boolean shouldCollectOnRequest(GCCause cause, boolean fullGC) { - if (cause == GCCause.HintedGC) { - guaranteeSizeParametersInitialized(); - UnsignedWord edenUsedBytes = HeapImpl.getHeapImpl().getAccounting().getEdenUsedBytes(); - if (fullGC) { - // For full GC request, we slightly lower the threshold to increase their - // probability to be performed, as they are supposed to be issued at the lowest - // memory usage point. - edenUsedBytes = edenUsedBytes.add(FULL_GC_BONUS); - } - return edenUsedBytes.aboveOrEqual(WordFactory.unsigned(Options.ExpectedEdenSize.getValue())) || - (UnsignedUtils.toDouble(edenUsedBytes) / UnsignedUtils.toDouble(edenSize) >= Options.UsedEdenProportionThreshold.getValue()); + public boolean shouldCollectOnHint(boolean fullGC) { + guaranteeSizeParametersInitialized(); + UnsignedWord edenUsedBytes = HeapImpl.getHeapImpl().getAccounting().getEdenUsedBytes(); + if (fullGC) { + // For full GC request, we slightly lower the threshold to increase their + // probability to be performed, as they are supposed to be issued at the lowest + // memory usage point. + edenUsedBytes = edenUsedBytes.add(FULL_GC_BONUS); } - return super.shouldCollectOnRequest(cause, fullGC); + return edenUsedBytes.aboveOrEqual(WordFactory.unsigned(Options.ExpectedEdenSize.getValue())) || + (UnsignedUtils.toDouble(edenUsedBytes) / UnsignedUtils.toDouble(edenSize) >= Options.UsedEdenProportionThreshold.getValue()); } @Override diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java index 122c8f07e3e1..3d76bc8738d5 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java @@ -31,13 +31,15 @@ public interface GC { /** Cause a full collection. */ void collectCompletely(GCCause cause); + /** + * Notify the GC that it might be a good time to do a GC. The final decision is up to the GC and + * its policy. + */ + void collectionHint(boolean fullGC); + /** Human-readable name. */ String getName(); /** Human-readable default heap size. */ String getDefaultMaxHeapSize(); - - /** Issue an optional GC request. */ - default void maybeCauseUserRequestedCollection(@SuppressWarnings("unused") GCCause cause, @SuppressWarnings("unused") boolean fullGC) { - } } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index db365b617ee2..aca3886b3916 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -52,9 +52,6 @@ import java.util.function.BooleanSupplier; import java.util.stream.Collectors; -import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.VMInspectionOptions; -import com.oracle.svm.core.heap.dump.HeapDumping; import org.graalvm.collections.EconomicMap; import org.graalvm.compiler.code.DisassemblerProvider; import org.graalvm.compiler.core.GraalServiceThread; @@ -117,7 +114,9 @@ import com.oracle.graal.pointsto.meta.InvokeInfo; import com.oracle.svm.core.OS; import com.oracle.svm.core.RuntimeAssertionsSupport; +import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; +import com.oracle.svm.core.VMInspectionOptions; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; @@ -127,8 +126,8 @@ import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.graal.meta.RuntimeConfiguration; import com.oracle.svm.core.graal.snippets.NodeLoweringProvider; -import com.oracle.svm.core.heap.GCCause; import com.oracle.svm.core.heap.Heap; +import com.oracle.svm.core.heap.dump.HeapDumping; import com.oracle.svm.core.log.FunctionPointerLogHandler; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.option.RuntimeOptionKey; @@ -743,7 +742,7 @@ final class Target_org_graalvm_compiler_serviceprovider_GraalServices { @Substitute private static void notifyLowMemoryPoint(boolean fullGC) { - Heap.getHeap().getGC().maybeCauseUserRequestedCollection(GCCause.HintedGC, fullGC); + Heap.getHeap().getGC().collectionHint(fullGC); } } From f1bacdd9b7e2a1a8046ee124d41f0097d08c7a2a Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 31 Aug 2023 18:14:33 +0200 Subject: [PATCH 5/8] Avoid that an incremental collection can prevent a full GC. --- .../com/oracle/svm/core/genscavenge/GCImpl.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index 6ff6d8e1b6d4..ce264bcb720b 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -181,6 +181,7 @@ boolean collectWithoutAllocating(GCCause cause, boolean forceFullGC) { UnmanagedMemoryUtil.fill((Pointer) data, WordFactory.unsigned(size), (byte) 0); data.setCauseId(cause.getId()); data.setRequestingEpoch(getCollectionEpoch()); + data.setCompleteCollectionCount(GCImpl.getGCImpl().getAccounting().getCompleteCollectionCount()); data.setRequestingNanoTime(System.nanoTime()); data.setForceFullGC(forceFullGC); enqueueCollectOperation(data); @@ -1313,7 +1314,12 @@ private static void collect(CollectionVMOperationData data) { @Override protected boolean hasWork(NativeVMOperationData data) { CollectionVMOperationData d = (CollectionVMOperationData) data; - return HeapImpl.getGCImpl().getCollectionEpoch().equal(d.getRequestingEpoch()); + if (d.getForceFullGC()) { + /* Skip if another full GC happened in the meanwhile. */ + return GCImpl.getGCImpl().getAccounting().getCompleteCollectionCount() == d.getCompleteCollectionCount(); + } + /* Skip if any other GC happened in the meanwhile. */ + return GCImpl.getGCImpl().getCollectionEpoch().equal(d.getRequestingEpoch()); } } @@ -1343,6 +1349,12 @@ private interface CollectionVMOperationData extends NativeVMOperationData { @RawField void setForceFullGC(boolean value); + @RawField + long getCompleteCollectionCount(); + + @RawField + void setCompleteCollectionCount(long value); + @RawField boolean getOutOfMemory(); From 0c68b903cafed094504e886d8322889d4ba87177 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 31 Aug 2023 18:53:31 +0200 Subject: [PATCH 6/8] Fixes, cleanups, and documentation updates. --- .../svm/core/genscavenge/CollectionPolicy.java | 5 ++--- .../oracle/svm/core/genscavenge/GCAccounting.java | 1 + .../src/com/oracle/svm/core/genscavenge/GCImpl.java | 12 +++++++----- .../core/genscavenge/LibGraalCollectionPolicy.java | 7 ++++--- .../src/com/oracle/svm/core/heap/GC.java | 4 ++-- .../core/jfr/events/AllocationRequiringGCEvent.java | 12 +++++++----- .../svm/graal/hotspot/libgraal/LibGraalFeature.java | 3 --- .../svm/test/jfr/TestAllocationRequiringGCEvent.java | 4 ---- 8 files changed, 23 insertions(+), 25 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java index 968fbc475f5a..8b235331c44e 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/CollectionPolicy.java @@ -122,9 +122,8 @@ static boolean shouldCollectYoungGenSeparately(boolean defaultValue) { boolean shouldCollectOnAllocation(); /** - * Return true if a user-requested GC (e.g., call to {@link System#gc()} or - * {@link org.graalvm.compiler.serviceprovider.GraalServices#notifyLowMemoryPoint(boolean)}) - * should be performed. + * Called when an application provides a hint to the GC that it might be a good time to do a + * collection. Returns true if the GC decides to do a collection. */ boolean shouldCollectOnHint(boolean fullGC); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCAccounting.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCAccounting.java index 0a861933dd07..4d83d99b2547 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCAccounting.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCAccounting.java @@ -78,6 +78,7 @@ public long getIncrementalCollectionTotalNanos() { return incrementalCollectionTotalNanos; } + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public long getCompleteCollectionCount() { return completeCollectionCount; } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java index f329356010e0..a5caf759d016 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java @@ -81,6 +81,7 @@ import com.oracle.svm.core.jdk.RuntimeSupport; import com.oracle.svm.core.jfr.JfrGCWhen; import com.oracle.svm.core.jfr.JfrTicks; +import com.oracle.svm.core.jfr.events.AllocationRequiringGCEvent; import com.oracle.svm.core.log.Log; import com.oracle.svm.core.os.CommittedMemoryProvider; import com.oracle.svm.core.snippets.ImplicitExceptions; @@ -144,13 +145,13 @@ public void collect(GCCause cause) { collect(cause, false); } - public void maybeCollectOnAllocation(UnsignedWord size) { + public void maybeCollectOnAllocation(UnsignedWord allocationSize) { boolean outOfMemory = false; - long startTicks = JfrTicks.elapsedTicks(); if (hasNeverCollectPolicy()) { UnsignedWord edenUsed = HeapImpl.getAccounting().getEdenUsedBytes(); outOfMemory = edenUsed.aboveThan(GCImpl.getPolicy().getMaximumHeapSize()); } else if (getPolicy().shouldCollectOnAllocation()) { + AllocationRequiringGCEvent.emit(getCollectionEpoch(), allocationSize); outOfMemory = collectWithoutAllocating(GenScavengeGCCause.OnAllocation, false); } if (outOfMemory) { @@ -184,7 +185,7 @@ boolean collectWithoutAllocating(GCCause cause, boolean forceFullGC) { UnmanagedMemoryUtil.fill((Pointer) data, WordFactory.unsigned(size), (byte) 0); data.setCauseId(cause.getId()); data.setRequestingEpoch(getCollectionEpoch()); - data.setCompleteCollectionCount(GCImpl.getGCImpl().getAccounting().getCompleteCollectionCount()); + data.setCompleteCollectionCount(GCImpl.getAccounting().getCompleteCollectionCount()); data.setRequestingNanoTime(System.nanoTime()); data.setForceFullGC(forceFullGC); enqueueCollectOperation(data); @@ -199,7 +200,8 @@ private void enqueueCollectOperation(CollectionVMOperationData data) { /** The body of the VMOperation to do the collection. */ private void collectOperation(CollectionVMOperationData data) { assert VMOperation.isGCInProgress(); - assert getCollectionEpoch().equal(data.getRequestingEpoch()); + assert getCollectionEpoch().equal(data.getRequestingEpoch()) || + data.getForceFullGC() && GCImpl.getAccounting().getCompleteCollectionCount() == data.getCompleteCollectionCount() : "unnecessary GC?"; timers.mutator.closeAt(data.getRequestingNanoTime()); timers.resetAllExceptMutator(); @@ -1209,7 +1211,7 @@ protected boolean hasWork(NativeVMOperationData data) { CollectionVMOperationData d = (CollectionVMOperationData) data; if (d.getForceFullGC()) { /* Skip if another full GC happened in the meanwhile. */ - return GCImpl.getGCImpl().getAccounting().getCompleteCollectionCount() == d.getCompleteCollectionCount(); + return GCImpl.getAccounting().getCompleteCollectionCount() == d.getCompleteCollectionCount(); } /* Skip if any other GC happened in the meanwhile. */ return GCImpl.getGCImpl().getCollectionEpoch().equal(d.getRequestingEpoch()); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java index f2b6fc7ff517..7e4aed6af194 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/LibGraalCollectionPolicy.java @@ -77,9 +77,10 @@ public boolean shouldCollectOnHint(boolean fullGC) { guaranteeSizeParametersInitialized(); UnsignedWord edenUsedBytes = HeapImpl.getAccounting().getEdenUsedBytes(); if (fullGC) { - // For full GC request, we slightly lower the threshold to increase their - // probability to be performed, as they are supposed to be issued at the lowest - // memory usage point. + /* + * For full GC request, we slightly lower the threshold to increase their probability to + * be performed, as they are supposed to be issued at the lowest memory usage point. + */ edenUsedBytes = edenUsedBytes.add(FULL_GC_BONUS); } return edenUsedBytes.aboveOrEqual(WordFactory.unsigned(Options.ExpectedEdenSize.getValue())) || diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java index 3d76bc8738d5..f2eed9860810 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GC.java @@ -32,8 +32,8 @@ public interface GC { void collectCompletely(GCCause cause); /** - * Notify the GC that it might be a good time to do a GC. The final decision is up to the GC and - * its policy. + * Notify the GC that it might be a good time to do a collection. The final decision is up to + * the GC and its policy. */ void collectionHint(boolean fullGC); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java index a2d08b390ad3..1357b40ae495 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/AllocationRequiringGCEvent.java @@ -27,6 +27,7 @@ package com.oracle.svm.core.jfr.events; import org.graalvm.nativeimage.StackValue; +import org.graalvm.word.UnsignedWord; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.jfr.HasJfrSupport; @@ -34,26 +35,27 @@ import com.oracle.svm.core.jfr.JfrNativeEventWriter; import com.oracle.svm.core.jfr.JfrNativeEventWriterData; import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess; +import com.oracle.svm.core.jfr.JfrTicks; import com.oracle.svm.core.jfr.SubstrateJVM; public class AllocationRequiringGCEvent { - public static void emit(long startTicks, long gcId, org.graalvm.word.UnsignedWord size) { + public static void emit(UnsignedWord gcId, UnsignedWord size) { if (HasJfrSupport.get()) { - emit0(startTicks, gcId, size); + emit0(gcId, size); } } @Uninterruptible(reason = "Accesses a JFR buffer.") - private static void emit0(long startTicks, long gcId, org.graalvm.word.UnsignedWord size) { + private static void emit0(UnsignedWord gcId, UnsignedWord size) { if (JfrEvent.AllocationRequiringGC.shouldEmit()) { JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.AllocationRequiringGC); - JfrNativeEventWriter.putLong(data, startTicks); + JfrNativeEventWriter.putLong(data, JfrTicks.elapsedTicks()); JfrNativeEventWriter.putEventThread(data); JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.AllocationRequiringGC, 0)); - JfrNativeEventWriter.putLong(data, gcId); + JfrNativeEventWriter.putLong(data, gcId.rawValue()); JfrNativeEventWriter.putLong(data, size.rawValue()); JfrNativeEventWriter.endSmallEvent(data); } diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java index 3f8771d91914..0ca4dea64bb0 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java @@ -114,9 +114,7 @@ import com.oracle.graal.pointsto.meta.InvokeInfo; import com.oracle.svm.core.OS; import com.oracle.svm.core.RuntimeAssertionsSupport; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.SubstrateUtil; -import com.oracle.svm.core.VMInspectionOptions; import com.oracle.svm.core.annotate.Delete; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; @@ -127,7 +125,6 @@ import com.oracle.svm.core.graal.meta.RuntimeConfiguration; import com.oracle.svm.core.graal.snippets.NodeLoweringProvider; import com.oracle.svm.core.heap.Heap; -import com.oracle.svm.core.heap.dump.HeapDumping; import com.oracle.svm.core.log.FunctionPointerLogHandler; import com.oracle.svm.core.option.HostedOptionKey; import com.oracle.svm.core.option.RuntimeOptionKey; diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java index d6474dea4169..a3f675115d8d 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestAllocationRequiringGCEvent.java @@ -33,9 +33,7 @@ import org.junit.Test; import com.oracle.svm.core.NeverInline; -import com.oracle.svm.core.genscavenge.HeapParameters; import com.oracle.svm.core.jfr.JfrEvent; -import com.oracle.svm.core.util.UnsignedUtils; import jdk.jfr.Recording; import jdk.jfr.consumer.RecordedEvent; @@ -46,8 +44,6 @@ public void test() throws Throwable { String[] events = new String[]{JfrEvent.AllocationRequiringGC.getName()}; Recording recording = startRecording(events); - int alignedHeapChunkSize = UnsignedUtils.safeToInt(HeapParameters.getAlignedHeapChunkSize()); - /* Allocate 256 arrays with 1 MB each. */ for (int i = 0; i < 256; i++) { allocateByteArray(1024 * 1024); From a123ce2c21366893f820c0c5181abe493a590eee Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Wed, 20 Sep 2023 14:09:43 +0200 Subject: [PATCH 7/8] Improve TestSystemGCEvent. --- .../src/com/oracle/svm/test/jfr/TestSystemGCEvent.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java index ff3a6b074377..655607f23bf7 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestSystemGCEvent.java @@ -26,6 +26,8 @@ package com.oracle.svm.test.jfr; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; @@ -49,6 +51,12 @@ public void test() throws Throwable { } private static void validateEvents(List events) { - assertTrue(events.size() >= 1); + for (RecordedEvent event : events) { + assertNotNull(event.getStackTrace()); + assertNotNull(event.getThread()); + assertNotNull(event.getStartTime()); + assertTrue(event.getStartTime().toEpochMilli() <= System.currentTimeMillis()); + assertFalse(event.getBoolean("invokedConcurrent")); + } } } From a14188702617ca8bc4cbcbaa20e01d2eeeb7edae Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Thu, 21 Sep 2023 14:16:47 +0200 Subject: [PATCH 8/8] Minor fix after updating to master. --- .../hotspot/libgraal/truffle/TruffleToLibGraalEntryPoints.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/truffle/TruffleToLibGraalEntryPoints.java b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/truffle/TruffleToLibGraalEntryPoints.java index 01eb72ae783b..17b822f577ad 100644 --- a/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/truffle/TruffleToLibGraalEntryPoints.java +++ b/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/truffle/TruffleToLibGraalEntryPoints.java @@ -76,7 +76,6 @@ import org.graalvm.word.PointerBase; import org.graalvm.word.WordFactory; -import com.oracle.svm.core.heap.GCCause; import com.oracle.svm.core.heap.Heap; import com.oracle.svm.graal.hotspot.libgraal.LibGraal; import com.oracle.svm.graal.hotspot.libgraal.LibGraalUtil; @@ -243,7 +242,7 @@ public static void doCompile(JNIEnv env, compiler.doCompile(task, compilable, listener); } finally { Heap.getHeap().doReferenceHandling(); - Heap.getHeap().getGC().maybeCauseUserRequestedCollection(GCCause.HintedGC, true); + Heap.getHeap().getGC().collectionHint(true); } } catch (Throwable t) { JNIExceptionWrapper.throwInHotSpot(env, t);