changeset 13177:74cfcd0fbedf

made method substitution take return types into account (GRAAL-612)
author Doug Simon <doug.simon@oracle.com>
date Tue, 26 Nov 2013 18:43:53 +0100
parents bc868f83bcec
children 5b58f4746286
files graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java
diffstat 1 files changed, 41 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Nov 26 13:35:52 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Nov 26 18:43:53 2013 +0100
@@ -165,8 +165,8 @@
                     throw new GraalInternalError("Substitution method must not be abstract or native: " + substituteMethod);
                 }
                 String originalName = originalName(substituteMethod, methodSubstitution.value());
-                Class[] originalParameters = originalParameters(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic());
-                Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalParameters);
+                JavaSignature originalSignature = originalSignature(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic());
+                Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalSignature);
                 if (originalMethod != null) {
                     ResolvedJavaMethod original = registerMethodSubstitution(originalMethod, substituteMethod);
                     if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) {
@@ -176,8 +176,8 @@
             }
             if (macroSubstitution != null) {
                 String originalName = originalName(substituteMethod, macroSubstitution.value());
-                Class[] originalParameters = originalParameters(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic());
-                Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalParameters);
+                JavaSignature originalSignature = originalSignature(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic());
+                Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalSignature);
                 if (originalMethod != null) {
                     ResolvedJavaMethod original = registerMacroSubstitution(originalMethod, macroSubstitution.macro());
                     if (original != null && macroSubstitution.forced() && shouldIntrinsify(original)) {
@@ -204,7 +204,7 @@
         } else {
             original = metaAccess.lookupJavaConstructor((Constructor) originalMember);
         }
-        Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute));
+        Debug.log("substitution: " + MetaUtil.format("%H.%n(%p) %r", original) + " --> " + MetaUtil.format("%H.%n(%p) %r", substitute));
 
         registeredMethodSubstitutions.put(original, substitute);
         return original;
@@ -507,25 +507,50 @@
         return dimensions == 0 ? baseClass : Array.newInstance(baseClass, new int[dimensions]).getClass();
     }
 
-    private Class[] originalParameters(Method substituteMethod, String methodSubstitution, boolean isStatic) {
+    static class JavaSignature {
+        final Class returnType;
+        final Class[] parameters;
+
+        public JavaSignature(Class returnType, Class[] parameters) {
+            this.parameters = parameters;
+            this.returnType = returnType;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder("(");
+            for (int i = 0; i < parameters.length; i++) {
+                if (i != 0) {
+                    sb.append(", ");
+                }
+                sb.append(parameters[i].getName());
+            }
+            return sb.append(") ").append(returnType.getName()).toString();
+        }
+    }
+
+    private JavaSignature originalSignature(Method substituteMethod, String methodSubstitution, boolean isStatic) {
         Class[] parameters;
+        Class returnType;
         if (methodSubstitution.isEmpty()) {
             parameters = substituteMethod.getParameterTypes();
             if (!isStatic) {
                 assert parameters.length > 0 : "must be a static method with the 'this' object as its first parameter";
                 parameters = Arrays.copyOfRange(parameters, 1, parameters.length);
             }
+            returnType = substituteMethod.getReturnType();
         } else {
             Signature signature = providers.getMetaAccess().parseMethodDescriptor(methodSubstitution);
             parameters = new Class[signature.getParameterCount(false)];
             for (int i = 0; i < parameters.length; i++) {
                 parameters[i] = resolveType(signature.getParameterType(i, null));
             }
+            returnType = resolveType(signature.getReturnType(null));
         }
-        return parameters;
+        return new JavaSignature(returnType, parameters);
     }
 
-    private static Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, Class[] parameters) {
+    private static Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, JavaSignature signature) {
         Class<?> originalClass = classSubstitution.value();
         if (originalClass == ClassSubstitution.class) {
             originalClass = resolveType(classSubstitution.className(), classSubstitution.optional());
@@ -536,9 +561,15 @@
         }
         try {
             if (name.equals("<init>")) {
-                return originalClass.getDeclaredConstructor(parameters);
+                assert signature.returnType.equals(void.class) : signature;
+                Constructor<?> original = originalClass.getDeclaredConstructor(signature.parameters);
+                return original;
             } else {
-                return originalClass.getDeclaredMethod(name, parameters);
+                Method original = originalClass.getDeclaredMethod(name, signature.parameters);
+                if (!original.getReturnType().equals(signature.returnType)) {
+                    throw new NoSuchMethodException(originalClass.getName() + "." + name + signature);
+                }
+                return original;
             }
         } catch (NoSuchMethodException | SecurityException e) {
             if (optional) {