Skip to content

Commit 7fe6c24

Browse files
committed
[GR-60116] Persist metadata of AOT types during build-time for Crema
PullRequest: graal/19798
2 parents 47c9c9d + f24ada7 commit 7fe6c24

File tree

15 files changed

+373
-114
lines changed

15 files changed

+373
-114
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/ImageCodeInfo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ public CodePointer getCodeStart() {
131131
return codeStart;
132132
}
133133

134+
@Platforms(Platform.HOSTED_ONLY.class)
134135
public HostedImageCodeInfo getHostedImageCodeInfo() {
135136
return hostedImageCodeInfo;
136137
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
import java.util.stream.Collectors;
3535
import java.util.stream.Stream;
3636

37+
import org.graalvm.nativeimage.Platform;
38+
import org.graalvm.nativeimage.Platforms;
39+
3740
import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue;
3841
import com.oracle.svm.core.option.BundleMember;
3942
import com.oracle.svm.core.option.HostedOptionKey;
@@ -213,6 +216,7 @@ public static List<URL> findConfigurationResources(String fileName, ClassLoader
213216
return resources;
214217
}
215218

219+
@Platforms(Platform.HOSTED_ONLY.class)
216220
private static UserError.UserException foundLockFile(String container) {
217221
throw UserError.abort("%s contains file '%s', which means an agent is currently writing to it." +
218222
"The agent must finish execution before its generated configuration can be used to build a native image." +
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.hub;
26+
27+
import jdk.vm.ci.meta.ResolvedJavaType;
28+
29+
public interface CremaSupport {
30+
ResolvedJavaType createInterpreterType(DynamicHub hub, ResolvedJavaType analysisType);
31+
}

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@
143143
import jdk.internal.reflect.FieldAccessor;
144144
import jdk.internal.reflect.Reflection;
145145
import jdk.internal.reflect.ReflectionFactory;
146+
import jdk.vm.ci.meta.ResolvedJavaType;
146147
import sun.reflect.annotation.AnnotationType;
147148
import sun.reflect.generics.factory.GenericsFactory;
148149
import sun.reflect.generics.repository.ClassRepository;
@@ -435,7 +436,11 @@ public static DynamicHub allocate(String name, DynamicHub superHub, DynamicHub c
435436
// GR-59683
436437
Module module = null;
437438

438-
DynamicHubCompanion companion = DynamicHubCompanion.createAtRuntime(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature);
439+
// GR-59683: Setup interpreter metadata at run-time.
440+
ResolvedJavaType interpreterType = null;
441+
442+
DynamicHubCompanion companion = DynamicHubCompanion.createAtRuntime(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature,
443+
interpreterType);
439444

440445
/* Always allow unsafe allocation for classes that were loaded at run-time. */
441446
companion.canUnsafeAllocate = true;
@@ -461,6 +466,8 @@ public static DynamicHub allocate(String name, DynamicHub superHub, DynamicHub c
461466
companion.enumConstantsReference = null;
462467

463468
/*
469+
* GR-61330:
470+
*
464471
* These are read in snippets and must also not be set directly or the analysis would not
465472
* consider them to be immutable:
466473
*
@@ -470,12 +477,12 @@ public static DynamicHub allocate(String name, DynamicHub superHub, DynamicHub c
470477
* NumUtil.safeToUByte(makeFlag(ADDITIONAL_FLAGS_INSTANTIATED_BIT, true));
471478
*/
472479

480+
// GR-61330: only write if the field exists according to analysis
481+
// companion.metaType = null;
482+
473483
// GR-60080: Proper referenceMap needed.
474484
int referenceMapIndex = DynamicHub.fromClass(Object.class).referenceMapIndex;
475485

476-
// GR-59683: Maybe can be used to inject a backreference to InterpreterResolvedObjectType
477-
companion.metaType = null;
478-
479486
// GR-57813
480487
companion.hubMetadata = null;
481488
companion.reflectionMetadata = null;
@@ -743,6 +750,14 @@ public SharedType getMetaType() {
743750
return companion.metaType;
744751
}
745752

753+
public ResolvedJavaType getInterpreterType() {
754+
return companion.interpreterType;
755+
}
756+
757+
public void setInterpreterType(ResolvedJavaType interpreterType) {
758+
companion.interpreterType = interpreterType;
759+
}
760+
746761
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
747762
public String getSourceFileName() {
748763
return companion.sourceFileName;

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.oracle.svm.core.meta.SharedType;
4040

4141
import jdk.internal.vm.annotation.Stable;
42+
import jdk.vm.ci.meta.ResolvedJavaType;
4243
import sun.reflect.annotation.AnnotationType;
4344
import sun.reflect.generics.repository.ClassRepository;
4445

@@ -128,6 +129,7 @@ public final class DynamicHubCompanion {
128129
* {@link DynamicHub#NO_CLASS_LOADER}.
129130
*/
130131
Object classLoader;
132+
ResolvedJavaType interpreterType;
131133

132134
String packageName;
133135
ProtectionDomain protectionDomain;
@@ -143,17 +145,18 @@ public final class DynamicHubCompanion {
143145
static DynamicHubCompanion createHosted(Module module, DynamicHub superHub, String sourceFileName, int modifiers,
144146
Object classLoader, Class<?> nestHost, String simpleBinaryName, Object declaringClass, String signature) {
145147

146-
return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature);
148+
return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature, null);
147149
}
148150

149151
static DynamicHubCompanion createAtRuntime(Module module, DynamicHub superHub, String sourceFileName, int modifiers,
150-
ClassLoader classLoader, Class<?> nestHost, String simpleBinaryName, Object declaringClass, String signature) {
152+
ClassLoader classLoader, Class<?> nestHost, String simpleBinaryName, Object declaringClass, String signature,
153+
ResolvedJavaType interpreterType) {
151154
assert RuntimeClassLoading.isSupported();
152-
return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature);
155+
return new DynamicHubCompanion(module, superHub, sourceFileName, modifiers, classLoader, nestHost, simpleBinaryName, declaringClass, signature, interpreterType);
153156
}
154157

155158
private DynamicHubCompanion(Module module, DynamicHub superHub, String sourceFileName, int modifiers,
156-
Object classLoader, Class<?> nestHost, String simpleBinaryName, Object declaringClass, String signature) {
159+
Object classLoader, Class<?> nestHost, String simpleBinaryName, Object declaringClass, String signature, ResolvedJavaType interpreterType) {
157160
this.module = module;
158161
this.superHub = superHub;
159162
this.sourceFileName = sourceFileName;
@@ -164,5 +167,6 @@ private DynamicHubCompanion(Module module, DynamicHub superHub, String sourceFil
164167
this.signature = signature;
165168

166169
this.classLoader = classLoader;
170+
this.interpreterType = interpreterType;
167171
}
168172
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import static jdk.graal.compiler.options.OptionStability.EXPERIMENTAL;
2828

2929
import org.graalvm.collections.EconomicMap;
30+
import org.graalvm.nativeimage.ImageSingletons;
3031

3132
import com.oracle.svm.core.SubstrateOptions;
3233
import com.oracle.svm.core.option.HostedOptionKey;
@@ -36,6 +37,7 @@
3637
import jdk.graal.compiler.api.replacements.Fold;
3738
import jdk.graal.compiler.options.Option;
3839
import jdk.graal.compiler.options.OptionKey;
40+
import jdk.vm.ci.meta.ResolvedJavaType;
3941

4042
public class RuntimeClassLoading {
4143
public static final class Options {
@@ -64,4 +66,8 @@ private static void validate(HostedOptionKey<Boolean> optionKey) {
6466
public static boolean isSupported() {
6567
return Options.SupportRuntimeClassLoading.getValue();
6668
}
69+
70+
public static ResolvedJavaType createInterpreterType(DynamicHub hub, ResolvedJavaType analysisType) {
71+
return ImageSingletons.lookup(CremaSupport.class).createInterpreterType(hub, analysisType);
72+
}
6773
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/analysis/DynamicHubInitializer.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.oracle.svm.core.classinitialization.ClassInitializationInfo;
4646
import com.oracle.svm.core.hub.DynamicHub;
4747
import com.oracle.svm.core.hub.DynamicHubCompanion;
48+
import com.oracle.svm.core.hub.RuntimeClassLoading;
4849
import com.oracle.svm.core.meta.MethodPointer;
4950
import com.oracle.svm.core.util.VMError;
5051
import com.oracle.svm.hosted.BootLoaderSupport;
@@ -75,6 +76,7 @@ public class DynamicHubInitializer {
7576
private final Field hubCompanionClassInitializationInfo;
7677
private final Field hubCompanionInterfacesEncoding;
7778
private final Field hubCompanionAnnotationsEnumConstantsReference;
79+
private final Field hubCompanionInterpreterType;
7880

7981
public DynamicHubInitializer(BigBang bb) {
8082
this.bb = bb;
@@ -88,6 +90,7 @@ public DynamicHubInitializer(BigBang bb) {
8890
hubCompanionClassInitializationInfo = ReflectionUtil.lookupField(DynamicHubCompanion.class, "classInitializationInfo");
8991
hubCompanionInterfacesEncoding = ReflectionUtil.lookupField(DynamicHubCompanion.class, "interfacesEncoding");
9092
hubCompanionAnnotationsEnumConstantsReference = ReflectionUtil.lookupField(DynamicHubCompanion.class, "enumConstantsReference");
93+
hubCompanionInterpreterType = ReflectionUtil.lookupField(DynamicHubCompanion.class, "interpreterType");
9194
}
9295

9396
public void initializeMetaData(ImageHeapScanner heapScanner, AnalysisType type) {
@@ -145,6 +148,11 @@ public void initializeMetaData(ImageHeapScanner heapScanner, AnalysisType type)
145148
}
146149
}
147150
}
151+
152+
if (RuntimeClassLoading.isSupported()) {
153+
hub.setInterpreterType(RuntimeClassLoading.createInterpreterType(hub, type));
154+
heapScanner.rescanField(hub.getCompanion(), hubCompanionInterpreterType);
155+
}
148156
}
149157

150158
/**

substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaType.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
* closed world e.g. instantiable, instantiated, effectively final ...
4646
*/
4747
public abstract class InterpreterResolvedJavaType implements ResolvedJavaType {
48+
public static final ResolvedJavaMethod[] NO_METHODS = new ResolvedJavaMethod[0];
4849

4950
private final String name;
5051
private final Class<?> clazz;
@@ -260,8 +261,8 @@ public final ResolvedJavaMethod[] getDeclaredConstructors() {
260261
}
261262

262263
@Override
263-
public final ResolvedJavaMethod[] getDeclaredMethods() {
264-
throw VMError.intentionallyUnimplemented();
264+
public ResolvedJavaMethod[] getDeclaredMethods() {
265+
return NO_METHODS;
265266
}
266267

267268
@Override

substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedObjectType.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,20 @@
2424
*/
2525
package com.oracle.svm.interpreter.metadata;
2626

27+
import static com.oracle.svm.core.BuildPhaseProvider.AfterAnalysis;
28+
2729
import org.graalvm.nativeimage.Platform;
2830
import org.graalvm.nativeimage.Platforms;
2931
import org.graalvm.word.WordBase;
3032

33+
import com.oracle.svm.core.heap.UnknownObjectField;
3134
import com.oracle.svm.core.hub.DynamicHub;
3235
import com.oracle.svm.core.util.VMError;
3336
import com.oracle.svm.interpreter.metadata.serialization.VisibleForSerialization;
3437

3538
import jdk.vm.ci.meta.JavaConstant;
3639
import jdk.vm.ci.meta.JavaKind;
40+
import jdk.vm.ci.meta.ResolvedJavaMethod;
3741
import jdk.vm.ci.meta.ResolvedJavaType;
3842

3943
public final class InterpreterResolvedObjectType extends InterpreterResolvedJavaType {
@@ -42,6 +46,7 @@ public final class InterpreterResolvedObjectType extends InterpreterResolvedJava
4246
private final int modifiers;
4347
private final InterpreterResolvedObjectType superclass;
4448
private final InterpreterResolvedObjectType[] interfaces;
49+
private InterpreterResolvedJavaMethod[] declaredMethods;
4550

4651
// Populated after analysis.
4752
private InterpreterConstantPool constantPool;
@@ -51,7 +56,9 @@ public final class InterpreterResolvedObjectType extends InterpreterResolvedJava
5156
private final String sourceFileName;
5257

5358
public static class VTableHolder {
59+
@UnknownObjectField(availability = AfterAnalysis.class) //
5460
public InterpreterResolvedObjectType holder;
61+
@UnknownObjectField(availability = AfterAnalysis.class) //
5562
public InterpreterResolvedJavaMethod[] vtable;
5663

5764
public VTableHolder(InterpreterResolvedObjectType holder, InterpreterResolvedJavaMethod[] vtable) {
@@ -60,6 +67,7 @@ public VTableHolder(InterpreterResolvedObjectType holder, InterpreterResolvedJav
6067
}
6168
}
6269

70+
@UnknownObjectField(availability = AfterAnalysis.class) //
6371
private VTableHolder vtableHolder = null;
6472

6573
// Debugger side constructor, class is an opaque JavaConstant.
@@ -210,7 +218,6 @@ public InterpreterResolvedJavaMethod[] getVtable() {
210218
}
211219

212220
public void setVtable(InterpreterResolvedJavaMethod[] vtable) {
213-
VMError.guarantee(vtableHolder == null);
214221
this.vtableHolder = new VTableHolder(this, vtable);
215222
}
216223

@@ -219,4 +226,13 @@ public VTableHolder getVtableHolder() {
219226
assert !isArray();
220227
return vtableHolder;
221228
}
229+
230+
@Override
231+
public ResolvedJavaMethod[] getDeclaredMethods() {
232+
return declaredMethods;
233+
}
234+
235+
public void setDeclaredMethods(InterpreterResolvedJavaMethod[] declaredMethods) {
236+
this.declaredMethods = declaredMethods;
237+
}
222238
}

0 commit comments

Comments
 (0)