Skip to content

Commit ea7c7f9

Browse files
author
Christian Wimmer
committed
Only allow Unsafe allocation for types registered explicitly in the configuration
1 parent a25a7b6 commit ea7c7f9

File tree

28 files changed

+173
-44
lines changed

28 files changed

+173
-44
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,9 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Rec
525525
* NewInstanceNode.
526526
*/
527527
if (b.currentBlockCatchesOOM()) {
528-
DynamicNewInstanceWithExceptionNode.createAndPush(b, clazz);
528+
DynamicNewInstanceWithExceptionNode.createAndPush(b, clazz, true);
529529
} else {
530-
DynamicNewInstanceNode.createAndPush(b, clazz);
530+
DynamicNewInstanceNode.createAndPush(b, clazz, true);
531531
}
532532
return true;
533533
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/java/DynamicNewInstanceNode.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import jdk.graal.compiler.nodes.spi.Canonicalizable;
4040
import jdk.graal.compiler.nodes.spi.CanonicalizerTool;
4141
import jdk.graal.compiler.nodes.spi.CoreProviders;
42-
4342
import jdk.vm.ci.meta.JavaKind;
4443
import jdk.vm.ci.meta.MetaAccessProvider;
4544
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -50,12 +49,12 @@ public final class DynamicNewInstanceNode extends AbstractNewObjectNode implemen
5049

5150
@Input ValueNode clazz;
5251

53-
public static void createAndPush(GraphBuilderContext b, ValueNode clazz) {
52+
public static void createAndPush(GraphBuilderContext b, ValueNode clazz, boolean validateClass) {
5453
ResolvedJavaType constantType = tryConvertToNonDynamic(clazz, b);
5554
if (constantType != null) {
5655
b.addPush(JavaKind.Object, new NewInstanceNode(constantType, true));
5756
} else {
58-
ValueNode clazzLegal = b.add(new ValidateNewInstanceClassNode(clazz));
57+
ValueNode clazzLegal = validateClass ? b.add(new ValidateNewInstanceClassNode(clazz)) : clazz;
5958
b.addPush(JavaKind.Object, new DynamicNewInstanceNode(clazzLegal, true));
6059
}
6160
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/java/DynamicNewInstanceWithExceptionNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ public class DynamicNewInstanceWithExceptionNode extends AllocateWithExceptionNo
4848
public static final NodeClass<DynamicNewInstanceWithExceptionNode> TYPE = NodeClass.create(DynamicNewInstanceWithExceptionNode.class);
4949
protected boolean fillContents;
5050

51-
public static void createAndPush(GraphBuilderContext b, ValueNode clazz) {
51+
public static void createAndPush(GraphBuilderContext b, ValueNode clazz, boolean validateClass) {
5252
ResolvedJavaType constantType = tryConvertToNonDynamic(clazz, b);
5353
if (constantType != null) {
5454
b.addPush(JavaKind.Object, new NewInstanceWithExceptionNode(constantType, true));
5555
} else {
56-
ValueNode clazzLegal = b.add(new ValidateNewInstanceClassNode(clazz));
56+
ValueNode clazzLegal = validateClass ? b.add(new ValidateNewInstanceClassNode(clazz)) : clazz;
5757
b.addPush(JavaKind.Object, new DynamicNewInstanceWithExceptionNode(clazzLegal, true));
5858
}
5959
}

sdk/src/org.graalvm.nativeimage/snapshot.sigtest

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ meth public abstract !varargs void registerReachabilityHandler(java.util.functio
10011001
meth public abstract void registerAsAccessed(java.lang.reflect.Field)
10021002
meth public abstract void registerAsInHeap(java.lang.Class<?>)
10031003
meth public abstract void registerAsUnsafeAccessed(java.lang.reflect.Field)
1004+
meth public abstract void registerAsUnsafeAllocated(java.lang.Class<?>)
10041005
meth public abstract void registerAsUsed(java.lang.Class<?>)
10051006
meth public abstract void registerClassInitializerReachabilityHandler(java.util.function.Consumer<org.graalvm.nativeimage.hosted.Feature$DuringAnalysisAccess>,java.lang.Class<?>)
10061007
meth public abstract void registerFieldValueTransformer(java.lang.reflect.Field,org.graalvm.nativeimage.hosted.FieldValueTransformer)

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/Feature.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -220,6 +220,14 @@ interface BeforeAnalysisAccess extends FeatureAccess {
220220
*/
221221
void registerAsInHeap(Class<?> type);
222222

223+
/**
224+
* Registers the provided type as allocatable without running a constructor, via
225+
* Unsafe.allocateInstance or via the JNI function AllocObject.
226+
*
227+
* @since 24.1
228+
*/
229+
void registerAsUnsafeAllocated(Class<?> type);
230+
223231
/**
224232
* Registers the provided field as accesses, i.e., the static analysis assumes the field is
225233
* used even if there are no explicit reads or writes in the bytecodes.

substratevm/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This changelog summarizes major changes to GraalVM Native Image.
2020
* (GR-52534) Change the digest (used e.g. for symbol names) from SHA-1 encoded as a hex string (40 bytes) to 128-bit Murmur3 as a Base-62 string (22 bytes).
2121
* (GR-52578) Print information about embedded resources into `embedded-resources.json` using the `-H:+GenerateEmbeddedResourcesFile` option.
2222
* (GR-51172) Add support to catch OutOfMemoryError exceptions on native image if there is no memory left.
23+
* (GR-53803) In the strict reflection configuration mode (when `ThrowMissingRegistrationErrors` is enabled), only allow `Unsafe.allocateInstance` for types registered explicitly in the configuration.
2324
* (GR-43837) `--report-unsupported-elements-at-runtime` is now enabled by default and the option is deprecated.
2425

2526
## GraalVM for JDK 22 (Internal Version 24.0.0)

substratevm/src/com.oracle.graal.pointsto.standalone/src/com/oracle/graal/pointsto/standalone/features/StandaloneAnalysisFeatureImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,11 @@ public void registerAsInHeap(AnalysisType aType, Object reason) {
186186
aType.registerAsInstantiated(reason);
187187
}
188188

189+
@Override
190+
public void registerAsUnsafeAllocated(Class<?> type) {
191+
getMetaAccess().lookupJavaType(type).registerAsUnsafeAllocated("registered from Feature API");
192+
}
193+
189194
@Override
190195
public void registerAsAccessed(Field field) {
191196
registerAsAccessed(getMetaAccess().lookupJavaField(field), "registered from Feature API");

substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ public abstract class AnalysisType extends AnalysisElement implements WrappedJav
100100
private static final AtomicReferenceFieldUpdater<AnalysisType, Object> isInstantiatedUpdater = AtomicReferenceFieldUpdater
101101
.newUpdater(AnalysisType.class, Object.class, "isInstantiated");
102102

103+
private static final AtomicReferenceFieldUpdater<AnalysisType, Object> isUnsafeAllocatedUpdater = AtomicReferenceFieldUpdater
104+
.newUpdater(AnalysisType.class, Object.class, "isUnsafeAllocated");
105+
103106
private static final AtomicReferenceFieldUpdater<AnalysisType, Object> isReachableUpdater = AtomicReferenceFieldUpdater
104107
.newUpdater(AnalysisType.class, Object.class, "isReachable");
105108

@@ -112,6 +115,8 @@ public abstract class AnalysisType extends AnalysisElement implements WrappedJav
112115
private final String unqualifiedName;
113116

114117
@SuppressWarnings("unused") private volatile Object isInstantiated;
118+
/** Can be allocated via Unsafe or JNI, i.e., without executing a constructor. */
119+
@SuppressWarnings("unused") private volatile Object isUnsafeAllocated;
115120
@SuppressWarnings("unused") private volatile Object isReachable;
116121
@SuppressWarnings("unused") private volatile int isAnySubtypeInstantiated;
117122
private boolean reachabilityListenerNotified;
@@ -523,6 +528,11 @@ protected void onInstantiated() {
523528
processMethodOverrides();
524529
}
525530

531+
public boolean registerAsUnsafeAllocated(Object reason) {
532+
registerAsInstantiated(reason);
533+
return AtomicUtils.atomicSet(this, reason, isUnsafeAllocatedUpdater);
534+
}
535+
526536
private void processMethodOverrides() {
527537
/*
528538
* Walk up the type hierarchy from this type keeping track of all processed types. For each
@@ -812,6 +822,10 @@ public Object getInstantiatedReason() {
812822
return isInstantiated;
813823
}
814824

825+
public boolean isUnsafeAllocated() {
826+
return AtomicUtils.isSet(this, isUnsafeAllocatedUpdater);
827+
}
828+
815829
/** Returns true if this type or any of its subtypes was marked as instantiated. */
816830
public boolean isAnySubtypeInstantiated() {
817831
return AtomicUtils.isSet(this, isAnySubtypeInstantiatedUpdater);

substratevm/src/com.oracle.svm.agent/src/com/oracle/svm/agent/JniCallInterceptor.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ private static JNIObjectHandle findClass(JNIEnvironment env, CCharPointer name)
143143
return result;
144144
}
145145

146+
@CEntryPoint(name = "AllocObject")
147+
@CEntryPointOptions(prologue = AgentIsolate.Prologue.class)
148+
static JNIObjectHandle allocObject(JNIEnvironment env, JNIObjectHandle clazz) {
149+
InterceptedState state = initInterceptedState();
150+
JNIObjectHandle callerClass = getCallerClass(state, env);
151+
JNIObjectHandle result = jniFunctions().getAllocObject().invoke(env, clazz);
152+
if (nullHandle().equal(result) || clearException(env)) {
153+
result = nullHandle();
154+
}
155+
if (shouldTrace()) {
156+
traceCall(env, "AllocObject", clazz, nullHandle(), callerClass, result.notEqual(nullHandle()), state);
157+
}
158+
return result;
159+
160+
}
161+
146162
@CEntryPoint(name = "GetMethodID")
147163
@CEntryPointOptions(prologue = AgentIsolate.Prologue.class)
148164
private static JNIMethodId getMethodID(JNIEnvironment env, JNIObjectHandle clazz, CCharPointer name, CCharPointer signature) {
@@ -316,6 +332,7 @@ public static void onVMStart(JvmtiEnv jvmti) {
316332
JNINativeInterface functions = functionsPtr.read();
317333
functions.setDefineClass(defineClassLiteral.getFunctionPointer());
318334
functions.setFindClass(findClassLiteral.getFunctionPointer());
335+
functions.setAllocObject(allocObjectLiteral.getFunctionPointer());
319336
functions.setGetMethodID(getMethodIDLiteral.getFunctionPointer());
320337
functions.setGetStaticMethodID(getStaticMethodIDLiteral.getFunctionPointer());
321338
functions.setGetFieldID(getFieldIDLiteral.getFunctionPointer());
@@ -342,6 +359,9 @@ public static void onUnload() {
342359
private static final CEntryPointLiteral<FindClassFunctionPointer> findClassLiteral = CEntryPointLiteral.create(JniCallInterceptor.class,
343360
"findClass", JNIEnvironment.class, CCharPointer.class);
344361

362+
private static final CEntryPointLiteral<FindClassFunctionPointer> allocObjectLiteral = CEntryPointLiteral.create(JniCallInterceptor.class,
363+
"allocObject", JNIEnvironment.class, JNIObjectHandle.class);
364+
345365
private static final CEntryPointLiteral<GetMethodIDFunctionPointer> getMethodIDLiteral = CEntryPointLiteral.create(JniCallInterceptor.class,
346366
"getMethodID", JNIEnvironment.class, JNIObjectHandle.class, CCharPointer.class, CCharPointer.class);
347367

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/JniProcessor.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ void processEntry(EconomicMap<String, ?> entry, ConfigurationSet configurationSe
8282
ConfigurationMemberDeclaration declaration = (declaringClass != null) ? ConfigurationMemberDeclaration.DECLARED : ConfigurationMemberDeclaration.PRESENT;
8383
TypeConfiguration config = configurationSet.getJniConfiguration();
8484
switch (function) {
85+
case "AllocObject":
86+
expectSize(args, 0);
87+
/*
88+
* AllocObject is implemented via Unsafe.allocateInstance, so we need to set the
89+
* "unsafe allocated" flag in the reflection configuration file.
90+
*/
91+
configurationSet.getReflectionConfiguration().getOrCreateType(condition, clazz).setUnsafeAllocated();
92+
break;
8593
case "GetStaticMethodID":
8694
case "GetMethodID": {
8795
expectSize(args, 2);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/MissingRegistrationSupport.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@
2424
*/
2525
package com.oracle.svm.core;
2626

27-
import jdk.graal.compiler.api.replacements.Fold;
2827
import org.graalvm.nativeimage.ImageSingletons;
2928
import org.graalvm.nativeimage.Platform;
3029
import org.graalvm.nativeimage.Platforms;
3130

3231
import com.oracle.svm.core.option.OptionClassFilter;
3332

33+
import jdk.graal.compiler.api.replacements.Fold;
34+
3435
public class MissingRegistrationSupport {
3536
private final OptionClassFilter classFilter;
3637

@@ -48,7 +49,11 @@ public boolean reportMissingRegistrationErrors(StackTraceElement responsibleClas
4849
return reportMissingRegistrationErrors(responsibleClass.getModuleName(), getPackageName(responsibleClass.getClassName()), responsibleClass.getClassName());
4950
}
5051

51-
public boolean reportMissingRegistrationErrors(String moduleName, String packageName, String className) {
52+
public boolean reportMissingRegistrationErrors(Class<?> clazz) {
53+
return reportMissingRegistrationErrors(clazz.getModule().getName(), clazz.getPackageName(), clazz.getName());
54+
}
55+
56+
private boolean reportMissingRegistrationErrors(String moduleName, String packageName, String className) {
5257
return classFilter.isIncluded(moduleName, packageName, className) != null;
5358
}
5459

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/SubstrateOptions.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,4 +1174,8 @@ public static class TruffleStableOptions {
11741174
@Option(help = "Reduce the amount of metadata in the image for implicit exceptions by removing inlining information from the stack trace. " +
11751175
"This makes the image smaller, but also the stack trace of implicit exceptions less precise.", type = OptionType.Expert)//
11761176
public static final HostedOptionKey<Boolean> ReduceImplicitExceptionStackTraceInformation = new HostedOptionKey<>(false);
1177+
1178+
@Option(help = "Allow all instantiated types to be allocated via Unsafe.allocateInstance().", type = OptionType.Expert, //
1179+
deprecated = true, deprecationMessage = "ThrowMissingRegistrationErrors is the preferred way of configuring this on a per-type level.") //
1180+
public static final HostedOptionKey<Boolean> AllowUnsafeAllocationOfAllInstantiatedTypes = new HostedOptionKey<>(null);
11771181
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/deopt/Deoptimizer.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@
8989
import jdk.graal.compiler.options.Option;
9090
import jdk.graal.compiler.word.BarrieredAccess;
9191
import jdk.graal.compiler.word.Word;
92-
import jdk.internal.misc.Unsafe;
9392
import jdk.vm.ci.code.InstalledCode;
9493
import jdk.vm.ci.meta.DeoptimizationAction;
9594
import jdk.vm.ci.meta.DeoptimizationReason;
@@ -1040,11 +1039,7 @@ private Object materializeObject(int virtualObjectId, FrameInfoQueryResult sourc
10401039
if (!LayoutEncoding.isPureInstance(layoutEncoding)) {
10411040
throw fatalDeoptimizationError("Non-pure instance layout encoding: " + layoutEncoding, sourceFrame);
10421041
}
1043-
try {
1044-
obj = Unsafe.getUnsafe().allocateInstance(DynamicHub.toClass(hub));
1045-
} catch (InstantiationException ex) {
1046-
throw fatalDeoptimizationError("Instantiation exception: " + ex, sourceFrame);
1047-
}
1042+
obj = KnownIntrinsics.unvalidatedAllocateInstance(DynamicHub.toClass(hub));
10481043
curOffset = WordFactory.unsigned(objectLayout.getFirstFieldOffset());
10491044
curIdx = 1;
10501045
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/jdk/SubstrateObjectCloneSnippets.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@
8080
import jdk.graal.compiler.replacements.nodes.ObjectClone;
8181
import jdk.graal.compiler.word.BarrieredAccess;
8282
import jdk.graal.compiler.word.ObjectAccess;
83-
import jdk.internal.misc.Unsafe;
8483
import jdk.vm.ci.meta.ResolvedJavaType;
8584

8685
public final class SubstrateObjectCloneSnippets extends SubstrateTemplates implements Snippets {
@@ -92,7 +91,7 @@ public static void registerForeignCalls(SubstrateForeignCallsProvider foreignCal
9291
}
9392

9493
@SubstrateForeignCallTarget(stubCallingConvention = false)
95-
private static Object doClone(Object original) throws CloneNotSupportedException, InstantiationException {
94+
private static Object doClone(Object original) throws CloneNotSupportedException {
9695
if (original == null) {
9796
throw new NullPointerException();
9897
} else if (!(original instanceof Cloneable)) {
@@ -122,7 +121,7 @@ private static Object doClone(Object original) throws CloneNotSupportedException
122121
throw VMError.shouldNotReachHere("Hybrid classes do not support Object.clone().");
123122
}
124123
} else {
125-
result = Unsafe.getUnsafe().allocateInstance(DynamicHub.toClass(hub));
124+
result = KnownIntrinsics.unvalidatedAllocateInstance(DynamicHub.toClass(hub));
126125
}
127126

128127
int firstFieldOffset = ConfigurationValues.getObjectLayout().getFirstFieldOffset();

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/graal/snippets/SubstrateAllocationSnippets.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ protected Object newmultiarray(DynamicHub hub, @ConstantParameter int rank, @Con
272272
public DynamicHub validateNewInstanceClass(DynamicHub hub) {
273273
if (probability(EXTREMELY_FAST_PATH_PROBABILITY, hub != null)) {
274274
DynamicHub nonNullHub = (DynamicHub) PiNode.piCastNonNull(hub, SnippetAnchorNode.anchor());
275-
if (probability(EXTREMELY_FAST_PATH_PROBABILITY, nonNullHub.canInstantiateAsInstance())) {
275+
if (probability(EXTREMELY_FAST_PATH_PROBABILITY, nonNullHub.canUnsafeInstantiateAsInstance())) {
276276
return nonNullHub;
277277
}
278278
}
@@ -317,7 +317,7 @@ private static void instanceHubErrorStub(DynamicHub hub) throws InstantiationExc
317317
throw new NullPointerException("Allocation type is null.");
318318
} else if (!hub.isInstanceClass() || LayoutEncoding.isSpecial(hub.getLayoutEncoding())) {
319319
throw new InstantiationException("Can only allocate instance objects for concrete classes.");
320-
} else if (!hub.isInstantiated()) {
320+
} else if (!hub.canUnsafeInstantiateAsInstance()) {
321321
if (MissingRegistrationUtils.throwMissingRegistrationErrors()) {
322322
MissingReflectionRegistrationUtils.forClass(hub.getTypeName());
323323
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ public final class DynamicHub implements AnnotatedElement, java.lang.reflect.Typ
312312
/** Indicates whether the type has been discovered as instantiated by the static analysis. */
313313
private static final int IS_INSTANTIATED_BIT = 0;
314314
/** Can this class be instantiated as an instance. */
315-
private static final int CAN_INSTANTIATE_AS_INSTANCE_BIT = 1;
315+
private static final int CAN_UNSAFE_INSTANTIATE_AS_INSTANCE_BIT = 1;
316316

317317
private static final int IS_REGISTERED_FOR_SERIALIZATION = 2;
318318

@@ -491,8 +491,8 @@ public void setClassInitializationInfo(ClassInitializationInfo classInitializati
491491

492492
@Platforms(Platform.HOSTED_ONLY.class)
493493
public void setSharedData(int layoutEncoding, int monitorOffset, int identityHashOffset, long referenceMapIndex,
494-
boolean isInstantiated, boolean canInstantiateAsInstance, boolean isRegisteredForSerialization) {
495-
assert !(!isInstantiated && canInstantiateAsInstance);
494+
boolean isInstantiated, boolean canUnsafeInstantiateAsInstance, boolean isRegisteredForSerialization) {
495+
assert !(!isInstantiated && canUnsafeInstantiateAsInstance);
496496
VMError.guarantee(monitorOffset == (char) monitorOffset, "Class %s has an invalid monitor field offset. Most likely, its objects are larger than supported.", name);
497497
VMError.guarantee(identityHashOffset == (char) identityHashOffset, "Class %s has an invalid identity hash code field offset. Most likely, its objects are larger than supported.", name);
498498

@@ -505,7 +505,7 @@ public void setSharedData(int layoutEncoding, int monitorOffset, int identityHas
505505
}
506506
this.referenceMapIndex = (int) referenceMapIndex;
507507
this.additionalFlags = NumUtil.safeToUByte(makeFlag(IS_INSTANTIATED_BIT, isInstantiated) |
508-
makeFlag(CAN_INSTANTIATE_AS_INSTANCE_BIT, canInstantiateAsInstance) |
508+
makeFlag(CAN_UNSAFE_INSTANTIATE_AS_INSTANCE_BIT, canUnsafeInstantiateAsInstance) |
509509
makeFlag(IS_REGISTERED_FOR_SERIALIZATION, isRegisteredForSerialization));
510510
}
511511

@@ -747,8 +747,8 @@ public boolean isInstantiated() {
747747
return isFlagSet(additionalFlags, IS_INSTANTIATED_BIT);
748748
}
749749

750-
public boolean canInstantiateAsInstance() {
751-
return isFlagSet(additionalFlags, CAN_INSTANTIATE_AS_INSTANCE_BIT);
750+
public boolean canUnsafeInstantiateAsInstance() {
751+
return isFlagSet(additionalFlags, CAN_UNSAFE_INSTANTIATE_AS_INSTANCE_BIT);
752752
}
753753

754754
public boolean isProxyClass() {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jni/headers/JNIFunctionPointerTypes.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ public interface FindClassFunctionPointer extends CFunctionPointer {
4545
JNIObjectHandle invoke(JNIEnvironment env, CCharPointer name);
4646
}
4747

48+
public interface AllocObjectFunctionPointer extends CFunctionPointer {
49+
@InvokeCFunctionPointer
50+
JNIObjectHandle invoke(JNIEnvironment env, JNIObjectHandle clazz);
51+
}
52+
4853
public interface GetMethodIDFunctionPointer extends CFunctionPointer {
4954
@InvokeCFunctionPointer
5055
JNIMethodId invoke(JNIEnvironment env, JNIObjectHandle clazz, CCharPointer name, CCharPointer signature);

0 commit comments

Comments
 (0)