Skip to content

Commit 644de03

Browse files
tests, type repo, sync, periodic events
final cleanup refactor gate formatting fix minor refactor
1 parent 4a5c404 commit 644de03

File tree

13 files changed

+304
-157
lines changed

13 files changed

+304
-157
lines changed

substratevm/mx.substratevm/suite.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@
336336
],
337337
"requires" : [
338338
"jdk.management",
339+
"jdk.jfr",
339340
],
340341
"requiresConcealed" : {
341342
"java.base": [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2023, 2023, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.svm.core.genscavenge;
28+
29+
import com.oracle.svm.core.Uninterruptible;
30+
import com.oracle.svm.core.heap.GCCause;
31+
import com.oracle.svm.core.jfr.JfrEvent;
32+
import com.oracle.svm.core.jfr.events.ObjectCountEventSupport;
33+
import jdk.jfr.Event;
34+
import jdk.jfr.Name;
35+
import jdk.jfr.Period;
36+
37+
@Name("EveryChunkPeriodicGCEvents")
38+
@Period(value = "everyChunk")
39+
public class EveryChunkNativeGCPeriodicEvents extends Event {
40+
41+
public static void emit() {
42+
emitObjectCount();
43+
}
44+
45+
@Uninterruptible(reason = "Set and unset should be atomic with invoked GC to avoid races.")
46+
private static void emitObjectCount() {
47+
if (JfrEvent.ObjectCount.shouldEmit()) {
48+
ObjectCountEventSupport.setShouldSendRequestableEvent(true);
49+
GCImpl.getGCImpl().collectWithoutAllocating(GCCause.JfrObjectCount, true);
50+
ObjectCountEventSupport.setShouldSendRequestableEvent(false);
51+
}
52+
}
53+
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/GCImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import com.oracle.svm.core.jfr.JfrGCWhen;
8383
import com.oracle.svm.core.jfr.JfrTicks;
8484
import com.oracle.svm.core.jfr.events.AllocationRequiringGCEvent;
85+
import com.oracle.svm.core.jfr.events.ObjectCountEventSupport;
8586
import com.oracle.svm.core.log.Log;
8687
import com.oracle.svm.core.os.CommittedMemoryProvider;
8788
import com.oracle.svm.core.snippets.ImplicitExceptions;
@@ -177,7 +178,7 @@ private void collect(GCCause cause, boolean forceFullGC) {
177178

178179
@Uninterruptible(reason = "Avoid races with other threads that also try to trigger a GC")
179180
@RestrictHeapAccess(access = RestrictHeapAccess.Access.NO_ALLOCATION, reason = "Must not allocate in the implementation of garbage collection.")
180-
boolean collectWithoutAllocating(GCCause cause, boolean forceFullGC) {
181+
public boolean collectWithoutAllocating(GCCause cause, boolean forceFullGC) {
181182
VMError.guarantee(!hasNeverCollectPolicy());
182183

183184
int size = SizeOf.get(CollectionVMOperationData.class);
@@ -244,6 +245,7 @@ private boolean collectImpl(GCCause cause, long requestingNanoTime, boolean forc
244245
}
245246
} finally {
246247
JfrGCEvents.emitGarbageCollectionEvent(getCollectionEpoch(), cause, startTicks);
248+
ObjectCountEventSupport.emitEvents((int) getCollectionEpoch().rawValue(), startTicks);
247249
}
248250
return outOfMemory;
249251
}

substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/JfrGCEventSupport.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
*/
2626
package com.oracle.svm.core.genscavenge;
2727

28+
import jdk.jfr.FlightRecorder;
2829
import org.graalvm.nativeimage.ImageSingletons;
2930
import org.graalvm.nativeimage.StackValue;
3031
import org.graalvm.word.UnsignedWord;
3132

33+
import com.oracle.svm.core.jdk.RuntimeSupport;
3234
import com.oracle.svm.core.SubstrateOptions;
3335
import com.oracle.svm.core.Uninterruptible;
3436
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
@@ -136,6 +138,18 @@ private int popPhase() {
136138
assert currentPhase > 0;
137139
return --currentPhase;
138140
}
141+
142+
public static RuntimeSupport.Hook startupHook() {
143+
return isFirstIsolate -> {
144+
FlightRecorder.addPeriodicEvent(EveryChunkNativeGCPeriodicEvents.class, EveryChunkNativeGCPeriodicEvents::emit);
145+
};
146+
}
147+
148+
public static RuntimeSupport.Hook shutdownHook() {
149+
return isFirstIsolate -> {
150+
FlightRecorder.removePeriodicEvent(EveryChunkNativeGCPeriodicEvents::emit);
151+
};
152+
}
139153
}
140154

141155
@AutomaticallyRegisteredFeature
@@ -150,6 +164,10 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
150164
if (HasJfrSupport.get()) {
151165
JfrGCName name = JfrGCNames.singleton().addGCName("serial");
152166
ImageSingletons.add(JfrGCEventSupport.class, new JfrGCEventSupport(name));
167+
168+
RuntimeSupport runtime = RuntimeSupport.getRuntimeSupport();
169+
runtime.addStartupHook(JfrGCEventSupport.startupHook());
170+
runtime.addShutdownHook(JfrGCEventSupport.shutdownHook());
153171
}
154172
}
155173
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/GCCause.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class GCCause {
4949
@DuplicatedInNativeCode public static final GCCause HintedGC = new GCCause("Hinted GC", 3);
5050
@DuplicatedInNativeCode public static final GCCause JvmtiForceGC = new GCCause("JvmtiEnv ForceGarbageCollection", 4);
5151
@DuplicatedInNativeCode public static final GCCause HeapDump = new GCCause("Heap Dump Initiated GC ", 5);
52+
@DuplicatedInNativeCode public static final GCCause JfrObjectCount = new GCCause("Required for JFR object counting", 6);
5253

5354
@UnknownObjectField(availability = ReadyForCompilation.class) protected static GCCause[] GCCauses;
5455

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHubSupport.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ public void setMaxTypeId(int maxTypeId) {
5050
this.maxTypeId = maxTypeId;
5151
}
5252

53-
@Platforms(Platform.HOSTED_ONLY.class)
5453
public int getMaxTypeId() {
5554
return maxTypeId;
5655
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrTypeRepository.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,20 @@ private TypeInfo collectTypeInfo(boolean flushpoint) {
102102
return typeInfo;
103103
}
104104

105+
boolean isClassGenerated(Class<?> clazz) {
106+
return clazz != null && clazz.getPackage() != null && clazz.getPackage().getName().equals("jdk.internal.reflect") && clazz.getName().contains("GeneratedSerializationConstructorAccessor");
107+
}
108+
105109
private void visitClass(TypeInfo typeInfo, Class<?> clazz) {
106-
if (clazz != null && addClass(typeInfo, clazz)) {
107-
visitPackage(typeInfo, clazz.getPackage(), clazz.getModule());
110+
if ((clazz != null && addClass(typeInfo, clazz))) {
111+
visitPackage(typeInfo, clazz.getPackage(), clazz.getModule(), isClassGenerated(clazz));
108112
visitClass(typeInfo, clazz.getSuperclass());
113+
visitClassLoader(typeInfo, clazz.getClassLoader());
109114
}
110115
}
111116

112-
private void visitPackage(TypeInfo typeInfo, Package pkg, Module module) {
113-
if (pkg != null && addPackage(typeInfo, pkg, module)) {
117+
private void visitPackage(TypeInfo typeInfo, Package pkg, Module module, boolean generated) {
118+
if (pkg != null && addPackage(typeInfo, pkg, module, generated)) {
114119
visitModule(typeInfo, module);
115120
}
116121
}
@@ -246,10 +251,14 @@ private boolean isClassVisited(TypeInfo typeInfo, Class<?> clazz) {
246251
return typeInfo.classes.contains(clazz) || flushedClasses.contains(clazz);
247252
}
248253

249-
private boolean addPackage(TypeInfo typeInfo, Package pkg, Module module) {
254+
private boolean addPackage(TypeInfo typeInfo, Package pkg, Module module, boolean generated) {
250255
if (isPackageVisited(typeInfo, pkg)) {
251-
assert module == (flushedPackages.containsKey(pkg.getName()) ? flushedPackages.get(pkg.getName()).module : typeInfo.packages.get(pkg.getName()).module);
252-
return false;
256+
Module cached = (flushedPackages.containsKey(pkg.getName()) ? flushedPackages.get(pkg.getName()).module : typeInfo.packages.get(pkg.getName()).module);
257+
if (cached.isNamed() || !module.isNamed()) {
258+
assert module == cached || (generated && !module.isNamed());
259+
return false;
260+
}
261+
assert module != cached && !generated;
253262
}
254263
// The empty package represented by "" is always traced with id 0
255264
long id = pkg.getName().isEmpty() ? 0 : ++currentPackageId;

0 commit comments

Comments
 (0)