From 4b45892dd049694edf59359fc360306d1aa4bebd Mon Sep 17 00:00:00 2001 From: kazukg Date: Thu, 20 Apr 2023 10:26:55 +0900 Subject: [PATCH 1/9] Add GCHeapSummaryEvent --- .../oracle/svm/core/genscavenge/GCImpl.java | 4 + .../genscavenge/JfrGCHeapSummaryEvent.java | 55 +++++++ .../JfrGCHeapSummaryEventSupport.java | 138 ++++++++++++++++++ .../src/com/oracle/svm/core/jfr/JfrEvent.java | 1 + .../com/oracle/svm/core/jfr/JfrFeature.java | 2 + .../com/oracle/svm/core/jfr/JfrGCWhen.java | 51 +++++++ .../svm/core/jfr/JfrGCWhenSerializer.java | 45 ++++++ .../com/oracle/svm/core/jfr/JfrGCWhens.java | 62 ++++++++ .../src/com/oracle/svm/core/jfr/JfrType.java | 2 + .../svm/test/jfr/TestGCHeapSummaryEvent.java | 56 +++++++ .../svm/test/jfr/utils/JfrFileParser.java | 3 + .../poolparsers/GCWhenConstantPoolParser.java | 50 +++++++ 12 files changed, 469 insertions(+) create mode 100644 substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java create mode 100644 substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java create mode 100755 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java create mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java create mode 100644 substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java create mode 100644 substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.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 de97ce2bc8ef..b5ace128151e 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 @@ -93,6 +93,8 @@ import com.oracle.svm.core.threadlocal.VMThreadLocalMTSupport; import com.oracle.svm.core.util.TimeUtils; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.core.genscavenge.JfrGCHeapSummaryEvent; +import com.oracle.svm.core.genscavenge.JfrGCHeapSummaryEventSupport; /** * Garbage collector (incremental or complete) for {@link HeapImpl}. @@ -208,7 +210,9 @@ private void collectOperation(CollectionVMOperationData data) { GCCause cause = GCCause.fromId(data.getCauseId()); printGCBefore(cause.getName()); + JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventBeforeGC(getCollectionEpoch(), JfrTicks.elapsedTicks(),getChunkBytes().rawValue()); boolean outOfMemory = collectImpl(cause, data.getRequestingNanoTime(), data.getForceFullGC()); + JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventAfterGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getChunkBytes().rawValue()); printGCAfter(cause.getName()); finishCollection(); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java new file mode 100644 index 000000000000..b948c1479e0d --- /dev/null +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022, 2022, 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 com.oracle.svm.core.genscavenge; + +import org.graalvm.compiler.api.replacements.Fold; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.word.UnsignedWord; + + +class JfrGCHeapSummaryEvent { + + public static void emitJfrGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch,long start,long heapUsed) { + if (hasJfrSupport() ) { + jfrSupport().emitGCHeapSummaryEventBeforeGC(gcEpoch, start,heapUsed); + } + } + + public static void emitJfrGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { + if (hasJfrSupport()) { + jfrSupport().emitGCHeapSummaryEventAfterGC(gcEpoch, start,heapUsed); + } + } + + @Fold + static boolean hasJfrSupport() { + return ImageSingletons.contains(JfrGCHeapSummaryEventSupport.class); + } + + @Fold + static JfrGCHeapSummaryEventSupport jfrSupport() { + return ImageSingletons.lookup(JfrGCHeapSummaryEventSupport.class); + } +} diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java new file mode 100644 index 000000000000..342c3d9d4d2f --- /dev/null +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2022, 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.genscavenge; + +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.StackValue; +import org.graalvm.word.UnsignedWord; + +import com.oracle.svm.core.SubstrateOptions; +import com.oracle.svm.core.Uninterruptible; +import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.feature.InternalFeature; +import com.oracle.svm.core.heap.GCCause; +import com.oracle.svm.core.jfr.HasJfrSupport; +import com.oracle.svm.core.jfr.JfrEvent; +import com.oracle.svm.core.jfr.JfrGCWhen; +import com.oracle.svm.core.jfr.JfrGCWhens; +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; +import com.oracle.svm.core.util.VMError; +import com.oracle.svm.core.jfr.JfrType; + +class JfrGCHeapSummaryEventSupport { + + private final JfrGCWhen before; + private final JfrGCWhen after; + + public JfrGCHeapSummaryEventSupport(JfrGCWhen before, JfrGCWhen after){ + this.before = before; + this.after = after; + } + + + @Uninterruptible(reason = "Accesses a JFR buffer.") + public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long heapUsed) { + + if (JfrEvent.GCHeapSummary.shouldEmit()) { + + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); + JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); + + JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; + + JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int gcId; + JfrNativeEventWriter.putLong(data, before.getId()); // @Label("When") String when; + + // VirtualSpace + JfrNativeEventWriter.putLong(data, 0L); // start + JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong + + JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") @Label("Heap Used") @Description("Bytes allocated by objects in the heap") long heapUsed; + + JfrNativeEventWriter.endSmallEvent(data); + } + + } + + @Uninterruptible(reason = "Accesses a JFR buffer.") + public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { + + if (JfrEvent.GCHeapSummary.shouldEmit()) { + + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); + JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); + + JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; + + JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int gcId; + JfrNativeEventWriter.putLong(data, after.getId()); // @Label("When") String when; + + // VirtualSpace + JfrNativeEventWriter.putLong(data, 0L); // start + JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong + + JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") @Label("Heap Used") @Description("Bytes allocated by objects in the heap") long heapUsed; + + JfrNativeEventWriter.endSmallEvent(data); + } + + } +} + + +@AutomaticallyRegisteredFeature +class JfrGCHeapSummaryEventFeature implements InternalFeature { + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + if (HasJfrSupport.get()) { + + //ImageSingletons.add(JfrGCWhens.class, new JfrGCWhens()); + + JfrGCWhen before = JfrGCWhens.singleton().addGCWhen("Before GC"); + + JfrGCWhen after = JfrGCWhens.singleton().addGCWhen("After GC"); + + ImageSingletons.add(JfrGCHeapSummaryEventSupport.class, new JfrGCHeapSummaryEventSupport(before, after)); + + } + } + +} 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 87f055bdd617..0f2201020ad8 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 @@ -60,6 +60,7 @@ public final class JfrEvent { public static final JfrEvent JavaMonitorWait = create("jdk.JavaMonitorWait"); public static final JfrEvent JavaMonitorInflate = create("jdk.JavaMonitorInflate"); public static final JfrEvent ObjectAllocationInNewTLAB = create("jdk.ObjectAllocationInNewTLAB"); + public static final JfrEvent GCHeapSummary = create("jdk.GCHeapSummary"); private final long id; private final String name; diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java index 17bf45e6a47f..82540ef98b47 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java @@ -166,6 +166,7 @@ public void afterRegistration(AfterRegistrationAccess access) { ImageSingletons.add(JfrTraceIdEpoch.class, new JfrTraceIdEpoch()); ImageSingletons.add(JfrGCNames.class, new JfrGCNames()); ImageSingletons.add(SamplerStackWalkVisitor.class, new SamplerStackWalkVisitor()); + ImageSingletons.add(JfrGCWhens.class, new JfrGCWhens()); JfrSerializerSupport.get().register(new JfrFrameTypeSerializer()); JfrSerializerSupport.get().register(new JfrThreadStateSerializer()); @@ -173,6 +174,7 @@ public void afterRegistration(AfterRegistrationAccess access) { JfrSerializerSupport.get().register(new JfrGCCauseSerializer()); JfrSerializerSupport.get().register(new JfrGCNameSerializer()); JfrSerializerSupport.get().register(new JfrVMOperationNameSerializer()); + JfrSerializerSupport.get().register(new JfrGCWhenSerializer()); ThreadListenerSupport.get().register(SubstrateJVM.getThreadLocal()); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java new file mode 100644 index 000000000000..659377f05a37 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2022, 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; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +import com.oracle.svm.core.Uninterruptible; + +public class JfrGCWhen { + private final int id; + private final String when; + + @Platforms(Platform.HOSTED_ONLY.class) + protected JfrGCWhen(int id, String when) { + this.id = id; + this.when = when; + } + + public String getWhen() { + return when; + } + + @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) + public int getId() { + return id; + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java new file mode 100755 index 000000000000..d74c98c6b639 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2023, 2023, 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 com.oracle.svm.core.jfr; + +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +public class JfrGCWhenSerializer implements JfrSerializer { + @Platforms(Platform.HOSTED_ONLY.class) + public JfrGCWhenSerializer() { + } + + @Override + public void write(JfrChunkWriter writer) { + JfrGCWhen[] gcWhens = JfrGCWhens.singleton().getWhens(); + writer.writeCompressedLong(JfrType.GCWhen.getId()); + writer.writeCompressedLong(gcWhens.length); + for (JfrGCWhen when : gcWhens) { + writer.writeCompressedLong(when.getId()); + writer.writeString(when.getWhen()); + } + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java new file mode 100644 index 000000000000..776596d5c87f --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2022, 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; + +import java.util.Arrays; + +import org.graalvm.compiler.api.replacements.Fold; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.Platform; +import org.graalvm.nativeimage.Platforms; + +public class JfrGCWhens { + private JfrGCWhen[] whens; + + @Platforms(Platform.HOSTED_ONLY.class) + public JfrGCWhens() { + whens = new JfrGCWhen[0]; + } + + @Fold + public static JfrGCWhens singleton() { + return ImageSingletons.lookup(JfrGCWhens.class); + } + + @Platforms(Platform.HOSTED_ONLY.class) + public synchronized JfrGCWhen addGCWhen(String when) { + int id = whens.length; + JfrGCWhen result = new JfrGCWhen(id, when); + + JfrGCWhen[] newArr = Arrays.copyOf(whens, id + 1); + newArr[id] = result; + whens = newArr; + return result; + } + + public JfrGCWhen[] getWhens() { + return whens; + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java index e6bd8df17d8c..ae077a48b5f0 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java @@ -44,6 +44,8 @@ public enum JfrType { FrameType("jdk.types.FrameType"), GCCause("jdk.types.GCCause"), GCName("jdk.types.GCName"), + GCWhen("jdk.types.GCWhen"), + VirtualSpace("jdk.types.VirtualSpace"), VMOperation("jdk.types.VMOperationType"), MonitorInflationCause("jdk.types.InflateCause"); diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java new file mode 100644 index 000000000000..736682c79c85 --- /dev/null +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2022, 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 static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.Test; + +import com.oracle.svm.core.jfr.JfrEvent; + +import jdk.jfr.Recording; +import jdk.jfr.consumer.RecordedEvent; + + +public class TestGCHeapSummaryEvent extends JfrRecordingTest { + + @Test + public void test() throws Throwable { + String[] events = new String[]{JfrEvent.GCHeapSummary.getName()}; + Recording recording = startRecording(events); + + System.gc(); + + stopRecording(recording, TestGCHeapSummaryEvent::validateEvents); + } + + private static void validateEvents(List events) { + assertTrue(events.size() > 0); + } +} \ No newline at end of file diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/JfrFileParser.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/JfrFileParser.java index 01d486221ded..062b78ed08f1 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/JfrFileParser.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/JfrFileParser.java @@ -60,6 +60,8 @@ import com.oracle.svm.test.jfr.utils.poolparsers.ThreadGroupConstantPoolParser; import com.oracle.svm.test.jfr.utils.poolparsers.ThreadStateConstantPoolParser; import com.oracle.svm.test.jfr.utils.poolparsers.VMOperationConstantPoolParser; +import com.oracle.svm.test.jfr.utils.poolparsers.GCWhenConstantPoolParser; + public class JfrFileParser { private final Path path; @@ -88,6 +90,7 @@ public JfrFileParser(Path path) { addParser(JfrType.GCCause, new GCCauseConstantPoolParser(this)); addParser(JfrType.VMOperation, new VMOperationConstantPoolParser(this)); addParser(JfrType.MonitorInflationCause, new MonitorInflationCauseConstantPoolParser(this)); + addParser(JfrType.GCWhen, new GCWhenConstantPoolParser(this)); } private void addParser(JfrType type, ConstantPoolParser parser) { diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java new file mode 100644 index 000000000000..f18bbc798ce9 --- /dev/null +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2022, 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.utils.poolparsers; + +import java.io.IOException; + +import org.junit.Assert; + +import com.oracle.svm.test.jfr.utils.JfrFileParser; +import com.oracle.svm.test.jfr.utils.RecordingInput; + +public class GCWhenConstantPoolParser extends AbstractSerializerParser { + public GCWhenConstantPoolParser(JfrFileParser parser) { + super(parser); + } + + @Override + public void parse(RecordingInput input) throws IOException { + int count = input.readInt(); + Assert.assertTrue(count > 0); + for (int i = 0; i < count; i++) { + addFoundId(input.readInt()); // Id. + Assert.assertFalse("GC when is empty!", input.readUTF().isEmpty()); + } + } +} From 6f50dae42ddab9cb38189c12f0e8bac06113097f Mon Sep 17 00:00:00 2001 From: kazukg Date: Sun, 30 Apr 2023 10:53:50 +0900 Subject: [PATCH 2/9] Modifications to avoid failing the build checks Removing unnecessary imports. --- .../oracle/svm/core/genscavenge/GCImpl.java | 2 - .../JfrGCHeapSummaryEventSupport.java | 70 ++++++++----------- 2 files changed, 30 insertions(+), 42 deletions(-) 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 b5ace128151e..d3bd8c5e6cde 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 @@ -93,8 +93,6 @@ import com.oracle.svm.core.threadlocal.VMThreadLocalMTSupport; import com.oracle.svm.core.util.TimeUtils; import com.oracle.svm.core.util.VMError; -import com.oracle.svm.core.genscavenge.JfrGCHeapSummaryEvent; -import com.oracle.svm.core.genscavenge.JfrGCHeapSummaryEventSupport; /** * Garbage collector (incremental or complete) for {@link HeapImpl}. diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java index 342c3d9d4d2f..575e76196bb2 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java @@ -29,11 +29,9 @@ import org.graalvm.nativeimage.StackValue; import org.graalvm.word.UnsignedWord; -import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; -import com.oracle.svm.core.heap.GCCause; import com.oracle.svm.core.jfr.HasJfrSupport; import com.oracle.svm.core.jfr.JfrEvent; import com.oracle.svm.core.jfr.JfrGCWhen; @@ -41,46 +39,41 @@ 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; -import com.oracle.svm.core.util.VMError; -import com.oracle.svm.core.jfr.JfrType; class JfrGCHeapSummaryEventSupport { - private final JfrGCWhen before; + private final JfrGCWhen before; private final JfrGCWhen after; - public JfrGCHeapSummaryEventSupport(JfrGCWhen before, JfrGCWhen after){ + JfrGCHeapSummaryEventSupport(JfrGCWhen before, JfrGCWhen after) { this.before = before; this.after = after; } - @Uninterruptible(reason = "Accesses a JFR buffer.") public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long heapUsed) { - + if (JfrEvent.GCHeapSummary.shouldEmit()) { - + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); - + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); - - JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; - + + JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; + JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int gcId; JfrNativeEventWriter.putLong(data, before.getId()); // @Label("When") String when; - + // VirtualSpace - JfrNativeEventWriter.putLong(data, 0L); // start - JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong - + JfrNativeEventWriter.putLong(data, 0L); // start + JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong + JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") @Label("Heap Used") @Description("Bytes allocated by objects in the heap") long heapUsed; - + JfrNativeEventWriter.endSmallEvent(data); } @@ -88,35 +81,34 @@ public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, lon @Uninterruptible(reason = "Accesses a JFR buffer.") public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { - + if (JfrEvent.GCHeapSummary.shouldEmit()) { - + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); - + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); - + JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; - + JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int gcId; JfrNativeEventWriter.putLong(data, after.getId()); // @Label("When") String when; - + // VirtualSpace - JfrNativeEventWriter.putLong(data, 0L); // start - JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong - + JfrNativeEventWriter.putLong(data, 0L); // start + JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong + JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") @Label("Heap Used") @Description("Bytes allocated by objects in the heap") long heapUsed; - + JfrNativeEventWriter.endSmallEvent(data); } - + } } - @AutomaticallyRegisteredFeature class JfrGCHeapSummaryEventFeature implements InternalFeature { @@ -124,8 +116,6 @@ class JfrGCHeapSummaryEventFeature implements InternalFeature { public void beforeAnalysis(BeforeAnalysisAccess access) { if (HasJfrSupport.get()) { - //ImageSingletons.add(JfrGCWhens.class, new JfrGCWhens()); - JfrGCWhen before = JfrGCWhens.singleton().addGCWhen("Before GC"); JfrGCWhen after = JfrGCWhens.singleton().addGCWhen("After GC"); From 6f628b48f1f718da005e2559c225303c89752bd1 Mon Sep 17 00:00:00 2001 From: kazukg Date: Mon, 1 May 2023 06:09:51 +0900 Subject: [PATCH 3/9] improvements - Added `emitGCHeapSummaryEvent` method to reduce duplication. - Hardcoded initialization of `JfrGCWhens.whens`. --- .../JfrGCHeapSummaryEventSupport.java | 47 +++++++------------ .../com/oracle/svm/core/jfr/JfrGCWhens.java | 34 +++++--------- 2 files changed, 30 insertions(+), 51 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java index 575e76196bb2..0dfaf725a425 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java @@ -50,37 +50,20 @@ class JfrGCHeapSummaryEventSupport { this.after = after; } - @Uninterruptible(reason = "Accesses a JFR buffer.") public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long heapUsed) { - if (JfrEvent.GCHeapSummary.shouldEmit()) { - - JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); - JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + emitGCHeapSummaryEvent(gcEpoch, start, heapUsed, before); - JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); - - JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; - - JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int gcId; - JfrNativeEventWriter.putLong(data, before.getId()); // @Label("When") String when; - - // VirtualSpace - JfrNativeEventWriter.putLong(data, 0L); // start - JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong + } - JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") @Label("Heap Used") @Description("Bytes allocated by objects in the heap") long heapUsed; + public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { - JfrNativeEventWriter.endSmallEvent(data); - } + emitGCHeapSummaryEvent(gcEpoch, start, heapUsed, after); } @Uninterruptible(reason = "Accesses a JFR buffer.") - public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { + public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long heapUsed, JfrGCWhen gcWhen) { if (JfrEvent.GCHeapSummary.shouldEmit()) { @@ -89,19 +72,24 @@ public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); - JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") long startTime; + JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") + // long startTime; - JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int gcId; - JfrNativeEventWriter.putLong(data, after.getId()); // @Label("When") String when; + JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int + // gcId; + JfrNativeEventWriter.putLong(data, gcWhen.getId()); // @Label("When") String when; - // VirtualSpace + // VirtualSpace JfrNativeEventWriter.putLong(data, 0L); // start JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong - JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") @Label("Heap Used") @Description("Bytes allocated by objects in the heap") long heapUsed; + JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") + // @Label("Heap Used") @Description("Bytes + // allocated by objects in the heap") long + // heapUsed; JfrNativeEventWriter.endSmallEvent(data); } @@ -116,9 +104,8 @@ class JfrGCHeapSummaryEventFeature implements InternalFeature { public void beforeAnalysis(BeforeAnalysisAccess access) { if (HasJfrSupport.get()) { - JfrGCWhen before = JfrGCWhens.singleton().addGCWhen("Before GC"); - - JfrGCWhen after = JfrGCWhens.singleton().addGCWhen("After GC"); + JfrGCWhen before = JfrGCWhens.singleton().getBeforeGCWhen(); + JfrGCWhen after = JfrGCWhens.singleton().getAfterGCWhen(); ImageSingletons.add(JfrGCHeapSummaryEventSupport.class, new JfrGCHeapSummaryEventSupport(before, after)); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java index 776596d5c87f..ea8e731e7126 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java @@ -25,38 +25,30 @@ */ package com.oracle.svm.core.jfr; -import java.util.Arrays; - import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; public class JfrGCWhens { - private JfrGCWhen[] whens; - @Platforms(Platform.HOSTED_ONLY.class) - public JfrGCWhens() { - whens = new JfrGCWhen[0]; - } + private JfrGCWhen[] whens = new JfrGCWhen[]{ + new JfrGCWhen(0, "Before GC"), new JfrGCWhen(1, "After GC") + }; - @Fold - public static JfrGCWhens singleton() { - return ImageSingletons.lookup(JfrGCWhens.class); + public JfrGCWhen getBeforeGCWhen() { + return whens[0]; } - @Platforms(Platform.HOSTED_ONLY.class) - public synchronized JfrGCWhen addGCWhen(String when) { - int id = whens.length; - JfrGCWhen result = new JfrGCWhen(id, when); - - JfrGCWhen[] newArr = Arrays.copyOf(whens, id + 1); - newArr[id] = result; - whens = newArr; - return result; + public JfrGCWhen getAfterGCWhen() { + return whens[1]; } public JfrGCWhen[] getWhens() { return whens; } + + @Fold + public static JfrGCWhens singleton() { + return ImageSingletons.lookup(JfrGCWhens.class); + } + } From b27ff8d6bd5fb6169db1db6b8cf4b465056909f2 Mon Sep 17 00:00:00 2001 From: kazukg Date: Mon, 1 May 2023 06:19:30 +0900 Subject: [PATCH 4/9] fix checkstyle error --- .../src/com/oracle/svm/core/genscavenge/GCImpl.java | 2 +- .../svm/core/genscavenge/JfrGCHeapSummaryEvent.java | 9 ++++----- .../genscavenge/JfrGCHeapSummaryEventSupport.java | 11 +++++------ .../oracle/svm/test/jfr/TestGCHeapSummaryEvent.java | 3 +-- 4 files changed, 11 insertions(+), 14 deletions(-) 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 d3bd8c5e6cde..733b91246b06 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 @@ -208,7 +208,7 @@ private void collectOperation(CollectionVMOperationData data) { GCCause cause = GCCause.fromId(data.getCauseId()); printGCBefore(cause.getName()); - JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventBeforeGC(getCollectionEpoch(), JfrTicks.elapsedTicks(),getChunkBytes().rawValue()); + JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventBeforeGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getChunkBytes().rawValue()); boolean outOfMemory = collectImpl(cause, data.getRequestingNanoTime(), data.getForceFullGC()); JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventAfterGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getChunkBytes().rawValue()); printGCAfter(cause.getName()); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java index b948c1479e0d..6af834b1f81c 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java @@ -28,18 +28,17 @@ import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.word.UnsignedWord; - class JfrGCHeapSummaryEvent { - public static void emitJfrGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch,long start,long heapUsed) { - if (hasJfrSupport() ) { - jfrSupport().emitGCHeapSummaryEventBeforeGC(gcEpoch, start,heapUsed); + public static void emitJfrGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long heapUsed) { + if (hasJfrSupport()) { + jfrSupport().emitGCHeapSummaryEventBeforeGC(gcEpoch, start, heapUsed); } } public static void emitJfrGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { if (hasJfrSupport()) { - jfrSupport().emitGCHeapSummaryEventAfterGC(gcEpoch, start,heapUsed); + jfrSupport().emitGCHeapSummaryEventAfterGC(gcEpoch, start, heapUsed); } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java index 0dfaf725a425..603f6bf852ff 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java @@ -73,10 +73,10 @@ public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long heapUs JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") - // long startTime; + // long startTime; JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int - // gcId; + // gcId; JfrNativeEventWriter.putLong(data, gcWhen.getId()); // @Label("When") String when; // VirtualSpace @@ -87,9 +87,9 @@ public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long heapUs JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") - // @Label("Heap Used") @Description("Bytes - // allocated by objects in the heap") long - // heapUsed; + // @Label("Heap Used") @Description("Bytes + // allocated by objects in the heap") long + // heapUsed; JfrNativeEventWriter.endSmallEvent(data); } @@ -108,7 +108,6 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { JfrGCWhen after = JfrGCWhens.singleton().getAfterGCWhen(); ImageSingletons.add(JfrGCHeapSummaryEventSupport.class, new JfrGCHeapSummaryEventSupport(before, after)); - } } diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java index 736682c79c85..5cfec4afc717 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java @@ -37,7 +37,6 @@ import jdk.jfr.Recording; import jdk.jfr.consumer.RecordedEvent; - public class TestGCHeapSummaryEvent extends JfrRecordingTest { @Test @@ -53,4 +52,4 @@ public void test() throws Throwable { private static void validateEvents(List events) { assertTrue(events.size() > 0); } -} \ No newline at end of file +} From dc171a24c1ea58ee6640e3cc1cdceec0432348ac Mon Sep 17 00:00:00 2001 From: kazukg Date: Mon, 1 May 2023 06:52:58 +0900 Subject: [PATCH 5/9] Added isInConfiguration Added isInConfiguration to include JfrGCHeapSummaryEventFeature only when the default SerialGC is used. --- .../svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java index 603f6bf852ff..fbfc68ae130b 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java @@ -29,6 +29,7 @@ import org.graalvm.nativeimage.StackValue; import org.graalvm.word.UnsignedWord; +import com.oracle.svm.core.SubstrateOptions; import com.oracle.svm.core.Uninterruptible; import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; import com.oracle.svm.core.feature.InternalFeature; @@ -100,6 +101,12 @@ public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long heapUs @AutomaticallyRegisteredFeature class JfrGCHeapSummaryEventFeature implements InternalFeature { + @Override + public boolean isInConfiguration(IsInConfigurationAccess access) { + return SubstrateOptions.UseSerialGC.getValue(); + } + + @Override public void beforeAnalysis(BeforeAnalysisAccess access) { if (HasJfrSupport.get()) { From 9971562f37eb947330d67e06ad0f74ae494144bd Mon Sep 17 00:00:00 2001 From: kazukg Date: Thu, 11 May 2023 06:32:53 +0900 Subject: [PATCH 6/9] Remove unnecessary definition from JfrType --- .../com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java | 1 - 1 file changed, 1 deletion(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java index ae077a48b5f0..886cd1b9fcf2 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrType.java @@ -45,7 +45,6 @@ public enum JfrType { GCCause("jdk.types.GCCause"), GCName("jdk.types.GCName"), GCWhen("jdk.types.GCWhen"), - VirtualSpace("jdk.types.VirtualSpace"), VMOperation("jdk.types.VMOperationType"), MonitorInflationCause("jdk.types.InflateCause"); From 9e99d5a8c5f44e73e597d1b8501bd0653784c809 Mon Sep 17 00:00:00 2001 From: kazukg Date: Thu, 11 May 2023 06:38:00 +0900 Subject: [PATCH 7/9] code improvements - Changed not to cache - Improved code to emit committed Size. --- .../oracle/svm/core/genscavenge/GCImpl.java | 4 +-- .../genscavenge/JfrGCHeapSummaryEvent.java | 8 +++--- .../JfrGCHeapSummaryEventSupport.java | 26 +++++-------------- 3 files changed, 13 insertions(+), 25 deletions(-) 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 733b91246b06..412e7366b0fc 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 @@ -208,9 +208,9 @@ private void collectOperation(CollectionVMOperationData data) { GCCause cause = GCCause.fromId(data.getCauseId()); printGCBefore(cause.getName()); - JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventBeforeGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getChunkBytes().rawValue()); + JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventBeforeGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getPolicy().getCurrentHeapCapacity().rawValue(), getChunkBytes().rawValue()); boolean outOfMemory = collectImpl(cause, data.getRequestingNanoTime(), data.getForceFullGC()); - JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventAfterGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getChunkBytes().rawValue()); + JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventAfterGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getPolicy().getCurrentHeapCapacity().rawValue(), getChunkBytes().rawValue()); printGCAfter(cause.getName()); finishCollection(); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java index 6af834b1f81c..54024e795761 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java @@ -30,15 +30,15 @@ class JfrGCHeapSummaryEvent { - public static void emitJfrGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long heapUsed) { + public static void emitJfrGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { if (hasJfrSupport()) { - jfrSupport().emitGCHeapSummaryEventBeforeGC(gcEpoch, start, heapUsed); + jfrSupport().emitGCHeapSummaryEventBeforeGC(gcEpoch, start, committedSize, heapUsed); } } - public static void emitJfrGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { + public static void emitJfrGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { if (hasJfrSupport()) { - jfrSupport().emitGCHeapSummaryEventAfterGC(gcEpoch, start, heapUsed); + jfrSupport().emitGCHeapSummaryEventAfterGC(gcEpoch, start, committedSize, heapUsed); } } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java index fbfc68ae130b..40d2dd081d19 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java @@ -43,28 +43,20 @@ class JfrGCHeapSummaryEventSupport { - private final JfrGCWhen before; - private final JfrGCWhen after; + public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { - JfrGCHeapSummaryEventSupport(JfrGCWhen before, JfrGCWhen after) { - this.before = before; - this.after = after; - } - - public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long heapUsed) { - - emitGCHeapSummaryEvent(gcEpoch, start, heapUsed, before); + emitGCHeapSummaryEvent(gcEpoch, start, committedSize, heapUsed, JfrGCWhens.singleton().getBeforeGCWhen()); } - public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long heapUsed) { + public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { - emitGCHeapSummaryEvent(gcEpoch, start, heapUsed, after); + emitGCHeapSummaryEvent(gcEpoch, start, committedSize, heapUsed, JfrGCWhens.singleton().getAfterGCWhen()); } @Uninterruptible(reason = "Accesses a JFR buffer.") - public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long heapUsed, JfrGCWhen gcWhen) { + public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed, JfrGCWhen gcWhen) { if (JfrEvent.GCHeapSummary.shouldEmit()) { @@ -83,7 +75,7 @@ public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long heapUs // VirtualSpace JfrNativeEventWriter.putLong(data, 0L); // start JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // committedSize : ulong + JfrNativeEventWriter.putLong(data, committedSize); // committedSize : ulong JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong @@ -106,15 +98,11 @@ public boolean isInConfiguration(IsInConfigurationAccess access) { return SubstrateOptions.UseSerialGC.getValue(); } - @Override public void beforeAnalysis(BeforeAnalysisAccess access) { if (HasJfrSupport.get()) { - JfrGCWhen before = JfrGCWhens.singleton().getBeforeGCWhen(); - JfrGCWhen after = JfrGCWhens.singleton().getAfterGCWhen(); - - ImageSingletons.add(JfrGCHeapSummaryEventSupport.class, new JfrGCHeapSummaryEventSupport(before, after)); + ImageSingletons.add(JfrGCHeapSummaryEventSupport.class, new JfrGCHeapSummaryEventSupport()); } } From 8adccb51fb2a0870bcb9ed8a4e48e6970f4ad288 Mon Sep 17 00:00:00 2001 From: kazukg Date: Mon, 29 May 2023 09:14:36 +0900 Subject: [PATCH 8/9] refactor - Changed to be processed by static method - Replaced class with an enum for improved - Updated copyright headers to ensure accuracy --- .../oracle/svm/core/genscavenge/GCImpl.java | 5 +- .../genscavenge/JfrGCHeapSummaryEvent.java | 66 ++++++++--- .../JfrGCHeapSummaryEventSupport.java | 109 ------------------ .../com/oracle/svm/core/jfr/JfrFeature.java | 1 - .../com/oracle/svm/core/jfr/JfrGCWhen.java | 29 ++--- .../svm/core/jfr/JfrGCWhenSerializer.java | 7 +- .../com/oracle/svm/core/jfr/JfrGCWhens.java | 54 --------- .../svm/test/jfr/TestGCHeapSummaryEvent.java | 5 +- .../poolparsers/GCWhenConstantPoolParser.java | 3 +- 9 files changed, 70 insertions(+), 209 deletions(-) delete mode 100644 substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java delete mode 100644 substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.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 412e7366b0fc..3529f737be8d 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 @@ -77,6 +77,7 @@ import com.oracle.svm.core.heap.RuntimeCodeCacheCleaner; import com.oracle.svm.core.heap.VMOperationInfos; 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.log.Log; import com.oracle.svm.core.os.CommittedMemoryProvider; @@ -208,9 +209,9 @@ private void collectOperation(CollectionVMOperationData data) { GCCause cause = GCCause.fromId(data.getCauseId()); printGCBefore(cause.getName()); - JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventBeforeGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getPolicy().getCurrentHeapCapacity().rawValue(), getChunkBytes().rawValue()); + JfrGCHeapSummaryEvent.emit(getCollectionEpoch(), JfrTicks.elapsedTicks(), getPolicy().getCurrentHeapCapacity().rawValue(), getChunkBytes().rawValue(), JfrGCWhen.BEFORE_GC); boolean outOfMemory = collectImpl(cause, data.getRequestingNanoTime(), data.getForceFullGC()); - JfrGCHeapSummaryEvent.emitJfrGCHeapSummaryEventAfterGC(getCollectionEpoch(), JfrTicks.elapsedTicks(), getPolicy().getCurrentHeapCapacity().rawValue(), getChunkBytes().rawValue()); + JfrGCHeapSummaryEvent.emit(getCollectionEpoch(), JfrTicks.elapsedTicks(), getPolicy().getCurrentHeapCapacity().rawValue(), getChunkBytes().rawValue(), JfrGCWhen.AFTER_GC); printGCAfter(cause.getName()); finishCollection(); diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java index 54024e795761..70c7ad59d3d9 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023 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 @@ -19,36 +19,72 @@ * 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 + * or visit www.oracle.com if you need additional information or have anycd * questions. */ package com.oracle.svm.core.genscavenge; -import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.compiler.api.replacements.Fold; + +import org.graalvm.nativeimage.StackValue; import org.graalvm.word.UnsignedWord; +import com.oracle.svm.core.SubstrateOptions; +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.JfrGCWhen; +import com.oracle.svm.core.jfr.JfrNativeEventWriter; +import com.oracle.svm.core.jfr.JfrNativeEventWriterData; +import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess; + class JfrGCHeapSummaryEvent { - public static void emitJfrGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { - if (hasJfrSupport()) { - jfrSupport().emitGCHeapSummaryEventBeforeGC(gcEpoch, start, committedSize, heapUsed); + public static void emit(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed, JfrGCWhen gcWhen) { + if (HasJfrSupport.get() && isEnabled()) { + emit0(gcEpoch, start, committedSize, heapUsed, gcWhen); } } - public static void emitJfrGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { - if (hasJfrSupport()) { - jfrSupport().emitGCHeapSummaryEventAfterGC(gcEpoch, start, committedSize, heapUsed); + @Uninterruptible(reason = "Accesses a JFR buffer.") + private static void emit0(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed, JfrGCWhen gcWhen) { + + if (JfrEvent.GCHeapSummary.shouldEmit()) { + + JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); + JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); + + JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); + + JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") + // long startTime; + + JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int + // gcId; + JfrNativeEventWriter.putLong(data, gcWhen.ordinal()); // @Label("When") String when; + + // VirtualSpace + JfrNativeEventWriter.putLong(data, 0L); // start + JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong + JfrNativeEventWriter.putLong(data, committedSize); // committedSize : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong + JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong + + JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") + // @Label("Heap Used") @Description("Bytes + // allocated by objects in the heap") long + // heapUsed; + + JfrNativeEventWriter.endSmallEvent(data); } - } - @Fold - static boolean hasJfrSupport() { - return ImageSingletons.contains(JfrGCHeapSummaryEventSupport.class); } @Fold - static JfrGCHeapSummaryEventSupport jfrSupport() { - return ImageSingletons.lookup(JfrGCHeapSummaryEventSupport.class); + static boolean isEnabled() { + return SubstrateOptions.UseSerialGC.getValue(); } + } diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java deleted file mode 100644 index 40d2dd081d19..000000000000 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEventSupport.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, 2022, 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.genscavenge; - -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.StackValue; -import org.graalvm.word.UnsignedWord; - -import com.oracle.svm.core.SubstrateOptions; -import com.oracle.svm.core.Uninterruptible; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; -import com.oracle.svm.core.feature.InternalFeature; -import com.oracle.svm.core.jfr.HasJfrSupport; -import com.oracle.svm.core.jfr.JfrEvent; -import com.oracle.svm.core.jfr.JfrGCWhen; -import com.oracle.svm.core.jfr.JfrGCWhens; -import com.oracle.svm.core.jfr.JfrNativeEventWriter; -import com.oracle.svm.core.jfr.JfrNativeEventWriterData; -import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess; - -class JfrGCHeapSummaryEventSupport { - - public void emitGCHeapSummaryEventBeforeGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { - - emitGCHeapSummaryEvent(gcEpoch, start, committedSize, heapUsed, JfrGCWhens.singleton().getBeforeGCWhen()); - - } - - public void emitGCHeapSummaryEventAfterGC(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed) { - - emitGCHeapSummaryEvent(gcEpoch, start, committedSize, heapUsed, JfrGCWhens.singleton().getAfterGCWhen()); - - } - - @Uninterruptible(reason = "Accesses a JFR buffer.") - public void emitGCHeapSummaryEvent(UnsignedWord gcEpoch, long start, long committedSize, long heapUsed, JfrGCWhen gcWhen) { - - if (JfrEvent.GCHeapSummary.shouldEmit()) { - - JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class); - JfrNativeEventWriterDataAccess.initializeThreadLocalNativeBuffer(data); - - JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); - - JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") - // long startTime; - - JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int - // gcId; - JfrNativeEventWriter.putLong(data, gcWhen.getId()); // @Label("When") String when; - - // VirtualSpace - JfrNativeEventWriter.putLong(data, 0L); // start - JfrNativeEventWriter.putLong(data, 0L); // committedEnd : ulong - JfrNativeEventWriter.putLong(data, committedSize); // committedSize : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedEnd : ulong - JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong - - JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") - // @Label("Heap Used") @Description("Bytes - // allocated by objects in the heap") long - // heapUsed; - - JfrNativeEventWriter.endSmallEvent(data); - } - - } -} - -@AutomaticallyRegisteredFeature -class JfrGCHeapSummaryEventFeature implements InternalFeature { - - @Override - public boolean isInConfiguration(IsInConfigurationAccess access) { - return SubstrateOptions.UseSerialGC.getValue(); - } - - @Override - public void beforeAnalysis(BeforeAnalysisAccess access) { - if (HasJfrSupport.get()) { - - ImageSingletons.add(JfrGCHeapSummaryEventSupport.class, new JfrGCHeapSummaryEventSupport()); - } - } - -} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java index 82540ef98b47..cfbc8f2ed20d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrFeature.java @@ -166,7 +166,6 @@ public void afterRegistration(AfterRegistrationAccess access) { ImageSingletons.add(JfrTraceIdEpoch.class, new JfrTraceIdEpoch()); ImageSingletons.add(JfrGCNames.class, new JfrGCNames()); ImageSingletons.add(SamplerStackWalkVisitor.class, new SamplerStackWalkVisitor()); - ImageSingletons.add(JfrGCWhens.class, new JfrGCWhens()); JfrSerializerSupport.get().register(new JfrFrameTypeSerializer()); JfrSerializerSupport.get().register(new JfrThreadStateSerializer()); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java index 659377f05a37..9cdb4326148a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhen.java @@ -1,6 +1,5 @@ /* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved. + * Copyright (c) 2023, 2023, 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 @@ -25,27 +24,17 @@ */ package com.oracle.svm.core.jfr; -import org.graalvm.nativeimage.Platform; -import org.graalvm.nativeimage.Platforms; +public enum JfrGCWhen { + BEFORE_GC("Before GC"), + AFTER_GC("After GC"); -import com.oracle.svm.core.Uninterruptible; + private final String gcWhen; -public class JfrGCWhen { - private final int id; - private final String when; - - @Platforms(Platform.HOSTED_ONLY.class) - protected JfrGCWhen(int id, String when) { - this.id = id; - this.when = when; - } - - public String getWhen() { - return when; + JfrGCWhen(String gcWhen) { + this.gcWhen = gcWhen; } - @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) - public int getId() { - return id; + public String getGcWhen() { + return this.gcWhen; } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java index d74c98c6b639..34b62dc44d4a 100755 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhenSerializer.java @@ -34,12 +34,13 @@ public JfrGCWhenSerializer() { @Override public void write(JfrChunkWriter writer) { - JfrGCWhen[] gcWhens = JfrGCWhens.singleton().getWhens(); + JfrGCWhen[] gcWhens = JfrGCWhen.values(); + writer.writeCompressedLong(JfrType.GCWhen.getId()); writer.writeCompressedLong(gcWhens.length); for (JfrGCWhen when : gcWhens) { - writer.writeCompressedLong(when.getId()); - writer.writeString(when.getWhen()); + writer.writeCompressedLong(when.ordinal()); + writer.writeString(when.getGcWhen()); } } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java deleted file mode 100644 index ea8e731e7126..000000000000 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrGCWhens.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, 2022, 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; - -import org.graalvm.compiler.api.replacements.Fold; -import org.graalvm.nativeimage.ImageSingletons; - -public class JfrGCWhens { - - private JfrGCWhen[] whens = new JfrGCWhen[]{ - new JfrGCWhen(0, "Before GC"), new JfrGCWhen(1, "After GC") - }; - - public JfrGCWhen getBeforeGCWhen() { - return whens[0]; - } - - public JfrGCWhen getAfterGCWhen() { - return whens[1]; - } - - public JfrGCWhen[] getWhens() { - return whens; - } - - @Fold - public static JfrGCWhens singleton() { - return ImageSingletons.lookup(JfrGCWhens.class); - } - -} diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java index 5cfec4afc717..03a168c86916 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java @@ -1,6 +1,5 @@ /* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved. + * Copyright (c) 2023, 2023, 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 @@ -41,7 +40,7 @@ public class TestGCHeapSummaryEvent extends JfrRecordingTest { @Test public void test() throws Throwable { - String[] events = new String[]{JfrEvent.GCHeapSummary.getName()}; + String[] events = new String[] { JfrEvent.GCHeapSummary.getName() }; Recording recording = startRecording(events); System.gc(); diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java index f18bbc798ce9..b1be4fd4444e 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/utils/poolparsers/GCWhenConstantPoolParser.java @@ -1,6 +1,5 @@ /* - * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved. + * Copyright (c) 2023, 2023, 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 From f16288b52ef3d0a3b684aa4954065bdad6b9d126 Mon Sep 17 00:00:00 2001 From: kazukg Date: Mon, 29 May 2023 21:51:20 +0900 Subject: [PATCH 9/9] FIX checksyle error --- .../svm/core/genscavenge/JfrGCHeapSummaryEvent.java | 13 ++++++------- .../oracle/svm/test/jfr/TestGCHeapSummaryEvent.java | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java index 70c7ad59d3d9..4993ce18922e 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCHeapSummaryEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023, 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 @@ -24,7 +24,6 @@ */ package com.oracle.svm.core.genscavenge; -import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.compiler.api.replacements.Fold; import org.graalvm.nativeimage.StackValue; @@ -59,10 +58,10 @@ private static void emit0(UnsignedWord gcEpoch, long start, long committedSize, JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.GCHeapSummary); JfrNativeEventWriter.putLong(data, start); // @Label("Start Time") @Timestamp("TICKS") - // long startTime; + // long startTime; JfrNativeEventWriter.putLong(data, gcEpoch.rawValue()); // @Label("GC Identifier") int - // gcId; + // gcId; JfrNativeEventWriter.putLong(data, gcWhen.ordinal()); // @Label("When") String when; // VirtualSpace @@ -73,9 +72,9 @@ private static void emit0(UnsignedWord gcEpoch, long start, long committedSize, JfrNativeEventWriter.putLong(data, 0L); // reservedSize : ulong JfrNativeEventWriter.putLong(data, heapUsed); // @Unsigned @DataAmount("BYTES") - // @Label("Heap Used") @Description("Bytes - // allocated by objects in the heap") long - // heapUsed; + // @Label("Heap Used") @Description("Bytes + // allocated by objects in the heap") long + // heapUsed; JfrNativeEventWriter.endSmallEvent(data); } diff --git a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java index 03a168c86916..229ef4004616 100644 --- a/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java +++ b/substratevm/src/com.oracle.svm.test/src/com/oracle/svm/test/jfr/TestGCHeapSummaryEvent.java @@ -40,7 +40,7 @@ public class TestGCHeapSummaryEvent extends JfrRecordingTest { @Test public void test() throws Throwable { - String[] events = new String[] { JfrEvent.GCHeapSummary.getName() }; + String[] events = new String[] {JfrEvent.GCHeapSummary.getName() }; Recording recording = startRecording(events); System.gc();