--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java Thu Oct 31 14:23:06 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java Thu Oct 31 16:54:16 2019 -0700
@@ -42,6 +42,7 @@
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* An {@link InvocationPlugin} for a method where the implementation of the method is provided by a
@@ -56,6 +57,8 @@
*/
public final class MethodSubstitutionPlugin implements InvocationPlugin {
+ private InvocationPlugins.Registration registration;
+
private ResolvedJavaMethod cachedSubstitute;
/**
@@ -64,9 +67,14 @@
private final Class<?> declaringClass;
/**
- * The name of the original and substitute method.
+ * The name of the substitute method.
*/
- private final String name;
+ private final String substituteName;
+
+ /**
+ * The name of the original method.
+ */
+ private final String originalName;
/**
* The parameter types of the substitute method.
@@ -81,16 +89,21 @@
* Creates a method substitution plugin.
*
* @param bytecodeProvider used to get the bytecodes to parse for the substitute method
+ * @param originalName the name of the original method
* @param declaringClass the class in which the substitute method is declared
- * @param name the name of the substitute method
+ * @param substituteName the name of the substitute method
* @param parameters the parameter types of the substitute method. If the original method is not
* static, then {@code parameters[0]} must be the {@link Class} value denoting
* {@link InvocationPlugin.Receiver}
*/
- public MethodSubstitutionPlugin(BytecodeProvider bytecodeProvider, Class<?> declaringClass, String name, Type... parameters) {
+ public MethodSubstitutionPlugin(InvocationPlugins.Registration registration, BytecodeProvider bytecodeProvider, String originalName, Class<?> declaringClass, String substituteName,
+ Type... parameters) {
+ assert bytecodeProvider != null : "Requires a non-null methodSubstitutionBytecodeProvider";
+ this.registration = registration;
this.bytecodeProvider = bytecodeProvider;
+ this.originalName = originalName;
this.declaringClass = declaringClass;
- this.name = name;
+ this.substituteName = substituteName;
this.parameters = parameters;
this.originalIsStatic = parameters.length == 0 || parameters[0] != InvocationPlugin.Receiver.class;
}
@@ -144,7 +157,7 @@
* Determines if a given method is the substitute method of this plugin.
*/
private boolean isSubstitute(Method m) {
- if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(name)) {
+ if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(substituteName)) {
if (parameters.length == m.getParameterCount()) {
Class<?>[] mparams = m.getParameterTypes();
int start = 0;
@@ -189,9 +202,6 @@
@Override
public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, InvocationPlugin.Receiver receiver, ValueNode[] argsIncludingReceiver) {
if (IS_IN_NATIVE_IMAGE || (UseEncodedGraphs.getValue(b.getOptions()) && !b.parsingIntrinsic())) {
- if (!IS_IN_NATIVE_IMAGE && UseEncodedGraphs.getValue(b.getOptions())) {
- b.getReplacements().registerMethodSubstitution(this, targetMethod, INLINE_AFTER_PARSING, b.getOptions());
- }
StructuredGraph subst = b.getReplacements().getMethodSubstitution(this,
targetMethod,
INLINE_AFTER_PARSING,
@@ -220,7 +230,27 @@
@Override
public String toString() {
- return String.format("%s[%s.%s(%s)]", getClass().getSimpleName(), declaringClass.getName(), name,
+ return String.format("%s[%s.%s(%s)]", getClass().getSimpleName(), declaringClass.getName(), substituteName,
Arrays.asList(parameters).stream().map(c -> c.getTypeName()).collect(Collectors.joining(", ")));
}
+
+ public String originalMethodAsString() {
+ return String.format("%s.%s(%s)", declaringClass.getName(), substituteName, Arrays.asList(parameters).stream().map(c -> c.getTypeName()).collect(Collectors.joining(", ")));
+ }
+
+ public ResolvedJavaMethod getOriginalMethod(MetaAccessProvider metaAccess) {
+ Class<?> clazz = resolveType(registration.getDeclaringType(), false);
+ if (clazz == null) {
+ throw new GraalError("Can't find original class for " + this + " with class " + registration.getDeclaringType());
+ }
+ ResolvedJavaType type = metaAccess.lookupJavaType(clazz);
+ String argumentsDescriptor = InvocationPlugins.toArgumentDescriptor(originalIsStatic, this.parameters);
+ for (ResolvedJavaMethod declared : type.getDeclaredMethods()) {
+ if (declared.getName().equals(originalName) && declared.isStatic() == originalIsStatic &&
+ declared.getSignature().toMethodDescriptor().startsWith(argumentsDescriptor)) {
+ return declared;
+ }
+ }
+ throw new GraalError("Can't find original method for " + this + " with class " + registration.getDeclaringType());
+ }
}