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 @@ -39,8 +39,8 @@

final class SubstrateReflectionAccessorFactoryJDK11 implements SubstrateReflectionAccessorFactory {
@Override
public SubstrateMethodAccessor createMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer, CFunctionPointer invokeSpecialFunctionPointer) {
return new SubstrateMethodAccessorJDK11(member, invokeFunctionPointer, invokeSpecialFunctionPointer);
public SubstrateMethodAccessor createMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer) {
return new SubstrateMethodAccessorJDK11(member, invokeFunctionPointer);
}

@Override
Expand All @@ -58,8 +58,8 @@ public void afterRegistration(AfterRegistrationAccess access) {
}

final class SubstrateMethodAccessorJDK11 extends SubstrateMethodAccessor implements jdk.internal.reflect.MethodAccessor {
SubstrateMethodAccessorJDK11(Executable member, CFunctionPointer invokeFunctionPointer, CFunctionPointer invokeSpecialFunctionPointer) {
super(member, invokeFunctionPointer, invokeSpecialFunctionPointer);
SubstrateMethodAccessorJDK11(Executable member, CFunctionPointer invokeFunctionPointer) {
super(member, invokeFunctionPointer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@

final class SubstrateReflectionAccessorFactoryJDK8 implements SubstrateReflectionAccessorFactory {
@Override
public SubstrateMethodAccessor createMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer, CFunctionPointer invokeSpecialFunctionPointer) {
return new SubstrateMethodAccessorJDK8(member, invokeFunctionPointer, invokeSpecialFunctionPointer);
public SubstrateMethodAccessor createMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer) {
return new SubstrateMethodAccessorJDK8(member, invokeFunctionPointer);
}

@Override
Expand All @@ -58,8 +58,8 @@ public void afterRegistration(AfterRegistrationAccess access) {
}

final class SubstrateMethodAccessorJDK8 extends SubstrateMethodAccessor implements sun.reflect.MethodAccessor {
SubstrateMethodAccessorJDK8(Executable member, CFunctionPointer invokeFunctionPointer, CFunctionPointer invokeSpecialFunctionPointer) {
super(member, invokeFunctionPointer, invokeSpecialFunctionPointer);
SubstrateMethodAccessorJDK8(Executable member, CFunctionPointer invokeFunctionPointer) {
super(member, invokeFunctionPointer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.calc.NarrowNode;
import org.graalvm.compiler.nodes.extended.BoxNode;
import org.graalvm.compiler.nodes.extended.GuardingNode;
import org.graalvm.compiler.nodes.extended.StateSplitProxyNode;
import org.graalvm.compiler.nodes.extended.UnboxNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration;
Expand Down Expand Up @@ -84,7 +85,6 @@
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
Expand Down Expand Up @@ -148,8 +148,8 @@ public LoadFieldNode createLoadField(ValueNode object, ResolvedJavaField field)
return append(LoadFieldNode.create(null, object, field));
}

public ValueNode createLoadIndexed(ValueNode array, int index, JavaKind kind) {
ValueNode loadIndexed = LoadIndexedNode.create(null, array, ConstantNode.forInt(index, getGraph()), null, kind, getMetaAccess(), getConstantReflection());
public ValueNode createLoadIndexed(ValueNode array, int index, JavaKind kind, GuardingNode boundsCheck) {
ValueNode loadIndexed = LoadIndexedNode.create(null, array, ConstantNode.forInt(index, getGraph()), boundsCheck, kind, getMetaAccess(), getConstantReflection());
if (loadIndexed instanceof FixedNode) {
return append((FixedNode) loadIndexed);
}
Expand All @@ -160,8 +160,8 @@ public ValueNode createStoreIndexed(ValueNode array, int index, JavaKind kind, V
return append(new StoreIndexedNode(array, ConstantNode.forInt(index, getGraph()), null, null, kind, value));
}

public ValueNode createUnboxing(ValueNode boxed, JavaKind targetKind, MetaAccessProvider metaAccess) {
return append(new UnboxNode(boxed, targetKind, metaAccess));
public ValueNode createUnboxing(ValueNode boxed, JavaKind targetKind) {
return append(new UnboxNode(boxed, targetKind, getMetaAccess()));
}

public ValueNode createInvokeWithExceptionAndUnwind(Class<?> declaringClass, String name, InvokeKind invokeKind, ValueNode... args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
import com.oracle.svm.core.SubstrateOptions;
import com.oracle.svm.core.annotate.AlwaysInline;

import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
// Checkstyle: stop
import sun.invoke.util.Wrapper;
// Checkstyle: resume
Expand Down Expand Up @@ -133,18 +131,6 @@ public static short shortUnbox(Object retVal, Class<?> returnType) {
}
}

public static ResolvedJavaMethod getThrowUnsupportedOperationException(MetaAccessProvider metaAccess) {
try {
return metaAccess.lookupJavaMethod(MethodHandleUtils.class.getMethod("throwUnsupportedOperationException"));
} catch (NoSuchMethodException e) {
throw shouldNotReachHere();
}
}

public static void throwUnsupportedOperationException() {
throw new UnsupportedOperationException("MethodHandle.invoke() and MethodHandle.invokeExact() cannot be invoked through reflection");
}

public static class MethodHandlesSupported implements BooleanSupplier {
@Override
public boolean getAsBoolean() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@
*/
package com.oracle.svm.core.reflect;

// Checkstyle: allow reflection

import java.lang.reflect.InvocationTargetException;

import com.oracle.svm.core.annotate.NeverInline;
import com.oracle.svm.core.jdk.InternalVMMethod;
import com.oracle.svm.core.reflect.SubstrateConstructorAccessor.ConstructorNewInstanceFunctionPointer;
import com.oracle.svm.core.reflect.SubstrateMethodAccessor.MethodInvokeFunctionPointer;
import com.oracle.svm.core.util.VMError;

/**
Expand All @@ -37,28 +44,76 @@
public final class ReflectionAccessorHolder {

/**
* Signature prototype for invoking a method via a {@link SubstrateMethodAccessor}.
* Signature prototype for invoking a method via a {@link SubstrateMethodAccessor}. Must match
* the signature of {@link MethodInvokeFunctionPointer#invoke}
*/
private static Object invokePrototype(Object obj, Object[] args) {
static Object invokePrototype(boolean invokeSpecial, Object obj, Object[] args) {
throw VMError.shouldNotReachHere("Only used as a prototype for generated methods");
}

/**
* Signature prototype for allocating a new instance via a {@link SubstrateConstructorAccessor}.
* Must match * the signature of {@link ConstructorNewInstanceFunctionPointer#invoke}
*/
private static Object newInstancePrototype(Object[] args) {
static Object newInstancePrototype(Object[] args) {
throw VMError.shouldNotReachHere("Only used as a prototype for generated methods");
}

/*
* Methods for throwing exceptions when a method or constructor is used in an illegal way.
* Methods for throwing exceptions when a method or constructor is used in an illegal way. These
* methods are invoked via function pointers, so must have the same signature as the prototypes
* above.
*/

private static Object invokeSpecialError(Object obj, Object[] args) {
throw new IllegalArgumentException("Static or abstract method cannot be invoked using invokeSpecial");
private static void methodHandleInvokeError(boolean invokeSpecial, Object obj, Object[] args) throws InvocationTargetException {
/* The nested exceptions are required by the specification. */
throw new InvocationTargetException(new UnsupportedOperationException("MethodHandle.invoke() and MethodHandle.invokeExact() cannot be invoked through reflection"));
}

private static Object newInstanceError(Object[] args) throws InstantiationException {
throw new InstantiationException("Only non-abstract instance classes can be instantiated using reflection");
}

/*
* Methods for throwing exceptions from within the generated Graal IR. The signature depends on
* the call site, i.e., it does not need to be the prototype signature.
*/

@NeverInline("Exception slow path")
private static InvocationTargetException throwInvocationTargetException(Throwable target) throws InvocationTargetException {
throw new InvocationTargetException(target);
}

@NeverInline("Exception slow path")
private static void throwIllegalArgumentExceptionForMethod(Object member, Object obj, Object[] args) {
throwIllegalArgumentException(member, false, obj, args);
}

@NeverInline("Exception slow path")
private static void throwIllegalArgumentExceptionForConstructor(Object member, Object[] args) {
throwIllegalArgumentException(member, true, null, args);
}

/**
* We do not know which check in the generated metod caused the exception, so we cannot print
* detailed information about that. But printing the signature of the method and all the types
* of the actual arguments should make it obvious what the problem is.
*/
private static void throwIllegalArgumentException(Object member, boolean constructor, Object obj, Object[] args) {
String sep = System.lineSeparator();
StringBuilder msg = new StringBuilder();
msg.append("Illegal arguments for invoking ").append(member);
if (!constructor) {
msg.append(sep).append(" obj: ").append(obj == null ? "null" : obj.getClass().getTypeName());
}
if (args == null) {
msg.append(sep).append(" args: null");
} else {
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
msg.append(sep).append(" args[").append(i).append("]: ").append(arg == null ? "null" : arg.getClass().getTypeName());
}
}
throw new IllegalArgumentException(msg.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
public abstract class SubstrateConstructorAccessor {

interface ConstructorNewInstanceFunctionPointer extends CFunctionPointer {
/** Must match the signature of {@link ReflectionAccessorHolder#newInstancePrototype}. */
@InvokeJavaFunctionPointer
Object invoke(Object[] args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,41 +38,36 @@
public abstract class SubstrateMethodAccessor {

interface MethodInvokeFunctionPointer extends CFunctionPointer {
/** Must match the signature of {@link ReflectionAccessorHolder#invokePrototype}. */
@InvokeJavaFunctionPointer
Object invoke(Object obj, Object[] args);
Object invoke(boolean invokeSpecial, Object obj, Object[] args);
}

private final Executable member;
private final CFunctionPointer invokeFunctionPointer;
private final CFunctionPointer invokeSpecialFunctionPointer;

protected SubstrateMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer, CFunctionPointer invokeSpecialFunctionPointer) {
protected SubstrateMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer) {
this.member = member;
this.invokeFunctionPointer = invokeFunctionPointer;
this.invokeSpecialFunctionPointer = invokeSpecialFunctionPointer;
}

public Object invoke(Object obj, Object[] args) {
MethodInvokeFunctionPointer functionPointer = (MethodInvokeFunctionPointer) this.invokeFunctionPointer;
if (functionPointer.isNull()) {
throw invokeError();
}
return functionPointer.invoke(obj, args);
return functionPointer.invoke(false, obj, args);
}

private RuntimeException invokeError() {
throw VMError.shouldNotReachHere("No SubstrateMethodAccessor.invokeFunctionPointer for " + member);
}

public Object invokeSpecial(Object obj, Object[] args) {
MethodInvokeFunctionPointer functionPointer = (MethodInvokeFunctionPointer) this.invokeSpecialFunctionPointer;
MethodInvokeFunctionPointer functionPointer = (MethodInvokeFunctionPointer) this.invokeFunctionPointer;
if (functionPointer.isNull()) {
throw invokeSpecialError();
throw invokeError();
}
return functionPointer.invoke(obj, args);
}

private RuntimeException invokeSpecialError() {
throw VMError.shouldNotReachHere("No SubstrateMethodAccessor.invokeSpecialFunctionPointer for " + member);
return functionPointer.invoke(true, obj, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import org.graalvm.nativeimage.c.function.CFunctionPointer;

public interface SubstrateReflectionAccessorFactory {
SubstrateMethodAccessor createMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer, CFunctionPointer invokeSpecialFunctionPointer);
SubstrateMethodAccessor createMethodAccessor(Executable member, CFunctionPointer invokeFunctionPointer);

SubstrateConstructorAccessor createConstructorAccessor(Executable member, CFunctionPointer newInstanceFunctionPointer);
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,8 @@
import com.oracle.svm.core.c.BoxedRelocatedPointer;
import com.oracle.svm.core.classinitialization.EnsureClassInitializedNode;
import com.oracle.svm.core.graal.code.SubstrateCompilationIdentifier;
import com.oracle.svm.core.graal.nodes.LoweredDeadEndNode;
import com.oracle.svm.core.graal.replacements.SubstrateGraphKit;
import com.oracle.svm.core.nodes.SubstrateMethodCallTargetNode;
import com.oracle.svm.core.util.ExceptionHelpers;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.hosted.meta.HostedMethod;

Expand Down Expand Up @@ -115,12 +113,6 @@ public <T extends WithExceptionNode> T appendWithUnwind(T withExceptionNode) {
return appendWithUnwind(withExceptionNode, bci());
}

public void throwInvocationTargetException(ValueNode exception) {
ResolvedJavaMethod throwInvocationTargetException = findMethod(ExceptionHelpers.class, "throwInvocationTargetException", true);
createJavaCallWithExceptionAndUnwind(InvokeKind.Static, throwInvocationTargetException, exception);
append(new LoweredDeadEndNode());
}

public LoadFieldNode createLoadFieldNode(ConstantNode receiver, Class<BoxedRelocatedPointer> clazz, String fieldName) {
try {
ResolvedJavaType type = getMetaAccess().lookupJavaType(clazz);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method,
retVal = kit.createInvokeWithExceptionAndUnwind(unboxMethod, CallTargetNode.InvokeKind.Static, kit.getFrameState(), kit.bci(), retVal, methodHandleOrMemberName);
break;
default:
retVal = kit.createUnboxing(invoke, returnKind, metaAccess);
retVal = kit.createUnboxing(invoke, returnKind);
}
}
kit.createReturn(retVal, returnKind);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import com.oracle.svm.core.heap.Heap;
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
import com.oracle.svm.core.threadlocal.FastThreadLocalObject;
import com.oracle.svm.core.util.ExceptionHelpers;
import com.oracle.svm.jni.nativeapi.JNIObjectHandle;
import com.oracle.svm.jni.nativeapi.JNIObjectRefType;

Expand Down Expand Up @@ -141,7 +140,12 @@ public static <T> T getObject(JNIObjectHandle handle) {
return JNIGlobalHandles.getObject(handle);
}

throw ExceptionHelpers.throwIllegalArgumentException("Invalid object handle");
throw throwIllegalArgumentException();
}

@NeverInline("Exception slow path")
private static IllegalArgumentException throwIllegalArgumentException() {
throw new IllegalArgumentException("Invalid object handle");
}

public static JNIObjectRefType getHandleType(JNIObjectHandle handle) {
Expand Down
Loading