Add context sensitive definition lookup methods.
Change-Id: I9ba2b74d1553c07c5447fc84665af57cd23f3bb2
diff --git a/src/main/java/com/android/tools/r8/graph/DexDefinitionSupplier.java b/src/main/java/com/android/tools/r8/graph/DexDefinitionSupplier.java
index 47223c0..cc91bcd 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDefinitionSupplier.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDefinitionSupplier.java
@@ -6,17 +6,76 @@
public interface DexDefinitionSupplier {
+ /**
+ * Lookup for the definition of a type independent of context.
+ *
+ * <p>This will make use of the compilers program, library and classpath precedence.
+ *
+ * @param type Type to look up the defintion for.
+ * @return Definition of the type or null if no definition exists.
+ */
+ default DexClass contextIndependentDefinitionFor(DexType type) {
+ return definitionFor(type);
+ }
+
+ /**
+ * Lookup for the definition of a type from a given context.
+ *
+ * <p>This ensures that a context overrides the usual lookup precedence if looking up itself.
+ *
+ * @param type Type to look up a definition for.
+ * @param context Context from which the lookup is taking place.
+ * @return Definition of the type or null if no definition exists.
+ */
+ default DexClass definitionFor(DexType type, DexProgramClass context) {
+ return type == context.type ? context : contextIndependentDefinitionFor(type);
+ }
+
+ /**
+ * Lookup for the program definition of a type from a given context.
+ *
+ * <p>This ensures that a context overrides the usual lookup precedence if looking up itself.
+ *
+ * @param type Type to look up a definition for.
+ * @param context Context from which the lookup is taking place.
+ * @return Definition of the type if it is a program type or null if not or no definition exists.
+ */
+ default DexProgramClass programDefinitionFor(DexType type, DexProgramClass context) {
+ return DexProgramClass.asProgramClassOrNull(definitionFor(type, context));
+ }
+
+ default <D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
+ DexClass definitionForHolder(DexEncodedMember<D, R> member, ProgramMethod context) {
+ return definitionForHolder(member.toReference(), context.getHolder());
+ }
+
+ default <D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
+ DexClass definitionForHolder(DexEncodedMember<D, R> member, DexProgramClass context) {
+ return definitionForHolder(member.toReference(), context);
+ }
+
+ default <D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
+ DexClass definitionForHolder(DexMember<D, R> member, ProgramMethod context) {
+ return definitionFor(member.holder, context.getHolder());
+ }
+
+ default <D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
+ DexClass definitionForHolder(DexMember<D, R> member, DexProgramClass context) {
+ return definitionFor(member.holder, context);
+ }
+
+ // Use definitionFor with a context or contextIndependentDefinitionFor without.
+ @Deprecated
DexClass definitionFor(DexType type);
+ // Use programDefinitionFor with a context.
+ @Deprecated
default DexProgramClass definitionForProgramType(DexType type) {
return DexProgramClass.asProgramClassOrNull(definitionFor(type));
}
- default <D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
- DexClass definitionForHolder(DexEncodedMember<D, R> member) {
- return definitionForHolder(member.toReference());
- }
-
+ // Use definitionForHolder with a context.
+ @Deprecated
default <D extends DexEncodedMember<D, R>, R extends DexMember<D, R>>
DexClass definitionForHolder(DexMember<D, R> member) {
return definitionFor(member.holder);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
index 5b1dd91..0df3c80 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAssignmentTracker.java
@@ -202,8 +202,8 @@
}
private void recordAllFieldPutsProcessed(
- DexEncodedField field, OptimizationFeedbackDelayed feedback) {
- DexProgramClass clazz = asProgramClassOrNull(appView.definitionForHolder(field));
+ DexEncodedField field, ProgramMethod context, OptimizationFeedbackDelayed feedback) {
+ DexProgramClass clazz = asProgramClassOrNull(appView.definitionForHolder(field, context));
if (clazz == null) {
assert false;
return;
@@ -282,7 +282,8 @@
// therefore important that the optimization info has been flushed in advance.
assert feedback.noUpdatesLeft();
for (ProgramMethod method : wave) {
- fieldAccessGraph.markProcessed(method, field -> recordAllFieldPutsProcessed(field, feedback));
+ fieldAccessGraph.markProcessed(
+ method, field -> recordAllFieldPutsProcessed(field, method, feedback));
objectAllocationGraph.markProcessed(
method, clazz -> recordAllAllocationsSitesProcessed(clazz, feedback));
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 6fe0808..a078c9b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -121,7 +121,7 @@
InvokeSuper invoke = current.asInvokeSuper();
DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget != null) {
- DexClass holder = appView.definitionForHolder(singleTarget);
+ DexClass holder = appView.definitionForHolder(singleTarget, context);
assert holder != null;
DexMethod invokedMethod = invoke.getInvokedMethod();
DexEncodedMethod newSingleTarget =