Implement custom lookup for signature polymorphic methods.

Bug: 144339115
Change-Id: I1afc314a9264717619d3f8bdcebbc68474ae3be3
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfo.java b/src/main/java/com/android/tools/r8/graph/AppInfo.java
index 14d41ea..6eb6a94 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -369,25 +369,15 @@
    * Section 5.4.3.3 of the JVM Spec</a>.
    */
   private DexEncodedMethod resolveMethodOnClassStep2(DexClass clazz, DexMethod method) {
-    // Pt. 1: Signature polymorphic method check. Those are only allowed on
-    //        java.lang.invoke.MethodHandle, so we only need to look for it if we are looking at
-    //        that type.
+    // Pt. 1: Signature polymorphic method check.
     // See also <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">
     // Section 2.9 of the JVM Spec</a>.
-    if (clazz.type == dexItemFactory.methodHandleType) {
-      DexMethod signaturePolymorphic = dexItemFactory.createMethod(clazz.type,
-          dexItemFactory.createProto(
-              dexItemFactory.objectType, dexItemFactory.objectArrayType),
-          method.name);
-      DexEncodedMethod result = clazz.lookupMethod(signaturePolymorphic);
-      // Check we found a result and that it has the required access flags for signature polymorphic
-      // functions.
-      if (result != null && result.accessFlags.isNative() && result.accessFlags.isVarargs()) {
-        return result;
-      }
+    DexEncodedMethod result = clazz.lookupSignaturePolymorphicMethod(method.name, dexItemFactory);
+    if (result != null) {
+      return result;
     }
     // Pt 2: Find a method that matches the descriptor.
-    DexEncodedMethod result = clazz.lookupMethod(method);
+    result = clazz.lookupMethod(method);
     if (result != null) {
       return result;
     }
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 0acef70..ccc2eed 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -581,6 +581,38 @@
     return result == null ? lookupVirtualMethod(method) : result;
   }
 
+  public DexEncodedMethod lookupSignaturePolymorphicMethod(
+      DexString methodName, DexItemFactory factory) {
+    if (type != factory.methodHandleType && type != factory.varHandleType) {
+      return null;
+    }
+    DexEncodedMethod matchingName = null;
+    DexEncodedMethod signaturePolymorphicMethod = null;
+    for (DexEncodedMethod method : virtualMethods) {
+      if (method.method.name == methodName) {
+        if (matchingName != null) {
+          // The jvm spec, section 5.4.3.3 details that there must be exactly one method with the
+          // given name only.
+          return null;
+        }
+        matchingName = method;
+        if (isSignaturePolymorphicMethod(method, factory)) {
+          signaturePolymorphicMethod = method;
+        }
+      }
+    }
+    return signaturePolymorphicMethod;
+  }
+
+  private boolean isSignaturePolymorphicMethod(DexEncodedMethod method, DexItemFactory factory) {
+    assert method.method.holder == factory.methodHandleType
+        || method.method.holder == factory.varHandleType;
+    return method.accessFlags.isVarargs()
+        && method.accessFlags.isNative()
+        && method.method.proto.parameters.size() == 1
+        && method.method.proto.parameters.values[0] != factory.objectArrayType;
+  }
+
   private <T extends DexItem, S extends Descriptor<T, S>> T lookupTarget(T[] items, S descriptor) {
     for (T entry : items) {
       if (descriptor.match(entry)) {
diff --git a/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java b/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java
index 02cb585..7d93488 100644
--- a/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java
+++ b/src/main/java/com/android/tools/r8/naming/MinifiedRenaming.java
@@ -98,10 +98,6 @@
     if (renamed != null) {
       return renamed;
     }
-    // TODO(b/144339115): Don't allocate in the item factory during resolution!
-    if (method.holder == appView.dexItemFactory().methodHandleType) {
-      return method.name;
-    }
     // If the method does not have a direct renaming, return the resolutions mapping.
     ResolutionResult resolutionResult = appView.appInfo().resolveMethod(method.holder, method);
     if (resolutionResult.hasSingleTarget()) {