src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/graphbuilderconf/MethodSubstitutionPlugin.java
changeset 58877 aec7bf35d6f5
parent 58299 6df94ce3ab2f
--- 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());
+    }
 }