AppInfoWithClassHierarchy: lookup direct
Bug:147578480
Change-Id: I61902e5dc074b16938229632ec83cdb74103a314
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
index a1b5c3c..c858748 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
@@ -66,17 +66,10 @@
* @param method the method to lookup
* @return The actual target for {@code method} or {@code null} if none found.
*/
-
@Deprecated // TODO(b/147578480): Remove
public DexEncodedMethod lookupStaticTarget(DexMethod method, DexType invocationContext) {
assert checkIfObsolete();
- assert invocationContext.isClassType();
- DexClass context = definitionFor(invocationContext);
- if (context == null) {
- return null;
- }
- assert context.isProgramClass();
- return lookupStaticTarget(method, context.asProgramClass());
+ return lookupStaticTarget(method, toProgramClass(invocationContext));
}
public final DexEncodedMethod lookupStaticTarget(
@@ -98,13 +91,7 @@
@Deprecated // TODO(b/147578480): Remove
public DexEncodedMethod lookupSuperTarget(DexMethod method, DexType invocationContext) {
assert checkIfObsolete();
- assert invocationContext.isClassType();
- DexClass context = definitionFor(invocationContext);
- if (context == null) {
- return null;
- }
- assert context.isProgramClass();
- return lookupSuperTarget(method, context.asProgramClass());
+ return lookupSuperTarget(method, toProgramClass(invocationContext));
}
public final DexEncodedMethod lookupSuperTarget(
@@ -112,4 +99,33 @@
assert checkIfObsolete();
return resolveMethod(method.holder, method).lookupInvokeSuperTarget(invocationContext, this);
}
+
+ /**
+ * Lookup direct method following the super chain from the holder of {@code method}.
+ *
+ * <p>This method will lookup private and constructor methods.
+ *
+ * @param method the method to lookup
+ * @return The actual target for {@code method} or {@code null} if none found.
+ */
+ @Deprecated // TODO(b/147578480): Remove
+ public DexEncodedMethod lookupDirectTarget(DexMethod method, DexType invocationContext) {
+ assert checkIfObsolete();
+ return lookupDirectTarget(method, toProgramClass(invocationContext));
+ }
+
+ public DexEncodedMethod lookupDirectTarget(DexMethod method, DexProgramClass invocationContext) {
+ assert checkIfObsolete();
+ return resolveMethod(method.holder, method).lookupInvokeDirectTarget(invocationContext, this);
+ }
+
+ private DexProgramClass toProgramClass(DexType type) {
+ assert type.isClassType();
+ DexClass clazz = definitionFor(type);
+ if (clazz == null) {
+ return null;
+ }
+ assert clazz.isProgramClass();
+ return clazz.asProgramClass();
+ }
}
diff --git a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
index 2b70ca2..7e98588 100644
--- a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
@@ -67,6 +67,10 @@
public abstract DexEncodedMethod lookupInvokeSuperTarget(
DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ /** Lookup the single target of an invoke-direct on this resolution result if possible. */
+ public abstract DexEncodedMethod lookupInvokeDirectTarget(
+ DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+
@Deprecated
public abstract DexEncodedMethod lookupInvokeSuperTarget(DexClass context, AppInfo appInfo);
@@ -219,6 +223,27 @@
return null;
}
+ /**
+ * Lookup direct method following the super chain from the holder of {@code method}.
+ *
+ * <p>This method will lookup private and constructor methods.
+ *
+ * @param context Class the invoke is contained in, i.e., the holder of the caller. * @param
+ * appInfo Application info.
+ * @return The actual target or {@code null} if none found.
+ */
+ @Override
+ public DexEncodedMethod lookupInvokeDirectTarget(
+ DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ if (!isAccessibleFrom(context, appInfo)) {
+ return null;
+ }
+ if (resolvedMethod.isDirectMethod()) {
+ return resolvedMethod;
+ }
+ return null;
+ }
+
@Override
public DexEncodedMethod lookupInvokeSuperTarget(DexClass context, AppInfo appInfo) {
assert context != null;
@@ -441,6 +466,12 @@
}
@Override
+ public DexEncodedMethod lookupInvokeDirectTarget(
+ DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ return null;
+ }
+
+ @Override
public final Set<DexEncodedMethod> lookupVirtualTargets(AppInfoWithSubtyping appInfo) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
index 936757f..29c6b76 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeDirect.java
@@ -125,7 +125,7 @@
DexMethod invokedMethod = getInvokedMethod();
if (appView.appInfo().hasLiveness()) {
AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- return appInfo.lookupDirectTarget(invokedMethod);
+ return appInfo.lookupDirectTarget(invokedMethod, invocationContext);
}
// In D8, we can treat invoke-direct instructions as having a single target if the invoke is
// targeting a method in the enclosing class.
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index bba68bf..33e4eed 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -966,7 +966,7 @@
case INTERFACE:
return lookupSingleInterfaceTarget(target, invocationContext);
case DIRECT:
- return lookupDirectTarget(target);
+ return lookupDirectTarget(target, invocationContext);
case STATIC:
return lookupStaticTarget(target, invocationContext);
case SUPER: