Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
import static jdk.graal.compiler.options.OptionStability.EXPERIMENTAL;

import java.security.ProtectionDomain;
import java.util.function.BooleanSupplier;

import org.graalvm.collections.EconomicMap;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.hub.crema.CremaSupport;
Expand Down Expand Up @@ -122,6 +125,22 @@ public static boolean isSupported() {
return Options.RuntimeClassLoading.getValue();
}

@Platforms(Platform.HOSTED_ONLY.class)
public static final class NoRuntimeClassLoading implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
return !isSupported();
}
}

@Platforms(Platform.HOSTED_ONLY.class)
public static final class WithRuntimeClassLoading implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
return isSupported();
}
}

public static Class<?> defineClass(ClassLoader loader, String expectedName, byte[] b, int off, int len, ClassDefinitionInfo info) {
if (PredefinedClassesSupport.hasBytecodeClasses()) {
Class<?> knownClass = PredefinedClassesSupport.knownClass(b, off, len);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.registry.SymbolsSupport;
import com.oracle.svm.espresso.classfile.ParserKlass;
import com.oracle.svm.espresso.classfile.descriptors.ByteSequence;
import com.oracle.svm.espresso.classfile.descriptors.Symbol;
import com.oracle.svm.espresso.classfile.descriptors.Type;

import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
Expand All @@ -57,17 +61,39 @@ interface CremaDispatchTable {

void fillDynamicHubInfo(DynamicHub hub, CremaDispatchTable table, List<Class<?>> transitiveSuperInterfaces, int[] interfaceIndices);

Object newInstance(ResolvedJavaMethod targetMethod, Object[] args);
/**
* Creates a new instance of {@code type} without running any constructor yet. The caller should
* make sure to run a constructor before publishing the result.
*/
Object rawNewInstance(ResolvedJavaType type);

Object execute(ResolvedJavaMethod targetMethod, Object[] args);

Class<?> toClass(ResolvedJavaType resolvedJavaType);

Class<?> resolveOrThrow(JavaType unresolvedJavaType, ResolvedJavaType accessingClass);
default Class<?> resolveOrThrow(JavaType unresolvedJavaType, ResolvedJavaType accessingClass) {
ByteSequence type = ByteSequence.create(unresolvedJavaType.getName());
Symbol<Type> symbolicType = SymbolsSupport.getTypes().getOrCreateValidType(type);
return resolveOrThrow(symbolicType, accessingClass);
}

Class<?> resolveOrThrow(Symbol<Type> type, ResolvedJavaType accessingClass);

default Class<?> resolveOrNull(JavaType unresolvedJavaType, ResolvedJavaType accessingClass) {
ByteSequence type = ByteSequence.create(unresolvedJavaType.getName());
Symbol<Type> symbolicType = SymbolsSupport.getTypes().getOrCreateValidType(type);
return resolveOrNull(symbolicType, accessingClass);
}

Class<?> resolveOrNull(Symbol<Type> type, ResolvedJavaType accessingClass);

Class<?> resolveOrNull(JavaType unresolvedJavaType, ResolvedJavaType accessingClass);
default Class<?> findLoadedClass(JavaType unresolvedJavaType, ResolvedJavaType accessingClass) {
ByteSequence type = ByteSequence.create(unresolvedJavaType.getName());
Symbol<Type> symbolicType = SymbolsSupport.getTypes().getOrCreateValidType(type);
return findLoadedClass(symbolicType, accessingClass);
}

Class<?> findLoadedClass(JavaType unresolvedJavaType, ResolvedJavaType accessingClass);
Class<?> findLoadedClass(Symbol<Type> type, ResolvedJavaType accessingClass);

Object getStaticStorage(Class<?> cls, boolean primitives, int layerNum);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public static void ensureInitialized() {

public static final class SVMTypes {
public static final Symbol<Type> com_oracle_svm_core_hub_Hybrid = SYMBOLS.putType("Lcom/oracle/svm/core/hub/Hybrid;");
public static final Symbol<Type> java_lang_Throwable = SYMBOLS.putType("Ljava/lang/Throwable;");

private SVMTypes() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
Expand All @@ -48,7 +49,9 @@
import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.RuntimeClassLoading;
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
import com.oracle.svm.core.invoke.Target_java_lang_invoke_MemberName;
import com.oracle.svm.core.layeredimagesingleton.MultiLayeredImageSingleton;
Expand Down Expand Up @@ -215,8 +218,17 @@ public static Target_java_lang_invoke_MemberName resolve(Target_java_lang_invoke
return resolved;
}

@Alias
@TargetElement(onlyWith = RuntimeClassLoading.WithRuntimeClassLoading.class)
public static native MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes);

@Delete
static native MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind, Class<?> defc, String name, Object type);
@TargetElement(onlyWith = RuntimeClassLoading.NoRuntimeClassLoading.class, name = "linkMethodHandleConstant")
static native MethodHandle linkMethodHandleConstantDeleted(Class<?> callerClass, int refKind, Class<?> defc, String name, Object type);

@Alias
@TargetElement(onlyWith = RuntimeClassLoading.WithRuntimeClassLoading.class)
public static native MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind, Class<?> defc, String name, Object type);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,21 @@
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.annotate.TargetElement;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.RuntimeClassLoading;
import com.oracle.svm.core.invoke.Target_java_lang_invoke_MemberName;

@TargetClass(value = MethodHandles.class, innerClass = "Lookup")
final class Target_java_lang_invoke_MethodHandles_Lookup {
// Checkstyle: stop
@Delete //
@TargetElement(onlyWith = RuntimeClassLoading.NoRuntimeClassLoading.class, name = "LOOKASIDE_TABLE") //
static ConcurrentHashMap<Target_java_lang_invoke_MemberName, MethodHandle> LOOKASIDE_TABLE_DELETED;

@Alias //
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClass = ConcurrentHashMap.class)//
@TargetElement(onlyWith = RuntimeClassLoading.WithRuntimeClassLoading.class) //
static ConcurrentHashMap<Target_java_lang_invoke_MemberName, MethodHandle> LOOKASIDE_TABLE;
// Checkstyle: resume

Expand Down Expand Up @@ -87,5 +95,6 @@ private IllegalAccessException makeAccessException(Class<?> targetClass) {
}

@Delete
@TargetElement(onlyWith = RuntimeClassLoading.NoRuntimeClassLoading.class) //
native MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
*/
package com.oracle.svm.core.reflect;

import java.lang.reflect.InvocationTargetException;

import com.oracle.svm.core.hub.crema.CremaSupport;
import com.oracle.svm.core.jdk.InternalVMMethod;

import jdk.internal.reflect.ConstructorAccessor;
import jdk.vm.ci.meta.ResolvedJavaMethod;

import org.graalvm.nativeimage.ImageSingletons;

@InternalVMMethod
public final class CremaConstructorAccessor extends AbstractCremaAccessor implements ConstructorAccessor {

Expand All @@ -40,9 +40,19 @@ public CremaConstructorAccessor(ResolvedJavaMethod targetMethod, Class<?> declar
}

@Override
public Object newInstance(Object[] args) {
public Object newInstance(Object[] args) throws InvocationTargetException {
verifyArguments(args);
ensureDeclaringClassInitialized();
return ImageSingletons.lookup(CremaSupport.class).newInstance(targetMethod, args);

Object newReference = CremaSupport.singleton().rawNewInstance(targetMethod.getDeclaringClass());
Object[] finalArgs = new Object[args.length + 1];
finalArgs[0] = newReference;
System.arraycopy(args, 0, finalArgs, 1, args.length);
try {
CremaSupport.singleton().execute(targetMethod, finalArgs);
} catch (Throwable t) {
throw new InvocationTargetException(t);
}
return newReference;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@
*/
package com.oracle.svm.core.reflect;

import java.lang.reflect.InvocationTargetException;

import com.oracle.svm.core.hub.crema.CremaSupport;
import com.oracle.svm.core.jdk.InternalVMMethod;
import com.oracle.svm.core.util.VMError;

import jdk.internal.reflect.MethodAccessor;

import jdk.vm.ci.meta.ResolvedJavaMethod;

import java.lang.reflect.InvocationTargetException;

@InternalVMMethod
public final class CremaMethodAccessor extends AbstractCremaAccessor implements MethodAccessor {

Expand All @@ -54,7 +53,11 @@ public Object invoke(Object obj, Object[] args) throws IllegalArgumentException,
Object[] finalArgs = new Object[args.length + 1];
finalArgs[0] = obj;
System.arraycopy(args, 0, finalArgs, 1, args.length);
return CremaSupport.singleton().execute(targetMethod, finalArgs);
try {
return CremaSupport.singleton().execute(targetMethod, finalArgs);
} catch (Throwable t) {
throw new InvocationTargetException(t);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,83 @@
*/
package com.oracle.svm.interpreter.metadata;

import java.lang.invoke.VarHandle;

import com.oracle.svm.core.hub.crema.CremaResolvedJavaMethod;
import com.oracle.svm.core.hub.registry.SVMSymbols;
import com.oracle.svm.core.reflect.CremaConstructorAccessor;
import com.oracle.svm.core.reflect.CremaMethodAccessor;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.espresso.classfile.ExceptionHandler;
import com.oracle.svm.espresso.classfile.ParserMethod;
import com.oracle.svm.espresso.classfile.attributes.CodeAttribute;
import com.oracle.svm.espresso.classfile.descriptors.Symbol;
import com.oracle.svm.espresso.classfile.descriptors.Type;

import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;

public final class CremaResolvedJavaMethodImpl extends InterpreterResolvedJavaMethod implements CremaResolvedJavaMethod {
private final ExceptionHandler[] rawExceptionHandlers;

private CremaResolvedJavaMethodImpl(InterpreterResolvedObjectType declaringClass, ParserMethod parserMethod, int vtableIndex) {
super(declaringClass, parserMethod, vtableIndex);
CodeAttribute codeAttribute = (CodeAttribute) parserMethod.getAttribute(CodeAttribute.NAME);
if (codeAttribute != null) {
this.rawExceptionHandlers = codeAttribute.getExceptionHandlers();
} else {
this.rawExceptionHandlers = null;
}
}

public static InterpreterResolvedJavaMethod create(InterpreterResolvedObjectType declaringClass, ParserMethod m, int vtableIndex) {
return new CremaResolvedJavaMethodImpl(declaringClass, m, vtableIndex);
}

@Override
public jdk.vm.ci.meta.ExceptionHandler[] getExceptionHandlers() {
/*
* GR-70247 The interpreter should primarily use classfile.ExceptionHandler. This would
* avoid having to deal with the JavaType which is not needed during interpretation.
*/
jdk.vm.ci.meta.ExceptionHandler[] result = exceptionHandlers;
if (result == null) {
boolean canCache = true;
if (rawExceptionHandlers == null || rawExceptionHandlers.length == 0) {
result = EMPTY_EXCEPTION_HANDLERS;
} else {
result = new jdk.vm.ci.meta.ExceptionHandler[rawExceptionHandlers.length];
InterpreterConstantPool constantPool = getConstantPool();
for (int i = 0; i < rawExceptionHandlers.length; i++) {
ExceptionHandler exceptionHandler = rawExceptionHandlers[i];
Symbol<Type> catchTypeSymbol = exceptionHandler.getCatchType();
int catchTypeCPI = exceptionHandler.catchTypeCPI();
JavaType catchType;
if (SVMSymbols.SVMTypes.java_lang_Throwable.equals(catchTypeSymbol)) {
catchTypeCPI = 0;
catchType = null;
} else if (catchTypeCPI != 0) {
catchType = constantPool.findClassAt(catchTypeCPI);
canCache = canCache && (catchType instanceof ResolvedJavaType);
} else {
assert catchTypeSymbol == null;
catchType = null;
}
result[i] = new jdk.vm.ci.meta.ExceptionHandler(exceptionHandler.getStartBCI(),
exceptionHandler.getEndBCI(),
exceptionHandler.getHandlerBCI(),
catchTypeCPI,
catchType);
}
VarHandle.fullFence();
}
if (canCache) {
this.exceptionHandlers = result;
}
}
return result;
}

@Override
public JavaType[] getDeclaredExceptions() {
// (GR-69097)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,34 @@

import static com.oracle.svm.interpreter.metadata.Bytecodes.INVOKEDYNAMIC;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.util.List;

import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PrimitiveConstant;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.BuildPhaseProvider.AfterAnalysis;
import com.oracle.svm.core.heap.UnknownObjectField;
import com.oracle.svm.core.hub.DynamicHub;
import com.oracle.svm.core.hub.crema.CremaSupport;
import com.oracle.svm.core.hub.registry.SymbolsSupport;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.espresso.classfile.ConstantPool;
import com.oracle.svm.espresso.classfile.ParserConstantPool;
import com.oracle.svm.espresso.classfile.descriptors.ByteSequence;
import com.oracle.svm.espresso.classfile.descriptors.Name;
import com.oracle.svm.espresso.classfile.descriptors.Symbol;
import com.oracle.svm.espresso.classfile.descriptors.Type;
import com.oracle.svm.espresso.classfile.descriptors.TypeSymbols;
import com.oracle.svm.interpreter.metadata.serialization.VisibleForSerialization;

import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaField;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.PrimitiveConstant;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Signature;
import jdk.vm.ci.meta.UnresolvedJavaField;
Expand Down Expand Up @@ -270,6 +280,18 @@ public String resolveStringAt(int cpi) {
return (String) resolvedEntry;
}

public MethodHandle resolvedMethodHandleAt(int cpi, InterpreterResolvedObjectType accessingClass) {
Object resolvedEntry = resolvedAt(cpi, accessingClass);
assert resolvedEntry != null;
return (MethodHandle) resolvedEntry;
}

public MethodType resolvedMethodTypeAt(char cpi, InterpreterResolvedObjectType accessingClass) {
Object resolvedEntry = resolvedAt(cpi, accessingClass);
assert resolvedEntry != null;
return (MethodType) resolvedEntry;
}

@Override
public int intAt(int index) {
checkTag(index, CONSTANT_Integer);
Expand Down Expand Up @@ -317,4 +339,22 @@ public long longAt(int index) {
}
return super.longAt(index);
}

public JavaType findClassAt(int cpi) {
if (peekCachedEntry(cpi) instanceof InterpreterResolvedObjectType type) {
return type;
}
Symbol<Name> nameSymbol = className(cpi);
ByteSequence typeBytes = TypeSymbols.nameToType(nameSymbol);
Symbol<Type> typeSymbol = SymbolsSupport.getTypes().lookupValidType(typeBytes);
if (typeSymbol == null) {
return null;
}
Class<?> cls = CremaSupport.singleton().findLoadedClass(typeSymbol, getHolder());
if (cls == null) {
return UnresolvedJavaType.create(typeBytes.toString());
} else {
return DynamicHub.fromClass(cls).getInterpreterType();
}
}
}
Loading