Use DexProgramClass and ProgramMethod for contexts
Bug: 155435595
Change-Id: I945e7df5a31be2820f5bddb460c7aff3be93d8f1
diff --git a/src/main/java/com/android/tools/r8/PrintUses.java b/src/main/java/com/android/tools/r8/PrintUses.java
index 9a26221..d7ef578 100644
--- a/src/main/java/com/android/tools/r8/PrintUses.java
+++ b/src/main/java/com/android/tools/r8/PrintUses.java
@@ -203,9 +203,7 @@
private void addField(DexField field, boolean isStatic) {
addType(field.type);
DexEncodedField baseField =
- isStatic
- ? appInfo.lookupStaticTarget(field.holder, field)
- : appInfo.lookupInstanceTarget(field.holder, field);
+ isStatic ? appInfo.lookupStaticTarget(field) : appInfo.lookupInstanceTarget(field);
if (baseField != null && baseField.holder() != field.holder) {
field = baseField.field;
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
index e9997b0..6f4e958 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArithmeticBinop.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.ValueType;
@@ -167,8 +167,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forBinop();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
index 85c4773..1290256 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLength.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -43,8 +43,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forArrayLength();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
index 010bcfd..02e20ea 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.ValueType;
@@ -88,8 +88,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forArrayGet();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
index 52df928..1976942 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayStore.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -78,8 +78,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forArrayPut();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
index 19ca32e..a46e68c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCheckCast.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -40,7 +42,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerCheckCast(type);
}
@@ -59,8 +61,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forCheckCast(type, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forCheckCast(type, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
index 259bfe3..8d128be 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfCmp.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.Cmp;
import com.android.tools.r8.ir.code.Cmp.Bias;
@@ -92,8 +92,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forBinop();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
index a203742..05d8568 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstClass.java
@@ -5,6 +5,8 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -71,7 +73,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerConstClass(type);
}
@@ -82,8 +84,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forConstClass(type, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forConstClass(type, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
index 04e569b..89fae02 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodHandle.java
@@ -4,8 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexMethodHandle;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.graph.UseRegistry.MethodHandleUse;
@@ -40,7 +41,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerMethodHandle(handle, MethodHandleUse.NOT_ARGUMENT_TO_LAMBDA_METAFACTORY);
}
@@ -58,8 +59,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstMethodHandle();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
index a67c3ed..8283278 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstMethodType.java
@@ -4,8 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -40,7 +41,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerProto(type);
}
@@ -58,8 +59,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstMethodType();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
index c3be968..889a63c 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -35,8 +35,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
index da5d12a..5451986 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNumber.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -133,8 +133,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
index 08ee865..3b113cb 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstString.java
@@ -4,8 +4,8 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -65,8 +65,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forConstInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
index fbc4939..94eadd1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfDexItemBasedConstString.java
@@ -5,8 +5,9 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
-import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -64,7 +65,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
if (nameComputationInfo.needsToRegisterReference()) {
assert item.isDexType();
registry.registerTypeReference(item.asDexType());
@@ -81,8 +82,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forDexItemBasedConstString(item, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forDexItemBasedConstString(item, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
index 5812288..7e31f5b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFieldInstruction.java
@@ -5,7 +5,9 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -64,7 +66,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
switch (opcode) {
case Opcodes.GETFIELD:
registry.registerInstanceFieldRead(field);
@@ -123,17 +125,16 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
switch (opcode) {
case Opcodes.GETSTATIC:
- return inliningConstraints.forStaticGet(field, invocationContext);
+ return inliningConstraints.forStaticGet(field, context);
case Opcodes.PUTSTATIC:
- return inliningConstraints.forStaticPut(field, invocationContext);
+ return inliningConstraints.forStaticPut(field, context);
case Opcodes.GETFIELD:
- return inliningConstraints.forInstanceGet(field, invocationContext);
+ return inliningConstraints.forInstanceGet(field, context);
case Opcodes.PUTFIELD:
- return inliningConstraints.forInstancePut(field, invocationContext);
+ return inliningConstraints.forInstancePut(field, context);
default:
throw new Unreachable("Unexpected opcode " + opcode);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
index 88d5ece..72f5be9 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrame.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -293,8 +294,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
index 412c97c7..bbb8996 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfGoto.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -60,8 +60,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIf.java b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
index ebc6a98..a6d0fca 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIf.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.If.Type;
@@ -93,8 +93,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
index c2f34f7..24c81a5 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIfCmp.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.If.Type;
@@ -94,8 +94,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
index 986d11f..4ce64a4 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfIinc.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -51,8 +51,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
index a355f58..115d27a 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInitClass.java
@@ -4,7 +4,9 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -49,7 +51,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType context) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerInitClass(clazz);
}
@@ -66,7 +68,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType context) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forInitClass(clazz, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
index 5d0997f..ca6b7ed 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstanceOf.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -49,7 +51,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerTypeReference(type);
}
@@ -67,8 +69,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forInstanceOf(type, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forInstanceOf(type, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
index d3cc826..05f1181 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInstruction.java
@@ -4,8 +4,11 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ClasspathMethod;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -28,7 +31,15 @@
return printer.toString();
}
- public void registerUse(UseRegistry registry, DexType clazz) {
+ public void registerUse(UseRegistry registry, ProgramMethod context) {
+ internalRegisterUse(registry, context);
+ }
+
+ public void registerUseForDesugaring(UseRegistry registry, ClasspathMethod context) {
+ internalRegisterUse(registry, context);
+ }
+
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
// Intentionally empty.
}
@@ -153,6 +164,5 @@
}
public abstract ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context);
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index 1a5dd5c..1146ff2 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -83,7 +84,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
switch (opcode) {
case Opcodes.INVOKEINTERFACE:
registry.registerInvokeInterface(method);
@@ -94,7 +95,7 @@
case Opcodes.INVOKESPECIAL:
if (method.name.toString().equals(Constants.INSTANCE_INITIALIZER_NAME)) {
registry.registerInvokeDirect(method);
- } else if (method.holder == clazz) {
+ } else if (method.holder == context.getHolderType()) {
registry.registerInvokeDirect(method);
} else {
registry.registerInvokeSuper(method);
@@ -196,8 +197,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
GraphLense graphLense = inliningConstraints.getGraphLense();
AppView<?> appView = inliningConstraints.getAppView();
DexMethod target = method;
@@ -215,7 +215,7 @@
if (appView.dexItemFactory().isConstructor(target)) {
type = Type.DIRECT;
assert noNeedToUseGraphLense(target, type, graphLense);
- } else if (target.holder == invocationContext) {
+ } else if (target.holder == context.type) {
// The method could have been publicized.
type = graphLense.lookupMethod(target, null, Type.DIRECT).getType();
assert type == Type.DIRECT || type == Type.VIRTUAL;
@@ -232,37 +232,39 @@
}
break;
- case Opcodes.INVOKESTATIC: {
- // Static invokes may have changed as a result of horizontal class merging.
- GraphLenseLookupResult lookup = graphLense.lookupMethod(target, null, Type.STATIC);
- target = lookup.getMethod();
- type = lookup.getType();
- break;
- }
-
- case Opcodes.INVOKEVIRTUAL: {
- type = Type.VIRTUAL;
- // Instructions that target a private method in the same class translates to
- // invoke-direct.
- if (target.holder == invocationContext) {
- DexClass clazz = appView.definitionFor(target.holder);
- if (clazz != null && clazz.lookupDirectMethod(target) != null) {
- type = Type.DIRECT;
- }
+ case Opcodes.INVOKESTATIC:
+ {
+ // Static invokes may have changed as a result of horizontal class merging.
+ GraphLenseLookupResult lookup = graphLense.lookupMethod(target, null, Type.STATIC);
+ target = lookup.getMethod();
+ type = lookup.getType();
}
-
- // Virtual invokes may have changed to interface invokes as a result of member rebinding.
- GraphLenseLookupResult lookup = graphLense.lookupMethod(target, null, type);
- target = lookup.getMethod();
- type = lookup.getType();
break;
- }
+
+ case Opcodes.INVOKEVIRTUAL:
+ {
+ type = Type.VIRTUAL;
+ // Instructions that target a private method in the same class translates to
+ // invoke-direct.
+ if (target.holder == context.type) {
+ DexClass clazz = appView.definitionFor(target.holder);
+ if (clazz != null && clazz.lookupDirectMethod(target) != null) {
+ type = Type.DIRECT;
+ }
+ }
+
+ // Virtual invokes may have changed to interface invokes as a result of member rebinding.
+ GraphLenseLookupResult lookup = graphLense.lookupMethod(target, null, type);
+ target = lookup.getMethod();
+ type = lookup.getType();
+ }
+ break;
default:
throw new Unreachable("Unexpected opcode " + opcode);
}
- return inliningConstraints.forInvoke(target, type, invocationContext);
+ return inliningConstraints.forInvoke(target, type, context);
}
private static boolean noNeedToUseGraphLense(
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
index 458bc23..fac04cd 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvokeDynamic.java
@@ -6,7 +6,9 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.DexCallSite;
+import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexMethodHandle;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
@@ -82,7 +84,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerCallSite(callSite);
}
@@ -110,8 +112,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forInvokeCustom();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
index 7e678dc..2fc78ea 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfJsrRet.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -45,7 +45,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
throw error();
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
index 3901a1a..6cc49de 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLabel.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -58,8 +58,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
index 80d6a8e..0680d73 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLoad.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -87,8 +87,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forLoad();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
index c2775a0..f34a7d7 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfLogicalBinop.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.ValueType;
@@ -139,8 +139,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forBinop();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
index 6386b3c..7fd0167 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMonitor.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.Monitor.Type;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -52,8 +52,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forMonitor();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
index d12d76b..1f787f8 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfMultiANewArray.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -45,7 +47,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerTypeReference(type);
}
@@ -64,8 +66,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forInvokeMultiNewArray(type, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forInvokeMultiNewArray(type, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
index 02b2a83..cd61c29 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNeg.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.ValueType;
@@ -81,8 +81,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forUnop();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNew.java b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
index be087af..8bd1249 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNew.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
@@ -4,6 +4,8 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -39,7 +41,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
registry.registerNewInstance(type);
}
@@ -55,8 +57,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forNewInstance(type, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forNewInstance(type, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
index 1ce6048..9ef5f1b 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNewArray.java
@@ -5,6 +5,8 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.DexClassAndMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.graph.UseRegistry;
@@ -78,7 +80,7 @@
}
@Override
- public void registerUse(UseRegistry registry, DexType clazz) {
+ void internalRegisterUse(UseRegistry registry, DexClassAndMethod context) {
if (!type.isPrimitiveArrayType()) {
registry.registerTypeReference(type);
}
@@ -98,8 +100,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
- return inliningConstraints.forNewArrayEmpty(type, invocationContext);
+ InliningConstraints inliningConstraints, DexProgramClass context) {
+ return inliningConstraints.forNewArrayEmpty(type, context);
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNop.java b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
index be9170c..4578bff 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNop.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNop.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -39,8 +39,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
index dbedc8a..afbff92 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNumberConversion.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.ValueType;
@@ -152,8 +152,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forUnop();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
index 2dac0c6..93febbb 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -67,8 +67,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
index e1b6de1..5934617 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturn.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -75,8 +75,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forReturn();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
index 0bbe1cd..c9d7f51 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfReturnVoid.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -44,8 +44,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forReturn();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
index 5821c3f..ef291d0 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStackInstruction.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -315,8 +315,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfStore.java b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
index d560b82..d8f13d1 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfStore.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfStore.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.cf.CfPrinter;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.CfSourceCode;
@@ -86,8 +86,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forStore();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
index bfbe30f..3169da0 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfSwitch.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -103,8 +103,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
index c0c094d..9b88cb5 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfThrow.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.cf.code;
import com.android.tools.r8.cf.CfPrinter;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.InitClassLens;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.CfState;
@@ -46,8 +46,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints,
- DexType invocationContext) {
+ InliningConstraints inliningConstraints, DexProgramClass context) {
return inliningConstraints.forJumpInstruction();
}
}
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 3a7bad1..d5f8faa 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -208,31 +208,19 @@
fieldDefinitionsCache.remove(type);
}
- // TODO(b/147578480): Temporary API since most of the code base use a type instead
- // of a DexProgramClass as the invocationContext.
- DexProgramClass toProgramClass(DexType type) {
- assert type.isClassType();
- return DexProgramClass.asProgramClassOrNull(definitionFor(type));
- }
-
/**
* Lookup static method on the method holder, or answers null.
*
* @param method the method to lookup
- * @param invocationContext the class the invoke is contained in, i.e., the holder of the caller.
+ * @param context the method the invoke is contained in, i.e., the caller.
* @return The actual target for {@code method} if on the holder, or {@code null}.
*/
- @Deprecated // TODO(b/147578480): Remove
- public DexEncodedMethod lookupStaticTargetOnItself(DexMethod method, DexType invocationContext) {
- return lookupStaticTargetOnItself(method, toProgramClass(invocationContext));
- }
-
public final DexEncodedMethod lookupStaticTargetOnItself(
- DexMethod method, DexProgramClass invocationContext) {
- if (method.holder != invocationContext.type) {
+ DexMethod method, ProgramMethod context) {
+ if (method.holder != context.getHolderType()) {
return null;
}
- DexEncodedMethod singleTarget = invocationContext.lookupDirectMethod(method);
+ DexEncodedMethod singleTarget = context.getHolder().lookupDirectMethod(method);
if (singleTarget != null && singleTarget.isStatic()) {
return singleTarget;
}
@@ -243,20 +231,15 @@
* Lookup direct method on the method holder, or answers null.
*
* @param method the method to lookup
- * @param invocationContext the class the invoke is contained in, i.e., the holder of the caller.
+ * @param context the method the invoke is contained in, i.e., the caller.
* @return The actual target for {@code method} if on the holder, or {@code null}.
*/
- @Deprecated // TODO(b/147578480): Remove
- public DexEncodedMethod lookupDirectTargetOnItself(DexMethod method, DexType invocationContext) {
- return lookupDirectTargetOnItself(method, toProgramClass(invocationContext));
- }
-
public final DexEncodedMethod lookupDirectTargetOnItself(
- DexMethod method, DexProgramClass invocationContext) {
- if (method.holder != invocationContext.type) {
+ DexMethod method, ProgramMethod context) {
+ if (method.holder != context.getHolderType()) {
return null;
}
- DexEncodedMethod singleTarget = invocationContext.lookupDirectMethod(method);
+ DexEncodedMethod singleTarget = context.getHolder().lookupDirectMethod(method);
if (singleTarget != null && !singleTarget.isStatic()) {
return singleTarget;
}
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 fc83884..7853a16 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfoWithClassHierarchy.java
@@ -329,26 +329,32 @@
* <p>The result is the field that will be hit at runtime, if such field is known. A result of
* null indicates that the field is either undefined or not an instance field.
*/
- public DexEncodedField lookupInstanceTarget(DexType type, DexField field) {
+ public DexEncodedField lookupInstanceTargetOn(DexType type, DexField field) {
assert checkIfObsolete();
- assert type.isClassType();
DexEncodedField result = resolveFieldOn(type, field).getResolvedField();
return result == null || result.accessFlags.isStatic() ? null : result;
}
+ public DexEncodedField lookupInstanceTarget(DexField field) {
+ return lookupInstanceTargetOn(field.type, field);
+ }
+
/**
* Lookup static field starting in type and following the interface and super chain.
*
* <p>The result is the field that will be hit at runtime, if such field is known. A result of
* null indicates that the field is either undefined or not a static field.
*/
- public DexEncodedField lookupStaticTarget(DexType type, DexField field) {
+ public DexEncodedField lookupStaticTargetOn(DexType type, DexField field) {
assert checkIfObsolete();
- assert type.isClassType();
DexEncodedField result = resolveFieldOn(type, field).getResolvedField();
return result == null || !result.accessFlags.isStatic() ? null : result;
}
+ public DexEncodedField lookupStaticTarget(DexField field) {
+ return lookupStaticTargetOn(field.type, field);
+ }
+
/**
* Lookup static method following the super chain from the holder of {@code method}.
*
@@ -358,16 +364,13 @@
* @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) {
+ public DexEncodedMethod lookupStaticTarget(DexMethod method, DexProgramClass context) {
assert checkIfObsolete();
- return lookupStaticTarget(method, toProgramClass(invocationContext));
+ return resolveMethod(method.holder, method).lookupInvokeStaticTarget(context, this);
}
- public final DexEncodedMethod lookupStaticTarget(
- DexMethod method, DexProgramClass invocationContext) {
- assert checkIfObsolete();
- return resolveMethod(method.holder, method).lookupInvokeStaticTarget(invocationContext, this);
+ public DexEncodedMethod lookupStaticTarget(DexMethod method, ProgramMethod context) {
+ return lookupStaticTarget(method, context.getHolder());
}
/**
@@ -377,19 +380,16 @@
* non-null value if the result of resolution was an instance (i.e. non-static) method.
*
* @param method the method to lookup
- * @param invocationContext the class the invoke is contained in, i.e., the holder of the caller.
+ * @param context the class the invoke is contained in, i.e., the holder of the caller.
* @return The actual target for {@code method} or {@code null} if none found.
*/
- @Deprecated // TODO(b/147578480): Remove
- public DexEncodedMethod lookupSuperTarget(DexMethod method, DexType invocationContext) {
+ public DexEncodedMethod lookupSuperTarget(DexMethod method, DexProgramClass context) {
assert checkIfObsolete();
- return lookupSuperTarget(method, toProgramClass(invocationContext));
+ return resolveMethod(method.holder, method).lookupInvokeSuperTarget(context, this);
}
- public final DexEncodedMethod lookupSuperTarget(
- DexMethod method, DexProgramClass invocationContext) {
- assert checkIfObsolete();
- return resolveMethod(method.holder, method).lookupInvokeSuperTarget(invocationContext, this);
+ public DexEncodedMethod lookupSuperTarget(DexMethod method, ProgramMethod context) {
+ return lookupSuperTarget(method, context.getHolder());
}
/**
@@ -400,14 +400,12 @@
* @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) {
+ public DexEncodedMethod lookupDirectTarget(DexMethod method, DexProgramClass context) {
assert checkIfObsolete();
- return lookupDirectTarget(method, toProgramClass(invocationContext));
+ return resolveMethod(method.holder, method).lookupInvokeDirectTarget(context, this);
}
- public DexEncodedMethod lookupDirectTarget(DexMethod method, DexProgramClass invocationContext) {
- assert checkIfObsolete();
- return resolveMethod(method.holder, method).lookupInvokeDirectTarget(invocationContext, this);
+ public DexEncodedMethod lookupDirectTarget(DexMethod method, ProgramMethod context) {
+ return lookupDirectTarget(method, context.getHolder());
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index 7a21ff1..0b9b084 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -395,23 +395,18 @@
@Override
public void registerCodeReferences(ProgramMethod method, UseRegistry registry) {
- internalRegisterCodeReferences(method, registry);
+ for (CfInstruction instruction : instructions) {
+ instruction.registerUse(registry, method);
+ }
+ tryCatchRanges.forEach(tryCatch -> tryCatch.guards.forEach(registry::registerTypeReference));
}
@Override
public void registerCodeReferencesForDesugaring(ClasspathMethod method, UseRegistry registry) {
- internalRegisterCodeReferences(method, registry);
- }
-
- private void internalRegisterCodeReferences(DexClassAndMethod method, UseRegistry registry) {
for (CfInstruction instruction : instructions) {
- instruction.registerUse(registry, method.getHolderType());
+ instruction.registerUseForDesugaring(registry, method);
}
- for (CfTryCatch tryCatch : tryCatchRanges) {
- for (DexType guard : tryCatch.guards) {
- registry.registerTypeReference(guard);
- }
- }
+ tryCatchRanges.forEach(tryCatch -> tryCatch.guards.forEach(registry::registerTypeReference));
}
@Override
@@ -513,8 +508,7 @@
ProgramMethod method,
AppView<AppInfoWithLiveness> appView,
GraphLense graphLense,
- DexType invocationContext) {
-
+ DexProgramClass context) {
InliningConstraints inliningConstraints = new InliningConstraints(appView, graphLense);
if (appView.options().isInterfaceMethodDesugaringEnabled()) {
// TODO(b/120130831): Conservatively need to say "no" at this point if there are invocations
@@ -536,9 +530,7 @@
for (CfInstruction insn : instructions) {
constraint =
ConstraintWithTarget.meet(
- constraint,
- insn.inliningConstraint(inliningConstraints, invocationContext),
- appView);
+ constraint, insn.inliningConstraint(inliningConstraints, context), appView);
if (constraint == ConstraintWithTarget.NEVER) {
return constraint;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index c589524..73395b2 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -231,7 +231,7 @@
}
public boolean mayTriggerClassInitializationSideEffects(
- AppView<AppInfoWithLiveness> appView, DexType context) {
+ AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
// Only static field matters when it comes to class initialization side effects.
if (!isStatic()) {
return false;
@@ -244,7 +244,7 @@
appView,
// Types that are a super type of the current context are guaranteed to be initialized
// already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.appInfo().isSubtype(context.getHolderType(), type),
Sets.newIdentityHashSet())) {
// Ignore class initialization side-effects for dead proto extension fields to ensure that
// we force replace these field reads by null.
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index b81c877..c2390fb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -120,9 +120,6 @@
public static final DexEncodedMethod SENTINEL =
new DexEncodedMethod(
null, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null);
- public static final DexEncodedMethod ANNOTATION_REFERENCE =
- new DexEncodedMethod(
- null, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null);
public static final Int2ReferenceMap<DebugLocalInfo> NO_PARAMETER_INFO =
new Int2ReferenceArrayMap<>(0);
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfo.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfo.java
index 38d3a8e..35917f5 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfo.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.graph;
-import java.util.Set;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -20,15 +20,15 @@
int getNumberOfWriteContexts();
- DexEncodedMethod getUniqueReadContext();
+ ProgramMethod getUniqueReadContext();
void forEachIndirectAccess(Consumer<DexField> consumer);
- void forEachIndirectAccessWithContexts(BiConsumer<DexField, Set<DexEncodedMethod>> consumer);
+ void forEachIndirectAccessWithContexts(BiConsumer<DexField, ProgramMethodSet> consumer);
- void forEachReadContext(Consumer<DexEncodedMethod> consumer);
+ void forEachReadContext(Consumer<ProgramMethod> consumer);
- void forEachWriteContext(Consumer<DexEncodedMethod> consumer);
+ void forEachWriteContext(Consumer<ProgramMethod> consumer);
boolean hasReflectiveAccess();
@@ -38,17 +38,17 @@
boolean isRead();
- boolean isReadFromMethodHandle();
+ boolean isReadFromAnnotation();
- boolean isReadOnlyIn(DexEncodedMethod method);
+ boolean isReadFromMethodHandle();
boolean isWritten();
boolean isWrittenFromMethodHandle();
- boolean isWrittenInMethodSatisfying(Predicate<DexEncodedMethod> predicate);
+ boolean isWrittenInMethodSatisfying(Predicate<ProgramMethod> predicate);
- boolean isWrittenOnlyInMethodSatisfying(Predicate<DexEncodedMethod> predicate);
+ boolean isWrittenOnlyInMethodSatisfying(Predicate<ProgramMethod> predicate);
boolean isWrittenOutside(DexEncodedMethod method);
}
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
index 5634d5b..9dd6c41 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoCollectionImpl.java
@@ -30,9 +30,10 @@
return infos.get(field);
}
- public void extend(DexField field, FieldAccessInfoImpl info) {
+ public FieldAccessInfoImpl extend(DexField field, FieldAccessInfoImpl info) {
assert !infos.containsKey(field);
infos.put(field, info);
+ return info;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
index b15153b..383c6e2 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldAccessInfoImpl.java
@@ -5,6 +5,7 @@
package com.android.tools.r8.graph;
import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.Sets;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -22,9 +23,10 @@
public static final FieldAccessInfoImpl MISSING_FIELD_ACCESS_INFO = new FieldAccessInfoImpl(null);
- public static int FLAG_IS_READ_FROM_METHOD_HANDLE = 1 << 0;
- public static int FLAG_IS_WRITTEN_FROM_METHOD_HANDLE = 1 << 1;
- public static int FLAG_HAS_REFLECTIVE_ACCESS = 1 << 2;
+ public static int FLAG_IS_READ_FROM_ANNOTATION = 1 << 0;
+ public static int FLAG_IS_READ_FROM_METHOD_HANDLE = 1 << 1;
+ public static int FLAG_IS_WRITTEN_FROM_METHOD_HANDLE = 1 << 2;
+ public static int FLAG_HAS_REFLECTIVE_ACCESS = 1 << 3;
// A direct reference to the definition of the field.
private DexField field;
@@ -34,11 +36,11 @@
// Maps every direct and indirect reference in a read-context to the set of methods in which that
// reference appears.
- private Map<DexField, Set<DexEncodedMethod>> readsWithContexts;
+ private Map<DexField, ProgramMethodSet> readsWithContexts;
// Maps every direct and indirect reference in a write-context to the set of methods in which that
// reference appears.
- private Map<DexField, Set<DexEncodedMethod>> writesWithContexts;
+ private Map<DexField, ProgramMethodSet> writesWithContexts;
public FieldAccessInfoImpl(DexField field) {
this.field = field;
@@ -49,10 +51,10 @@
flattenAccessContexts(writesWithContexts);
}
- private void flattenAccessContexts(Map<DexField, Set<DexEncodedMethod>> accessesWithContexts) {
+ private void flattenAccessContexts(Map<DexField, ProgramMethodSet> accessesWithContexts) {
if (accessesWithContexts != null) {
- Set<DexEncodedMethod> flattenedAccessContexts =
- accessesWithContexts.computeIfAbsent(field, ignore -> Sets.newIdentityHashSet());
+ ProgramMethodSet flattenedAccessContexts =
+ accessesWithContexts.computeIfAbsent(field, ignore -> ProgramMethodSet.create());
accessesWithContexts.forEach(
(access, contexts) -> {
if (access != field) {
@@ -87,7 +89,7 @@
return getNumberOfAccessContexts(writesWithContexts);
}
- private int getNumberOfAccessContexts(Map<DexField, Set<DexEncodedMethod>> accessesWithContexts) {
+ private int getNumberOfAccessContexts(Map<DexField, ProgramMethodSet> accessesWithContexts) {
if (accessesWithContexts == null) {
return 0;
}
@@ -98,9 +100,9 @@
}
@Override
- public DexEncodedMethod getUniqueReadContext() {
+ public ProgramMethod getUniqueReadContext() {
if (readsWithContexts != null && readsWithContexts.size() == 1) {
- Set<DexEncodedMethod> contexts = readsWithContexts.values().iterator().next();
+ ProgramMethodSet contexts = readsWithContexts.values().iterator().next();
if (contexts.size() == 1) {
return contexts.iterator().next();
}
@@ -120,7 +122,7 @@
}
private static void forEachAccessInMap(
- Map<DexField, Set<DexEncodedMethod>> accessesWithContexts,
+ Map<DexField, ProgramMethodSet> accessesWithContexts,
Predicate<DexField> predicate,
Consumer<DexField> consumer) {
if (accessesWithContexts != null) {
@@ -134,9 +136,8 @@
}
@Override
- public void forEachIndirectAccessWithContexts(
- BiConsumer<DexField, Set<DexEncodedMethod>> consumer) {
- Map<DexField, Set<DexEncodedMethod>> indirectAccessesWithContexts = new IdentityHashMap<>();
+ public void forEachIndirectAccessWithContexts(BiConsumer<DexField, ProgramMethodSet> consumer) {
+ Map<DexField, ProgramMethodSet> indirectAccessesWithContexts = new IdentityHashMap<>();
extendAccessesWithContexts(
indirectAccessesWithContexts, access -> access != field, readsWithContexts);
extendAccessesWithContexts(
@@ -145,15 +146,15 @@
}
private void extendAccessesWithContexts(
- Map<DexField, Set<DexEncodedMethod>> accessesWithContexts,
+ Map<DexField, ProgramMethodSet> accessesWithContexts,
Predicate<DexField> predicate,
- Map<DexField, Set<DexEncodedMethod>> extension) {
+ Map<DexField, ProgramMethodSet> extension) {
if (extension != null) {
extension.forEach(
(access, contexts) -> {
if (predicate.test(access)) {
accessesWithContexts
- .computeIfAbsent(access, ignore -> Sets.newIdentityHashSet())
+ .computeIfAbsent(access, ignore -> ProgramMethodSet.create())
.addAll(contexts);
}
});
@@ -161,24 +162,23 @@
}
@Override
- public void forEachReadContext(Consumer<DexEncodedMethod> consumer) {
+ public void forEachReadContext(Consumer<ProgramMethod> consumer) {
forEachAccessContext(readsWithContexts, consumer);
}
@Override
- public void forEachWriteContext(Consumer<DexEncodedMethod> consumer) {
+ public void forEachWriteContext(Consumer<ProgramMethod> consumer) {
forEachAccessContext(writesWithContexts, consumer);
}
private void forEachAccessContext(
- Map<DexField, Set<DexEncodedMethod>> accessesWithContexts,
- Consumer<DexEncodedMethod> consumer) {
+ Map<DexField, ProgramMethodSet> accessesWithContexts, Consumer<ProgramMethod> consumer) {
// There can be indirect reads and writes of the same field reference, so we need to keep track
// of the previously-seen indirect accesses to avoid reporting duplicates.
- Set<DexEncodedMethod> visited = Sets.newIdentityHashSet();
+ ProgramMethodSet visited = ProgramMethodSet.create();
if (accessesWithContexts != null) {
- for (Set<DexEncodedMethod> encodedAccessContexts : accessesWithContexts.values()) {
- for (DexEncodedMethod encodedAccessContext : encodedAccessContexts) {
+ for (ProgramMethodSet encodedAccessContexts : accessesWithContexts.values()) {
+ for (ProgramMethod encodedAccessContext : encodedAccessContexts) {
if (visited.add(encodedAccessContext)) {
consumer.accept(encodedAccessContext);
}
@@ -199,7 +199,16 @@
/** Returns true if this field is read by the program. */
@Override
public boolean isRead() {
- return readsWithContexts != null && !readsWithContexts.isEmpty();
+ return (readsWithContexts != null && !readsWithContexts.isEmpty()) || isReadFromAnnotation();
+ }
+
+ @Override
+ public boolean isReadFromAnnotation() {
+ return (flags & FLAG_IS_READ_FROM_ANNOTATION) != 0;
+ }
+
+ public void setReadFromAnnotation() {
+ flags |= FLAG_IS_READ_FROM_ANNOTATION;
}
@Override
@@ -211,14 +220,6 @@
flags |= FLAG_IS_READ_FROM_METHOD_HANDLE;
}
- @Override
- public boolean isReadOnlyIn(DexEncodedMethod method) {
- assert isRead();
- assert method != null;
- DexEncodedMethod uniqueReadContext = getUniqueReadContext();
- return uniqueReadContext != null && uniqueReadContext == method;
- }
-
/** Returns true if this field is written by the program. */
@Override
public boolean isWritten() {
@@ -238,10 +239,10 @@
* Returns true if this field is written by a method for which {@param predicate} returns true.
*/
@Override
- public boolean isWrittenInMethodSatisfying(Predicate<DexEncodedMethod> predicate) {
+ public boolean isWrittenInMethodSatisfying(Predicate<ProgramMethod> predicate) {
if (writesWithContexts != null) {
- for (Set<DexEncodedMethod> encodedWriteContexts : writesWithContexts.values()) {
- for (DexEncodedMethod encodedWriteContext : encodedWriteContexts) {
+ for (ProgramMethodSet encodedWriteContexts : writesWithContexts.values()) {
+ for (ProgramMethod encodedWriteContext : encodedWriteContexts) {
if (predicate.test(encodedWriteContext)) {
return true;
}
@@ -256,10 +257,10 @@
* true.
*/
@Override
- public boolean isWrittenOnlyInMethodSatisfying(Predicate<DexEncodedMethod> predicate) {
+ public boolean isWrittenOnlyInMethodSatisfying(Predicate<ProgramMethod> predicate) {
if (writesWithContexts != null) {
- for (Set<DexEncodedMethod> encodedWriteContexts : writesWithContexts.values()) {
- for (DexEncodedMethod encodedWriteContext : encodedWriteContexts) {
+ for (ProgramMethodSet encodedWriteContexts : writesWithContexts.values()) {
+ for (ProgramMethod encodedWriteContext : encodedWriteContexts) {
if (!predicate.test(encodedWriteContext)) {
return false;
}
@@ -275,9 +276,9 @@
@Override
public boolean isWrittenOutside(DexEncodedMethod method) {
if (writesWithContexts != null) {
- for (Set<DexEncodedMethod> encodedWriteContexts : writesWithContexts.values()) {
- for (DexEncodedMethod encodedWriteContext : encodedWriteContexts) {
- if (encodedWriteContext != method) {
+ for (ProgramMethodSet encodedWriteContexts : writesWithContexts.values()) {
+ for (ProgramMethod encodedWriteContext : encodedWriteContexts) {
+ if (encodedWriteContext.getDefinition() != method) {
return true;
}
}
@@ -286,21 +287,21 @@
return false;
}
- public boolean recordRead(DexField access, DexEncodedMethod context) {
+ public boolean recordRead(DexField access, ProgramMethod context) {
if (readsWithContexts == null) {
readsWithContexts = new IdentityHashMap<>();
}
return readsWithContexts
- .computeIfAbsent(access, ignore -> Sets.newIdentityHashSet())
+ .computeIfAbsent(access, ignore -> ProgramMethodSet.create())
.add(context);
}
- public boolean recordWrite(DexField access, DexEncodedMethod context) {
+ public boolean recordWrite(DexField access, ProgramMethod context) {
if (writesWithContexts == null) {
writesWithContexts = new IdentityHashMap<>();
}
return writesWithContexts
- .computeIfAbsent(access, ignore -> Sets.newIdentityHashSet())
+ .computeIfAbsent(access, ignore -> ProgramMethodSet.create())
.add(context);
}
@@ -319,11 +320,11 @@
rewritten.readsWithContexts = new IdentityHashMap<>();
readsWithContexts.forEach(
(access, contexts) -> {
- Set<DexEncodedMethod> newContexts =
+ ProgramMethodSet newContexts =
rewritten.readsWithContexts.computeIfAbsent(
- lens.lookupField(access), ignore -> Sets.newIdentityHashSet());
- for (DexEncodedMethod context : contexts) {
- newContexts.add(lens.mapDexEncodedMethod(context, definitions));
+ lens.lookupField(access), ignore -> ProgramMethodSet.create());
+ for (ProgramMethod context : contexts) {
+ newContexts.add(lens.mapProgramMethod(context, definitions));
}
});
}
@@ -331,11 +332,11 @@
rewritten.writesWithContexts = new IdentityHashMap<>();
writesWithContexts.forEach(
(access, contexts) -> {
- Set<DexEncodedMethod> newContexts =
+ ProgramMethodSet newContexts =
rewritten.writesWithContexts.computeIfAbsent(
- lens.lookupField(access), ignore -> Sets.newIdentityHashSet());
- for (DexEncodedMethod context : contexts) {
- newContexts.add(lens.mapDexEncodedMethod(context, definitions));
+ lens.lookupField(access), ignore -> ProgramMethodSet.create());
+ for (ProgramMethod context : contexts) {
+ newContexts.add(lens.mapProgramMethod(context, definitions));
}
});
}
diff --git a/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java b/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java
index 266a23b..890d030 100644
--- a/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/FieldResolutionResult.java
@@ -17,7 +17,7 @@
}
public abstract OptionalBool isAccessibleFrom(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ ProgramMethod context, AppInfoWithClassHierarchy appInfo);
public boolean isSuccessfulResolution() {
return false;
@@ -59,10 +59,9 @@
}
@Override
- public OptionalBool isAccessibleFrom(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ public OptionalBool isAccessibleFrom(ProgramMethod context, AppInfoWithClassHierarchy appInfo) {
return AccessControl.isFieldAccessible(
- resolvedField, initialResolutionHolder, context, appInfo);
+ resolvedField, initialResolutionHolder, context.getHolder(), appInfo);
}
@Override
@@ -81,8 +80,7 @@
private static final FailedFieldResolutionResult INSTANCE = new FailedFieldResolutionResult();
@Override
- public OptionalBool isAccessibleFrom(
- DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
+ public OptionalBool isAccessibleFrom(ProgramMethod context, AppInfoWithClassHierarchy appInfo) {
return OptionalBool.FALSE;
}
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index e5de7ff..2a5f317 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -145,9 +145,6 @@
public DexEncodedMethod mapDexEncodedMethod(
DexEncodedMethod originalEncodedMethod, DexDefinitionSupplier definitions) {
assert originalEncodedMethod != DexEncodedMethod.SENTINEL;
- if (originalEncodedMethod == DexEncodedMethod.ANNOTATION_REFERENCE) {
- return DexEncodedMethod.ANNOTATION_REFERENCE;
- }
DexMethod newMethod = getRenamedMethodSignature(originalEncodedMethod.method);
// Note that:
// * Even if `newMethod` is the same as `originalEncodedMethod.method`, we still need to look it
@@ -161,6 +158,13 @@
return newEncodedMethod;
}
+ public ProgramMethod mapProgramMethod(
+ ProgramMethod oldMethod, DexDefinitionSupplier definitions) {
+ DexMethod newMethod = getRenamedMethodSignature(oldMethod.getReference());
+ DexProgramClass holder = definitions.definitionForHolder(newMethod).asProgramClass();
+ return holder.lookupProgramMethod(newMethod);
+ }
+
public abstract DexType lookupType(DexType type);
// This overload can be used when the graph lense is known to be context insensitive.
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 fd1781d..fab752df 100644
--- a/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/ResolutionResult.java
@@ -62,6 +62,11 @@
public abstract OptionalBool isAccessibleFrom(
DexProgramClass context, AppInfoWithClassHierarchy appInfo);
+ public final OptionalBool isAccessibleFrom(
+ ProgramMethod context, AppInfoWithClassHierarchy appInfo) {
+ return isAccessibleFrom(context.getHolder(), appInfo);
+ }
+
public abstract OptionalBool isAccessibleForVirtualDispatchFrom(
DexProgramClass context, AppInfoWithClassHierarchy appInfo);
@@ -228,12 +233,12 @@
* result of resolution was a static, non-abstract method.
*
* @param context Class the invoke is contained in, i.e., the holder of the caller.
- * * @param appInfo Application info.
+ * @param appInfo Application info.
* @return The actual target or {@code null} if none found.
*/
@Override
- public DexEncodedMethod lookupInvokeStaticTarget(DexProgramClass context,
- AppInfoWithClassHierarchy appInfo) {
+ public DexEncodedMethod lookupInvokeStaticTarget(
+ DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
if (isAccessibleFrom(context, appInfo).isFalse()) {
return null;
}
@@ -265,7 +270,7 @@
}
private DexEncodedMethod internalInvokeSpecialOrSuper(
- DexClass context,
+ DexProgramClass context,
AppInfoWithClassHierarchy appInfo,
BiPredicate<DexClass, DexClass> isSuperclass) {
@@ -669,8 +674,8 @@
}
@Override
- public DexEncodedMethod lookupInvokeStaticTarget(DexProgramClass context,
- AppInfoWithClassHierarchy appInfo) {
+ public DexEncodedMethod lookupInvokeStaticTarget(
+ DexProgramClass context, AppInfoWithClassHierarchy appInfo) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java
index 48518f5..59c37b8 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/InitializedClassesInInstanceMethodsAnalysis.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
@@ -28,25 +27,26 @@
this.mapping = mapping;
}
- public boolean isClassDefinitelyLoadedInInstanceMethodsOn(DexType subject, DexType context) {
+ public boolean isClassDefinitelyLoadedInInstanceMethod(
+ DexProgramClass subject, ProgramMethod context) {
+ assert !context.getDefinition().isStatic();
// If `subject` is kept, then it is instantiated by reflection, which means that the analysis
// has not seen all allocation sites. In that case, we conservatively return false.
AppInfoWithClassHierarchy appInfo = appView.appInfo();
- if (appInfo.hasLiveness() && appInfo.withLiveness().isPinned(subject)) {
+ if (appInfo.hasLiveness() && appInfo.withLiveness().isPinned(subject.type)) {
return false;
}
// Check that `subject` is guaranteed to be initialized in all instance methods of `context`.
DexType guaranteedToBeInitializedInContext =
- mapping.getOrDefault(context, appView.dexItemFactory().objectType);
- if (!appInfo.isSubtype(guaranteedToBeInitializedInContext, subject)) {
+ mapping.getOrDefault(context.getHolderType(), appView.dexItemFactory().objectType);
+ if (!appInfo.isSubtype(guaranteedToBeInitializedInContext, subject.type)) {
return false;
}
// Also check that `subject` is not an interface, since interfaces are not initialized
// transitively.
- DexClass clazz = appView.definitionFor(subject);
- return clazz != null && !clazz.isInterface();
+ return !subject.isInterface();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
index 3335e27..6264490 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/ClassInitializationAnalysis.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -97,7 +98,7 @@
}
public boolean isClassDefinitelyLoadedBeforeInstruction(DexType type, Instruction instruction) {
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
BasicBlock block = instruction.getBlock();
// Visit the instructions in `block` prior to `instruction`.
@@ -307,7 +308,7 @@
public static boolean forInvokeInterface(
InvokeInterface instruction,
DexType type,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -343,7 +344,7 @@
public static boolean forInvokeStatic(
InvokeStatic instruction,
DexType type,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -358,7 +359,7 @@
public static boolean forInvokeSuper(
InvokeSuper instruction,
DexType type,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -402,7 +403,7 @@
public static boolean forInvokeVirtual(
InvokeVirtual instruction,
DexType type,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java
index 5452f50..32c1bb1 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/DeterminismAnalysis.java
@@ -37,7 +37,7 @@
}
if (instr.isInvokeMethod()) {
DexEncodedMethod target =
- instr.asInvokeMethod().lookupSingleTarget(appView, code.method().holder());
+ instr.asInvokeMethod().lookupSingleTarget(appView, code.context());
if (target != null && target.getOptimizationInfo().returnValueOnlyDependsOnArguments()) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java
index d6b0ba1..b73a496 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/InitializedClassesOnNormalExitAnalysis.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.DefaultInstructionVisitor;
import com.android.tools.r8.ir.code.DominatorTree;
@@ -36,7 +37,7 @@
public static Set<DexType> computeInitializedClassesOnNormalExit(
AppView<AppInfoWithLiveness> appView, IRCode code) {
DominatorTree dominatorTree = new DominatorTree(code, Assumption.MAY_HAVE_UNREACHABLE_BLOCKS);
- Visitor visitor = new Visitor(appView, code.method().holder());
+ Visitor visitor = new Visitor(appView, code.context());
for (BasicBlock dominator : dominatorTree.normalExitDominatorBlocks()) {
if (dominator.hasCatchHandlers()) {
// When determining which classes that are guaranteed to be initialized from a given
@@ -55,10 +56,10 @@
private static class Visitor extends DefaultInstructionVisitor<Void> {
private final AppView<AppInfoWithLiveness> appView;
- private final DexType context;
+ private final ProgramMethod context;
private final Set<DexType> initializedClassesOnNormalExit = Sets.newIdentityHashSet();
- Visitor(AppView<AppInfoWithLiveness> appView, DexType context) {
+ Visitor(AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
this.appView = appView;
this.context = context;
}
@@ -72,7 +73,7 @@
}
private void markInitializedOnNormalExit(DexType knownToBeInitialized) {
- if (knownToBeInitialized == context) {
+ if (knownToBeInitialized == context.getHolderType()) {
// Do not record that the given method causes its own holder to be initialized, since this
// is trivial.
return;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java
index fbb6735..82e53b7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/ValueMayDependOnEnvironmentAnalysis.java
@@ -10,7 +10,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.IRCode;
@@ -27,8 +27,6 @@
import com.android.tools.r8.utils.LongInterval;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
-import java.util.List;
-import java.util.Map;
import java.util.Set;
/**
@@ -69,19 +67,15 @@
private final AppView<?> appView;
private final IRCode code;
- private final DexType context;
+ private final ProgramMethod context;
private final Set<Value> knownNotToDependOnEnvironment = Sets.newIdentityHashSet();
private final Set<Value> visited = Sets.newIdentityHashSet();
- // Lazily computed mapping from final field definitions of the enclosing class to the static-put
- // instructions in the class initializer that assigns these final fields.
- private Map<DexEncodedField, List<StaticPut>> finalFieldPuts;
-
public ValueMayDependOnEnvironmentAnalysis(AppView<?> appView, IRCode code) {
this.appView = appView;
this.code = code;
- this.context = code.method().holder();
+ this.context = code.context();
}
public boolean valueMayDependOnEnvironment(Value value) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java b/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java
index 27c4e19..e4235e6 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/equivalence/BasicBlockBehavioralSubsumption.java
@@ -8,7 +8,7 @@
import static com.google.common.base.Predicates.or;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstClass;
import com.android.tools.r8.ir.code.ConstNumber;
@@ -33,9 +33,9 @@
public class BasicBlockBehavioralSubsumption {
private final AppView<?> appView;
- private final DexType context;
+ private final ProgramMethod context;
- public BasicBlockBehavioralSubsumption(AppView<?> appView, DexType context) {
+ public BasicBlockBehavioralSubsumption(AppView<?> appView, ProgramMethod context) {
this.appView = appView;
this.context = context;
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/escape/DefaultEscapeAnalysisConfiguration.java b/src/main/java/com/android/tools/r8/ir/analysis/escape/DefaultEscapeAnalysisConfiguration.java
index 6ec09bb..b65eda2 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/escape/DefaultEscapeAnalysisConfiguration.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/escape/DefaultEscapeAnalysisConfiguration.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.analysis.escape;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.Instruction;
public class DefaultEscapeAnalysisConfiguration implements EscapeAnalysisConfiguration {
@@ -24,7 +24,7 @@
AppView<?> appView,
EscapeAnalysis escapeAnalysis,
Instruction escapeRoute,
- DexMethod context) {
+ ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysis.java
index b1cac80..b1821c3 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysis.java
@@ -5,6 +5,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
@@ -137,8 +138,8 @@
}
}
}
- if (!configuration.isLegitimateEscapeRoute(appView, this, user, code.method().method)
- && isDirectlyEscaping(user, code.method().method, arguments)) {
+ if (!configuration.isLegitimateEscapeRoute(appView, this, user, code.context())
+ && isDirectlyEscaping(user, code.context(), arguments)) {
if (stoppingCriterion.test(user)) {
return true;
}
@@ -173,7 +174,8 @@
}
}
- private boolean isDirectlyEscaping(Instruction instr, DexMethod context, List<Value> arguments) {
+ private boolean isDirectlyEscaping(
+ Instruction instr, ProgramMethod context, List<Value> arguments) {
// As return value.
if (instr.isReturn()) {
return true;
@@ -190,7 +192,7 @@
if (instr.isInvokeMethod()) {
DexMethod invokedMethod = instr.asInvokeMethod().getInvokedMethod();
// Filter out the recursion with exactly same arguments.
- if (invokedMethod == context) {
+ if (invokedMethod == context.getReference()) {
return !instr.inValues().equals(arguments);
}
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisConfiguration.java b/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisConfiguration.java
index ea3a7e3..e3e5f4b 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisConfiguration.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisConfiguration.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.analysis.escape;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.Instruction;
public interface EscapeAnalysisConfiguration {
@@ -14,5 +14,5 @@
AppView<?> appView,
EscapeAnalysis escapeAnalysis,
Instruction escapeRoute,
- DexMethod context);
+ ProgramMethod context);
}
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAccessAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAccessAnalysis.java
index 67d9f3c..4b209ac 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAccessAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldaccess/FieldAccessAnalysis.java
@@ -80,7 +80,7 @@
if (field != null) {
if (fieldAssignmentTracker != null) {
fieldAssignmentTracker.recordFieldAccess(
- fieldInstruction, field.getDefinition(), code.method());
+ fieldInstruction, field.getDefinition(), code.context());
}
if (fieldBitAccessAnalysis != null) {
fieldBitAccessAnalysis.recordFieldAccess(
@@ -93,7 +93,7 @@
DexProgramClass clazz = asProgramClassOrNull(appView.definitionFor(newInstance.clazz));
if (clazz != null) {
if (fieldAssignmentTracker != null) {
- fieldAssignmentTracker.recordAllocationSite(newInstance, clazz, code.method());
+ fieldAssignmentTracker.recordAllocationSite(newInstance, clazz, code.context());
}
}
}
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 0f6e2ac..fbb6443 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
@@ -119,13 +119,13 @@
}
void recordFieldAccess(
- FieldInstruction instruction, DexEncodedField field, DexEncodedMethod context) {
+ FieldInstruction instruction, DexEncodedField field, ProgramMethod context) {
if (instruction.isFieldPut()) {
recordFieldPut(field, instruction.value(), context);
}
}
- private void recordFieldPut(DexEncodedField field, Value value, DexEncodedMethod context) {
+ private void recordFieldPut(DexEncodedField field, Value value, ProgramMethod context) {
assert verifyValueIsConsistentWithFieldOptimizationInfo(
value, field.getOptimizationInfo(), context);
if (!value.isZero()) {
@@ -133,8 +133,7 @@
}
}
- void recordAllocationSite(
- NewInstance instruction, DexProgramClass clazz, DexEncodedMethod context) {
+ void recordAllocationSite(NewInstance instruction, DexProgramClass clazz, ProgramMethod context) {
Map<DexEncodedField, AbstractValue> abstractInstanceFieldValuesForClass =
abstractInstanceFieldValues.get(clazz);
if (abstractInstanceFieldValuesForClass == null) {
@@ -149,7 +148,7 @@
return;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context.holder());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
// We just lost track.
abstractInstanceFieldValues.remove(clazz);
@@ -174,7 +173,7 @@
initializationInfo.asArgumentInitializationInfo();
Value argument = invoke.arguments().get(argumentInitializationInfo.getArgumentIndex());
AbstractValue abstractValue =
- entry.getValue().join(argument.getAbstractValue(appView, context.holder()));
+ entry.getValue().join(argument.getAbstractValue(appView, context));
assert !abstractValue.isBottom();
if (!abstractValue.isUnknown()) {
entry.setValue(abstractValue);
@@ -290,12 +289,12 @@
}
private boolean verifyValueIsConsistentWithFieldOptimizationInfo(
- Value value, FieldOptimizationInfo optimizationInfo, DexEncodedMethod context) {
+ Value value, FieldOptimizationInfo optimizationInfo, ProgramMethod context) {
AbstractValue abstractValue = optimizationInfo.getAbstractValue();
if (abstractValue.isUnknown()) {
return true;
}
- assert abstractValue == value.getAbstractValue(appView, context.holder());
+ assert abstractValue == value.getAbstractValue(appView, context);
return true;
}
@@ -324,7 +323,9 @@
if (!info.hasReflectiveAccess() && !info.isWrittenFromMethodHandle()) {
info.forEachWriteContext(
context ->
- fieldWrites.computeIfAbsent(context, ignore -> new ArrayList<>()).add(field));
+ fieldWrites
+ .computeIfAbsent(context.getDefinition(), ignore -> new ArrayList<>())
+ .add(field));
pendingFieldWrites.put(field, info.getNumberOfWriteContexts());
}
});
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/FieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/FieldValueAnalysis.java
index 5042ab4..e4bf2a9 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/FieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/FieldValueAnalysis.java
@@ -6,10 +6,8 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.DominatorTree;
import com.android.tools.r8.ir.code.DominatorTree.Assumption;
@@ -32,10 +30,9 @@
public abstract class FieldValueAnalysis {
final AppView<AppInfoWithLiveness> appView;
- final DexProgramClass clazz;
final IRCode code;
+ final ProgramMethod context;
final OptimizationFeedback feedback;
- final DexEncodedMethod method;
private DominatorTree dominatorTree;
private Map<BasicBlock, AbstractFieldSet> fieldsMaybeReadBeforeBlockInclusiveCache;
@@ -43,18 +40,11 @@
final Map<DexEncodedField, LinkedList<FieldInstruction>> putsPerField = new IdentityHashMap<>();
FieldValueAnalysis(
- AppView<AppInfoWithLiveness> appView,
- IRCode code,
- OptimizationFeedback feedback,
- DexProgramClass clazz,
- DexEncodedMethod method) {
- assert clazz != null;
- assert clazz.type == method.holder();
+ AppView<AppInfoWithLiveness> appView, IRCode code, OptimizationFeedback feedback) {
this.appView = appView;
- this.clazz = clazz;
this.code = code;
this.feedback = feedback;
- this.method = method;
+ this.context = code.context();
}
DominatorTree getOrCreateDominatorTree() {
@@ -129,7 +119,6 @@
// Then check if any of the instructions that precede the given instruction in the current block
// may read the field.
- DexType context = method.holder();
InstructionIterator instructionIterator = block.iterator();
while (instructionIterator.hasNext()) {
Instruction current = instructionIterator.next();
@@ -164,7 +153,6 @@
* and its transitive predecessors.
*/
private Map<BasicBlock, AbstractFieldSet> createFieldsMaybeReadBeforeBlockInclusive() {
- DexType context = method.holder();
Map<BasicBlock, AbstractFieldSet> result = new IdentityHashMap<>();
Deque<BasicBlock> worklist = DequeUtils.newArrayDeque(code.entryBlock());
while (!worklist.isEmpty()) {
@@ -249,7 +237,7 @@
}
private boolean verifyFieldSetContainsAllFieldReadsInBlock(
- KnownFieldSet readSet, BasicBlock block, DexType context) {
+ KnownFieldSet readSet, BasicBlock block, ProgramMethod context) {
for (Instruction instruction : block.getInstructions()) {
AbstractFieldSet instructionReadSet = instruction.readSet(appView, context);
assert !instructionReadSet.isTop();
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
index 58b4194..b818cc2 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/InstanceFieldValueAnalysis.java
@@ -10,7 +10,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -48,11 +47,9 @@
AppView<AppInfoWithLiveness> appView,
IRCode code,
OptimizationFeedback feedback,
- DexProgramClass clazz,
- DexEncodedMethod method,
DexEncodedMethod parentConstructor,
InvokeDirect parentConstructorCall) {
- super(appView, code, feedback, clazz, method);
+ super(appView, code, feedback);
this.factory = appView.instanceFieldInitializationInfoFactory();
this.parentConstructor = parentConstructor;
this.parentConstructorCall = parentConstructorCall;
@@ -67,11 +64,10 @@
IRCode code,
ClassInitializerDefaultsResult classInitializerDefaultsResult,
OptimizationFeedback feedback,
- DexEncodedMethod method,
Timing timing) {
timing.begin("Analyze instance initializer");
InstanceFieldInitializationInfoCollection result =
- run(appView, code, classInitializerDefaultsResult, feedback, method);
+ run(appView, code, classInitializerDefaultsResult, feedback);
timing.end();
return result;
}
@@ -80,16 +76,10 @@
AppView<?> appView,
IRCode code,
ClassInitializerDefaultsResult classInitializerDefaultsResult,
- OptimizationFeedback feedback,
- DexEncodedMethod method) {
+ OptimizationFeedback feedback) {
assert appView.appInfo().hasLiveness();
assert appView.enableWholeProgramOptimizations();
- assert method.isInstanceInitializer();
-
- DexProgramClass clazz = appView.definitionFor(method.holder()).asProgramClass();
- if (!appView.options().enableValuePropagationForInstanceFields) {
- return EmptyInstanceFieldInitializationInfoCollection.getInstance();
- }
+ assert code.context().getDefinition().isInstanceInitializer();
InvokeDirect parentConstructorCall =
IRCodeUtils.getUniqueConstructorInvoke(code.getThis(), appView.dexItemFactory());
@@ -98,7 +88,7 @@
}
DexEncodedMethod parentConstructor =
- parentConstructorCall.lookupSingleTarget(appView, clazz.type);
+ parentConstructorCall.lookupSingleTarget(appView, code.context());
if (parentConstructor == null) {
return EmptyInstanceFieldInitializationInfoCollection.getInstance();
}
@@ -108,8 +98,6 @@
appView.withLiveness(),
code,
feedback,
- clazz,
- method,
parentConstructor,
parentConstructorCall);
analysis.computeFieldOptimizationInfo(classInitializerDefaultsResult);
@@ -119,7 +107,7 @@
@Override
boolean isSubjectToOptimization(DexEncodedField field) {
- return !field.isStatic() && field.holder() == clazz.type;
+ return !field.isStatic() && field.holder() == context.getHolderType();
}
@Override
@@ -160,7 +148,7 @@
return;
}
- AbstractValue abstractValue = value.getAbstractValue(appView, clazz.type);
+ AbstractValue abstractValue = value.getAbstractValue(appView, context);
if (abstractValue.isSingleValue()) {
builder.recordInitializationInfo(field, abstractValue.asSingleValue());
return;
@@ -185,12 +173,12 @@
return true;
}
- if (appView.appInfo().isFieldOnlyWrittenInMethod(field, method)) {
+ if (appView.appInfo().isFieldOnlyWrittenInMethod(field, context.getDefinition())) {
return true;
}
if (appView.appInfo().isInstanceFieldWrittenOnlyInInstanceInitializers(field)) {
- if (parentConstructorCall.getInvokedMethod().holder != clazz.type) {
+ if (parentConstructorCall.getInvokedMethod().holder != context.getHolderType()) {
// The field is only written in instance initializers of the enclosing class, and the
// constructor call targets a constructor in the super class.
return true;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
index f488267..81df82a 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/fieldvalueanalysis/StaticFieldValueAnalysis.java
@@ -13,7 +13,6 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -38,12 +37,8 @@
public class StaticFieldValueAnalysis extends FieldValueAnalysis {
private StaticFieldValueAnalysis(
- AppView<AppInfoWithLiveness> appView,
- IRCode code,
- OptimizationFeedback feedback,
- DexProgramClass clazz,
- DexEncodedMethod method) {
- super(appView, code, feedback, clazz, method);
+ AppView<AppInfoWithLiveness> appView, IRCode code, OptimizationFeedback feedback) {
+ super(appView, code, feedback);
}
public static void run(
@@ -51,14 +46,12 @@
IRCode code,
ClassInitializerDefaultsResult classInitializerDefaultsResult,
OptimizationFeedback feedback,
- DexEncodedMethod method,
Timing timing) {
assert appView.appInfo().hasLiveness();
assert appView.enableWholeProgramOptimizations();
- assert method.isClassInitializer();
+ assert code.context().getDefinition().isClassInitializer();
timing.begin("Analyze class initializer");
- DexProgramClass clazz = appView.definitionFor(method.holder()).asProgramClass();
- new StaticFieldValueAnalysis(appView.withLiveness(), code, feedback, clazz, method)
+ new StaticFieldValueAnalysis(appView.withLiveness(), code, feedback)
.computeFieldOptimizationInfo(classInitializerDefaultsResult);
timing.end();
}
@@ -70,7 +63,7 @@
classInitializerDefaultsResult.forEachOptimizedField(
(field, value) -> {
if (putsPerField.containsKey(field)
- || !appView.appInfo().isFieldOnlyWrittenInMethod(field, method)) {
+ || !appView.appInfo().isFieldOnlyWrittenInMethod(field, context.getDefinition())) {
return;
}
@@ -96,15 +89,15 @@
@Override
boolean isSubjectToOptimization(DexEncodedField field) {
return field.isStatic()
- && field.holder() == clazz.type
- && appView.appInfo().isFieldOnlyWrittenInMethod(field, method);
+ && field.holder() == context.getHolderType()
+ && appView.appInfo().isFieldOnlyWrittenInMethod(field, context.getDefinition());
}
@Override
void updateFieldOptimizationInfo(DexEncodedField field, FieldInstruction fieldPut, Value value) {
// Abstract value.
Value root = value.getAliasedValue();
- AbstractValue abstractValue = root.getAbstractValue(appView, clazz.type);
+ AbstractValue abstractValue = root.getAbstractValue(appView, context);
if (abstractValue.isUnknown()) {
feedback.recordFieldHasAbstractValue(field, appView, computeSingleFieldValue(field, root));
} else {
@@ -149,12 +142,13 @@
*/
private SingleFieldValue computeSingleEnumFieldValue(Value value) {
assert !value.hasAliasedValue();
- if (!clazz.isEnum() || !value.isDefinedByInstructionSatisfying(Instruction::isNewInstance)) {
+ if (!context.getHolder().isEnum()
+ || !value.isDefinedByInstructionSatisfying(Instruction::isNewInstance)) {
return null;
}
NewInstance newInstance = value.definition.asNewInstance();
- if (newInstance.clazz != clazz.type) {
+ if (newInstance.clazz != context.getHolderType()) {
return null;
}
@@ -183,7 +177,8 @@
break;
case STATIC_PUT:
- DexEncodedField field = clazz.lookupStaticField(user.asStaticPut().getField());
+ DexEncodedField field =
+ context.getHolder().lookupStaticField(user.asStaticPut().getField());
if (field != null && field.accessFlags.isEnum()) {
if (enumField != null) {
return null;
@@ -219,7 +214,7 @@
return ObjectState.empty();
}
- DexEncodedMethod singleTarget = uniqueConstructorInvoke.lookupSingleTarget(appView, clazz.type);
+ DexEncodedMethod singleTarget = uniqueConstructorInvoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
return ObjectState.empty();
}
@@ -242,7 +237,7 @@
initializationInfo.asArgumentInitializationInfo();
Value argument =
uniqueConstructorInvoke.getArgument(argumentInitializationInfo.getArgumentIndex());
- builder.recordFieldHasValue(field, argument.getAbstractValue(appView, clazz.type));
+ builder.recordFieldHasValue(field, argument.getAbstractValue(appView, context));
} else if (initializationInfo.isSingleValue()) {
builder.recordFieldHasValue(field, initializationInfo.asSingleValue());
}
@@ -251,12 +246,12 @@
}
private boolean isEnumValuesArray(Value value) {
- assert clazz.isEnum();
+ assert context.getHolder().isEnum();
DexItemFactory dexItemFactory = appView.dexItemFactory();
DexField valuesField =
dexItemFactory.createField(
- clazz.type,
- clazz.type.toArrayType(1, dexItemFactory),
+ context.getHolderType(),
+ context.getHolderType().toArrayType(1, dexItemFactory),
dexItemFactory.enumValuesFieldName);
Value root = value.getAliasedValue();
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedExtensionRegistryShrinker.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedExtensionRegistryShrinker.java
index 980b1a3..400b509 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedExtensionRegistryShrinker.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/GeneratedExtensionRegistryShrinker.java
@@ -209,9 +209,9 @@
return false;
}
- DexEncodedMethod uniqueReadContext = fieldAccessInfo.getUniqueReadContext();
+ ProgramMethod uniqueReadContext = fieldAccessInfo.getUniqueReadContext();
return uniqueReadContext != null
- && references.isFindLiteExtensionByNumberMethod(uniqueReadContext.method);
+ && references.isFindLiteExtensionByNumberMethod(uniqueReadContext);
}
private void forEachDeadProtoExtensionField(Consumer<DexField> consumer) {
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java
index c2c9a50..861c0cd 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/ProtoReferences.java
@@ -140,6 +140,10 @@
&& method.holder != extensionRegistryLiteType;
}
+ public boolean isFindLiteExtensionByNumberMethod(ProgramMethod method) {
+ return isFindLiteExtensionByNumberMethod(method.getReference());
+ }
+
public boolean isGeneratedMessageLiteBuilder(DexProgramClass clazz) {
return (clazz.superType == generatedMessageLiteBuilderType
|| clazz.superType == generatedMessageLiteExtendableBuilderType)
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
index d6d83ac..0ee0bc8 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/proto/schema/ProtoEnqueuerExtension.java
@@ -434,10 +434,10 @@
ProgramMethod defaultInitializer =
dynamicMethod.getHolder().getProgramDefaultInitializer();
assert defaultInitializer != null;
- Predicate<DexEncodedMethod> neitherDefaultConstructorNorDynamicMethod =
+ Predicate<ProgramMethod> neitherDefaultConstructorNorDynamicMethod =
writer ->
- writer != defaultInitializer.getDefinition()
- && writer != dynamicMethod.getDefinition();
+ !writer.isStructurallyEqualTo(defaultInitializer)
+ && !writer.isStructurallyEqualTo(dynamicMethod);
if (enqueuer.isFieldWrittenInMethodSatisfying(
newlyLiveField, neitherDefaultConstructorNorDynamicMethod)) {
enqueuer.registerReflectiveFieldRead(newlyLiveField.getReference(), dynamicMethod);
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/sideeffect/ClassInitializerSideEffectAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/sideeffect/ClassInitializerSideEffectAnalysis.java
index 4752d83..da7fab0 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/sideeffect/ClassInitializerSideEffectAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/sideeffect/ClassInitializerSideEffectAnalysis.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ValueMayDependOnEnvironmentAnalysis;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.IRCode;
@@ -39,7 +39,7 @@
*/
public static ClassInitializerSideEffect classInitializerCanBePostponed(
AppView<?> appView, IRCode code) {
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
OptionalBool controlFlowMayDependOnEnvironment = OptionalBool.unknown();
boolean mayHaveSideEffects = false;
@@ -114,7 +114,7 @@
DexEncodedField field =
appView.appInfo().resolveField(staticPut.getField()).getResolvedField();
if (field == null
- || field.holder() != context
+ || field.holder() != context.getHolderType()
|| environmentAnalysis.valueMayDependOnEnvironment(staticPut.value())
|| instruction.instructionInstanceCanThrow(appView, context).isThrowing()) {
return ClassInitializerSideEffect.SIDE_EFFECTS_THAT_CANNOT_BE_POSTPONED;
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
index 76213c6..62a3aa6 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/value/SingleConstClassValue.java
@@ -75,7 +75,7 @@
Value returnedValue =
code.createValue(classClassType(appView, definitelyNotNull()), debugLocalInfo);
ConstClass instruction = new ConstClass(returnedValue, type);
- assert !instruction.instructionMayHaveSideEffects(appView, code.method().holder());
+ assert !instruction.instructionMayHaveSideEffects(appView, code.context());
return instruction;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java
index 8cd1503..3cd25ea 100644
--- a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingNop.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.cf.code.CfNop;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -61,7 +61,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return ConstraintWithTarget.ALWAYS;
}
@@ -76,7 +76,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java
index 2a32bb6..4b99975 100644
--- a/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java
+++ b/src/main/java/com/android/tools/r8/ir/code/AlwaysMaterializingUser.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -62,7 +62,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forAlwaysMaterializingUser();
}
@@ -77,7 +77,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Argument.java b/src/main/java/com/android/tools/r8/ir/code/Argument.java
index 2ace686..5b68bf5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Argument.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Argument.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -101,7 +102,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forArgument();
}
@@ -136,7 +137,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
index 432cf11..845cb26 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -151,7 +152,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forArrayGet();
}
@@ -237,7 +238,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return array() == value;
}
@@ -263,7 +264,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java b/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java
index a1ed1d7..fcea78c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayLength.java
@@ -8,7 +8,7 @@
import com.android.tools.r8.cf.code.CfArrayLength;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -74,7 +74,7 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
if (array().type.isNullable()) {
return AbstractError.specific(appView.dexItemFactory().npeType);
}
@@ -84,13 +84,13 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(appView, context).isThrowing();
}
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
@@ -114,7 +114,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forArrayLength();
}
@@ -140,7 +140,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return array() == value;
}
@@ -155,7 +155,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java b/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
index 37daada..860473c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayPut.java
@@ -15,7 +15,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.ArrayTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -134,7 +134,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
// In debug mode, ArrayPut has a side-effect on the locals.
if (appView.options().debug) {
return true;
@@ -192,7 +192,7 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
@@ -220,7 +220,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forArrayPut();
}
@@ -240,7 +240,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return array() == value;
}
@@ -260,7 +260,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Assume.java b/src/main/java/com/android/tools/r8/ir/code/Assume.java
index e5316e4..c6012bd 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Assume.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Assume.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.Assume.Assumption;
@@ -238,7 +239,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forAssume();
}
@@ -270,7 +271,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Binop.java b/src/main/java/com/android/tools/r8/ir/code/Binop.java
index f0d4eff..613ff5b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Binop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Binop.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.PrimitiveTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -123,7 +123,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forBinop();
}
@@ -144,7 +144,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
index da952bd..cdbf6f0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -96,12 +97,12 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(appView, context).isThrowing();
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
if (appView.options().debug || !appView.appInfo().hasLiveness()) {
return AbstractError.top();
}
@@ -154,8 +155,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forCheckCast(type, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forCheckCast(type, context.getHolder());
}
@Override
@@ -225,7 +226,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
index c2d5232..274a03f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -99,7 +100,7 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
DexType baseType = getValue().toBaseType(appView.dexItemFactory());
if (baseType.isPrimitiveType()) {
return AbstractError.bottom();
@@ -108,7 +109,7 @@
// Not applicable for D8.
if (!appView.enableWholeProgramOptimizations()) {
// Unless the type of interest is same as the context.
- if (baseType == context) {
+ if (baseType == context.getHolderType()) {
return AbstractError.bottom();
}
return AbstractError.top();
@@ -133,13 +134,13 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(appView, context).isThrowing();
}
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
@@ -164,8 +165,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forConstClass(clazz, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forConstClass(clazz, context.getHolder());
}
@Override
@@ -189,7 +190,7 @@
}
@Override
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
if (!instructionMayHaveSideEffects(appView, context)) {
return appView.abstractValueFactory().createSingleConstClassValue(clazz);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstInstruction.java b/src/main/java/com/android/tools/r8/ir/code/ConstInstruction.java
index 8db125c..0e8ce5d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstInstruction.java
@@ -5,7 +5,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
@@ -50,7 +50,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forConstInstruction();
}
@@ -60,7 +60,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java b/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
index a390b3f..3973d6e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -78,7 +79,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forConstMethodHandle();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java b/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
index 774475d..6f153a6 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -124,7 +125,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forConstMethodType();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
index fcb0c1b..8845669 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.constant.Bottom;
import com.android.tools.r8.ir.analysis.constant.ConstLatticeElement;
import com.android.tools.r8.ir.analysis.constant.LatticeElement;
@@ -333,7 +334,7 @@
}
@Override
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
return appView.abstractValueFactory().createSingleNumberValue(value);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstString.java b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
index a90a67e..9a2483c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -156,12 +157,12 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
@Override
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
if (!instructionInstanceCanThrow()) {
return appView.abstractValueFactory().createSingleStringValue(value);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
index 64e2c14..292d6b7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalRead.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -66,7 +66,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forDebugLocalRead();
}
@@ -88,7 +88,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java b/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java
index 5b4c66b..842eaa4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugLocalsChange.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -99,7 +99,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forDebugLocalsChange();
}
@@ -135,7 +135,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
index b9ab9cd..fd6f9a9 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.cf.code.CfNop;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -62,7 +62,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forDebugPosition();
}
@@ -89,7 +89,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java b/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
index bc29749..959dbfc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.BasicBlock.ThrowingInfo;
@@ -157,12 +158,12 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forDexItemBasedConstString(item, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forDexItemBasedConstString(item, context.getHolder());
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Dup.java b/src/main/java/com/android/tools/r8/ir/code/Dup.java
index cddc41e..070b8e9 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Dup.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Dup.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.cf.code.CfStackInstruction.Opcode;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -94,7 +94,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forDup();
}
@@ -119,7 +119,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Dup2.java b/src/main/java/com/android/tools/r8/ir/code/Dup2.java
index 465c408..7053383 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Dup2.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Dup2.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.cf.code.CfStackInstruction.Opcode;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -108,7 +108,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forDup2();
}
@@ -133,7 +133,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
index e131f9e..6b8b667 100644
--- a/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/FieldInstruction.java
@@ -11,7 +11,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.AbstractFieldSet;
import com.android.tools.r8.ir.analysis.fieldvalueanalysis.ConcreteMutableFieldSet;
@@ -61,19 +61,19 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
return instructionInstanceCanThrow(appView, context, SideEffectAssumption.NONE);
}
public AbstractError instructionInstanceCanThrow(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
DexEncodedField resolvedField;
if (appView.enableWholeProgramOptimizations()) {
// TODO(b/123857022): Should be possible to use definitionFor().
resolvedField = appView.appInfo().resolveField(field).getResolvedField();
} else {
// In D8, only allow the field in the same context.
- if (field.holder != context) {
+ if (field.holder != context.getHolderType()) {
return AbstractError.top();
}
// Note that, in D8, we are not using AppInfo#resolveField to avoid traversing the hierarchy.
@@ -138,7 +138,7 @@
if (field.holder.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet())) {
return AbstractError.top();
}
@@ -153,7 +153,7 @@
}
@Override
- public AbstractFieldSet readSet(AppView<?> appView, DexType context) {
+ public AbstractFieldSet readSet(AppView<?> appView, ProgramMethod context) {
if (instructionMayTriggerMethodInvocation(appView, context)) {
// This may trigger class initialization, which could potentially read any field.
return UnknownFieldSet.getInstance();
@@ -228,7 +228,7 @@
}
@Override
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
assert isFieldGet();
DexEncodedField field = appView.appInfo().resolveField(getField()).getResolvedField();
if (field != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/InitClass.java b/src/main/java/com/android/tools/r8/ir/code/InitClass.java
index 02ee0eb..14d9a56 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InitClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InitClass.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
@@ -78,7 +79,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -92,14 +93,14 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
if (!isTypeVisibleFromContext(appView, context, clazz)) {
return AbstractError.top();
}
if (clazz.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet())) {
return AbstractError.top();
}
@@ -108,24 +109,24 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(appView, context).isThrowing();
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
if (appView.enableWholeProgramOptimizations()) {
// In R8, check if the class initialization of `clazz` or any of its ancestor types may have
// side effects.
return clazz.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet());
} else {
// In D8, this instruction may trigger class initialization if `clazz` is different from the
// current context.
- return clazz != context;
+ return clazz != context.getHolderType();
}
}
@@ -146,8 +147,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInitClass(clazz, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInitClass(clazz, context.getHolder());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java
index e78d3a7..9077c97 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceFieldInstruction.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.Instruction.SideEffectAssumption;
public interface InstanceFieldInstruction {
@@ -17,7 +17,7 @@
Value object();
boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption);
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption);
FieldInstruction asFieldInstruction();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index 3050da7..12dfa1d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -116,7 +117,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(appView, context, assumption).isThrowing();
}
@@ -127,7 +128,7 @@
// * IncompatibleClassChangeError (instance-* instruction for static fields)
// * IllegalAccessError (not visible from the access context)
// * NullPointerException (null receiver)
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
@@ -151,8 +152,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInstanceGet(getField(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInstanceGet(getField(), context.getHolder());
}
@Override
@@ -204,7 +205,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return object() == value;
}
@@ -221,7 +222,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -230,7 +231,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
index c18e3c5..3d7ae52 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -86,8 +87,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInstanceOf(type, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInstanceOf(type, context.getHolder());
}
@Override
@@ -117,7 +118,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
index b998022..84ea9dc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstancePut.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -115,7 +116,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
if (appView.appInfo().hasLiveness()) {
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfoWithLiveness = appViewWithLiveness.appInfo();
@@ -143,7 +144,7 @@
// * IllegalAccessError (not visible from the access context)
// * NullPointerException (null receiver)
// * not read at all
- boolean haveSideEffects = instructionMayHaveSideEffects(appView, code.method().holder());
+ boolean haveSideEffects = instructionMayHaveSideEffects(appView, code.context());
assert appView.enableWholeProgramOptimizations() || haveSideEffects
: "Expected instance-put instruction to have side effects in D8";
return !haveSideEffects;
@@ -191,8 +192,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInstancePut(getField(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInstancePut(getField(), context.getHolder());
}
@Override
@@ -233,7 +234,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return object() == value;
}
@@ -250,7 +251,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -259,7 +260,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index b280728..bd8d7fe 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -139,7 +140,7 @@
return oldOutValue;
}
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
assert hasOutValue();
return UnknownValue.getInstance();
}
@@ -532,7 +533,8 @@
return false;
}
- public boolean isBlockLocalInstructionWithoutSideEffects(AppView<?> appView, DexType context) {
+ public boolean isBlockLocalInstructionWithoutSideEffects(
+ AppView<?> appView, ProgramMethod context) {
return definesBlockLocalValue() && !instructionMayHaveSideEffects(appView, context);
}
@@ -570,12 +572,12 @@
return instructionTypeCanThrow();
}
- public boolean instructionMayHaveSideEffects(AppView<?> appView, DexType context) {
+ public boolean instructionMayHaveSideEffects(AppView<?> appView, ProgramMethod context) {
return instructionMayHaveSideEffects(appView, context, SideEffectAssumption.NONE);
}
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow();
}
@@ -584,9 +586,9 @@
* indirectly (e.g., via class initialization).
*/
public abstract boolean instructionMayTriggerMethodInvocation(
- AppView<?> appView, DexType context);
+ AppView<?> appView, ProgramMethod context);
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
return instructionInstanceCanThrow() ? AbstractError.top() : AbstractError.bottom();
}
@@ -601,7 +603,7 @@
* Returns an abstraction of the set of fields that may possibly be read as a result of executing
* this instruction.
*/
- public AbstractFieldSet readSet(AppView<?> appView, DexType context) {
+ public AbstractFieldSet readSet(AppView<?> appView, ProgramMethod context) {
if (instructionMayTriggerMethodInvocation(appView, context)
&& instructionMayHaveSideEffects(appView, context)) {
return UnknownFieldSet.getInstance();
@@ -1378,7 +1380,7 @@
* <p>The type is used to judge visibility constraints and also for dispatch decisions.
*/
public abstract ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context);
public abstract void insertLoadAndStores(InstructionListIterator it, LoadStoreHelper helper);
@@ -1432,7 +1434,7 @@
* @return true if the instruction throws NullPointerException if value is null at runtime, false
* otherwise.
*/
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return false;
}
@@ -1460,7 +1462,7 @@
*/
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java b/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
index c3fec64..29b8a3b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeCustom.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -165,7 +166,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forInvokeCustom();
}
@@ -196,7 +197,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return true;
}
}
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 e492db1..edf535f 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
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -121,24 +122,24 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, DexType invocationContext) {
+ public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
DexMethod invokedMethod = getInvokedMethod();
if (appView.appInfo().hasLiveness()) {
AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- DexEncodedMethod result = appInfo.lookupDirectTarget(invokedMethod, invocationContext);
+ DexEncodedMethod result = appInfo.lookupDirectTarget(invokedMethod, context);
assert verifyD8LookupResult(
- result, appView.appInfo().lookupDirectTargetOnItself(invokedMethod, invocationContext));
+ result, appView.appInfo().lookupDirectTargetOnItself(invokedMethod, context));
return result;
}
// In D8, we can treat invoke-direct instructions as having a single target if the invoke is
// targeting a method in the enclosing class.
- return appView.appInfo().lookupDirectTargetOnItself(invokedMethod, invocationContext);
+ return appView.appInfo().lookupDirectTargetOnItself(invokedMethod, context);
}
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeDirect(getInvokedMethod(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeDirect(getInvokedMethod(), context.getHolder());
}
@Override
@@ -149,7 +150,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -159,7 +160,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
if (appView.options().debug) {
return true;
}
@@ -217,8 +218,8 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- DexEncodedMethod method = code.method();
- if (instructionMayHaveSideEffects(appView, method.holder())) {
+ ProgramMethod context = code.context();
+ if (instructionMayHaveSideEffects(appView, context)) {
return false;
}
@@ -236,7 +237,7 @@
if (appView.dexItemFactory().isConstructor(invoke.getInvokedMethod())
&& invoke.getReceiver() == getReceiver()) {
// If another constructor call than `this` is found, then it must not have side effects.
- if (invoke.instructionMayHaveSideEffects(appView, method.holder())) {
+ if (invoke.instructionMayHaveSideEffects(appView, context)) {
return false;
}
if (otherInitCalls == null) {
@@ -267,7 +268,7 @@
}
@Override
- public AbstractFieldSet readSet(AppView<?> appView, DexType context) {
+ public AbstractFieldSet readSet(AppView<?> appView, ProgramMethod context) {
DexMethod invokedMethod = getInvokedMethod();
// Trivial instance initializers do not read any fields.
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
index e9f3063..017e172 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeInterface.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -86,14 +87,14 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, DexType invocationContext) {
+ public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
if (appView.appInfo().hasLiveness()) {
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
return appViewWithLiveness
.appInfo()
.lookupSingleVirtualTarget(
getInvokedMethod(),
- invocationContext,
+ context,
true,
appView,
TypeAnalysis.getRefinedReceiverType(appViewWithLiveness, this),
@@ -104,8 +105,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeInterface(getInvokedMethod(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeInterface(getInvokedMethod(), context.getHolder());
}
@Override
@@ -116,7 +117,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index 6c9fb6f..36398d5 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -28,12 +28,9 @@
import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
import com.android.tools.r8.ir.regalloc.RegisterAllocator;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.SetUtils;
-import com.google.common.collect.Sets;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.BitSet;
-import java.util.Collection;
import java.util.List;
-import java.util.Set;
public abstract class InvokeMethod extends Invoke {
@@ -76,23 +73,22 @@
// In subclasses, e.g., invoke-virtual or invoke-super, use a narrower receiver type by using
// receiver type and calling context---the holder of the method where the current invocation is.
// TODO(b/140204899): Refactor lookup methods to be defined in a single place.
- public abstract DexEncodedMethod lookupSingleTarget(
- AppView<?> appView, DexType invocationContext);
+ public abstract DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context);
public final ProgramMethod lookupSingleProgramTarget(AppView<?> appView, ProgramMethod context) {
- DexEncodedMethod singleTarget = lookupSingleTarget(appView, context.getHolderType());
+ DexEncodedMethod singleTarget = lookupSingleTarget(appView, context);
return singleTarget != null ? singleTarget.asProgramMethod(appView) : null;
}
// TODO(b/140204899): Refactor lookup methods to be defined in a single place.
- public Collection<DexEncodedMethod> lookupTargets(
- AppView<AppInfoWithLiveness> appView, DexType invocationContext) {
+ public ProgramMethodSet lookupProgramDispatchTargets(
+ AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
if (!getInvokedMethod().holder.isClassType()) {
return null;
}
if (!isInvokeMethodWithDynamicDispatch()) {
- DexEncodedMethod singleTarget = lookupSingleTarget(appView, invocationContext);
- return singleTarget != null ? SetUtils.newIdentityHashSet(singleTarget) : null;
+ ProgramMethod singleTarget = lookupSingleProgramTarget(appView, context);
+ return singleTarget != null ? ProgramMethodSet.create(singleTarget) : null;
}
DexProgramClass refinedReceiverUpperBound =
asProgramClassOrNull(
@@ -118,22 +114,25 @@
if (refinedReceiverUpperBound != null) {
lookupResult =
resolutionResult.lookupVirtualDispatchTargets(
- appView.definitionForProgramType(invocationContext),
+ context.getHolder(),
appView.withLiveness().appInfo(),
refinedReceiverUpperBound,
refinedReceiverLowerBound);
} else {
lookupResult =
resolutionResult.lookupVirtualDispatchTargets(
- appView.definitionForProgramType(invocationContext),
- appView.withLiveness().appInfo());
+ context.getHolder(), appView.withLiveness().appInfo());
}
if (lookupResult.isLookupResultFailure()) {
return null;
}
- Set<DexEncodedMethod> result = Sets.newIdentityHashSet();
+ ProgramMethodSet result = ProgramMethodSet.create();
lookupResult.forEach(
- methodTarget -> result.add(methodTarget.getDefinition()),
+ methodTarget -> {
+ if (methodTarget.isProgramMethod()) {
+ result.add(methodTarget.asProgramMethod());
+ }
+ },
lambda -> {
// TODO(b/150277553): Support lambda targets.
});
@@ -195,17 +194,17 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return true;
}
@Override
- public AbstractFieldSet readSet(AppView<?> appView, DexType context) {
+ public AbstractFieldSet readSet(AppView<?> appView, ProgramMethod context) {
return LibraryMethodReadSetModeling.getModeledReadSetOrUnknown(this, appView.dexItemFactory());
}
@Override
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
assert hasOutValue();
DexEncodedMethod method = lookupSingleTarget(appView, context);
if (method != null) {
@@ -224,7 +223,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
DexEncodedMethod singleTarget = lookupSingleTarget(appView, context);
if (singleTarget != null) {
BitSet nonNullParamOrThrow = singleTarget.getOptimizationInfo().getNonNullParamOrThrow();
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
index 00ffbe1..83799e7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
@@ -53,7 +53,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return value == getReceiver() || super.throwsNpeIfValueIsNull(value, appView, context);
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java
index 4006bd7..1e41503 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMultiNewArray.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -77,8 +78,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeMultiNewArray(type, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeMultiNewArray(type, context.getHolder());
}
@Override
@@ -113,7 +114,7 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
DexType baseType = type.isArrayType() ? type.toBaseType(appView.dexItemFactory()) : type;
if (baseType.isPrimitiveType()) {
// Primitives types are known to be present and accessible.
@@ -123,7 +124,7 @@
assert baseType.isReferenceType();
- if (baseType == context) {
+ if (baseType == context.getHolderType()) {
// The enclosing type is known to be present and accessible.
return instructionInstanceCanThrowNegativeArraySizeException();
}
@@ -172,7 +173,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
// Check if the instruction has a side effect on the locals environment.
if (hasOutValue() && outValue().hasLocalInfo()) {
assert appView.options().debug;
@@ -184,11 +185,11 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java b/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java
index 3f5a1ab..1d6547e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeNewArray.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -106,8 +107,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeNewArray(type, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeNewArray(type, context.getHolder());
}
@Override
@@ -140,7 +141,7 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
DexType baseType = type.isArrayType() ? type.toBaseType(appView.dexItemFactory()) : type;
if (baseType.isPrimitiveType()) {
// Primitives types are known to be present and accessible.
@@ -150,7 +151,7 @@
assert baseType.isReferenceType();
- if (baseType == context) {
+ if (baseType == context.getHolderType()) {
// The enclosing type is known to be present and accessible.
return AbstractError.bottom();
}
@@ -185,7 +186,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
// Check if the instruction has a side effect on the locals environment.
if (hasOutValue() && outValue().hasLocalInfo()) {
assert appView.options().debug;
@@ -197,11 +198,11 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java b/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
index 8d46da1..6a1e8a2 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokePolymorphic.java
@@ -23,7 +23,7 @@
import com.android.tools.r8.ir.optimize.InliningConstraints;
import com.android.tools.r8.ir.optimize.inliner.WhyAreYouNotInliningReporter;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import java.util.Collection;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.List;
public class InvokePolymorphic extends InvokeMethod {
@@ -120,22 +120,22 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, DexType invocationContext) {
+ public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
// TODO(herhut): Implement lookup target for invokePolymorphic.
return null;
}
@Override
- public Collection<DexEncodedMethod> lookupTargets(
- AppView<AppInfoWithLiveness> appView, DexType invocationContext) {
+ public ProgramMethodSet lookupProgramDispatchTargets(
+ AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
// TODO(herhut): Implement lookup target for invokePolymorphic.
return null;
}
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokePolymorphic(getInvokedMethod(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokePolymorphic(getInvokedMethod(), context.getHolder());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
index 5ea6e46..2b64167 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeStatic.java
@@ -103,13 +103,13 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, DexType invocationContext) {
+ public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
DexMethod invokedMethod = getInvokedMethod();
if (appView.appInfo().hasLiveness()) {
AppInfoWithLiveness appInfo = appView.appInfo().withLiveness();
- DexEncodedMethod result = appInfo.lookupStaticTarget(invokedMethod, invocationContext);
+ DexEncodedMethod result = appInfo.lookupStaticTarget(invokedMethod, context);
assert verifyD8LookupResult(
- result, appView.appInfo().lookupStaticTargetOnItself(invokedMethod, invocationContext));
+ result, appView.appInfo().lookupStaticTargetOnItself(invokedMethod, context));
return result;
}
// Allow optimizing static library invokes in D8.
@@ -120,13 +120,13 @@
}
// In D8, we can treat invoke-static instructions as having a single target if the invoke is
// targeting a method in the enclosing class.
- return appView.appInfo().lookupStaticTargetOnItself(invokedMethod, invocationContext);
+ return appView.appInfo().lookupStaticTargetOnItself(invokedMethod, context);
}
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeStatic(getInvokedMethod(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeStatic(getInvokedMethod(), context.getHolder());
}
@Override
@@ -148,7 +148,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -158,7 +158,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
if (!appView.enableWholeProgramOptimizations()) {
return true;
}
@@ -207,7 +207,7 @@
appView,
// Types that are a super type of `context` are guaranteed to be initialized
// already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet());
}
@@ -216,6 +216,6 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
index 588a0f1..0df812c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeSuper.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -93,12 +94,12 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, DexType invocationContext) {
- if (appView.appInfo().hasLiveness() && invocationContext != null) {
+ public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
+ if (appView.appInfo().hasLiveness() && context != null) {
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfo = appViewWithLiveness.appInfo();
- if (appInfo.isSubtype(invocationContext, getInvokedMethod().holder)) {
- return appInfo.lookupSuperTarget(getInvokedMethod(), invocationContext);
+ if (appInfo.isSubtype(context.getHolderType(), getInvokedMethod().holder)) {
+ return appInfo.lookupSuperTarget(getInvokedMethod(), context);
}
}
return null;
@@ -106,14 +107,14 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeSuper(getInvokedMethod(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeSuper(getInvokedMethod(), context.getHolder());
}
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
index b9a0765..464fdc2 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeVirtual.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -90,19 +91,19 @@
}
@Override
- public DexEncodedMethod lookupSingleTarget(AppView<?> appView, DexType invocationContext) {
- return lookupSingleTarget(appView, invocationContext, getInvokedMethod(), getReceiver());
+ public DexEncodedMethod lookupSingleTarget(AppView<?> appView, ProgramMethod context) {
+ return lookupSingleTarget(appView, context, getInvokedMethod(), getReceiver());
}
public static DexEncodedMethod lookupSingleTarget(
- AppView<?> appView, DexType invocationContext, DexMethod method, Value receiver) {
+ AppView<?> appView, ProgramMethod context, DexMethod method, Value receiver) {
if (appView.appInfo().hasLiveness()) {
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
return appViewWithLiveness
.appInfo()
.lookupSingleVirtualTarget(
method,
- invocationContext,
+ context,
false,
appView,
TypeAnalysis.getRefinedReceiverType(appViewWithLiveness, method, receiver),
@@ -126,8 +127,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forInvokeVirtual(getInvokedMethod(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forInvokeVirtual(getInvokedMethod(), context.getHolder());
}
@Override
@@ -138,7 +139,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -148,7 +149,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
if (!appView.enableWholeProgramOptimizations()) {
return true;
}
@@ -205,6 +206,6 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/JumpInstruction.java b/src/main/java/com/android/tools/r8/ir/code/JumpInstruction.java
index 8e1e347..9536919 100644
--- a/src/main/java/com/android/tools/r8/ir/code/JumpInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/JumpInstruction.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
import java.util.List;
@@ -48,7 +48,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forJumpInstruction();
}
@@ -58,7 +58,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Load.java b/src/main/java/com/android/tools/r8/ir/code/Load.java
index 9886690..eee3bef 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Load.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Load.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -63,7 +64,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forLoad();
}
@@ -99,7 +100,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Monitor.java b/src/main/java/com/android/tools/r8/ir/code/Monitor.java
index 598bc6c..f779651 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Monitor.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Monitor.java
@@ -12,7 +12,7 @@
import com.android.tools.r8.code.MonitorExit;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -109,7 +109,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forMonitor();
}
@@ -141,7 +141,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
return object() == value;
}
@@ -156,7 +156,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Move.java b/src/main/java/com/android/tools/r8/ir/code/Move.java
index 24e831c..f531071 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Move.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Move.java
@@ -8,7 +8,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -99,7 +99,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forMove();
}
@@ -119,7 +119,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/MoveException.java b/src/main/java/com/android/tools/r8/ir/code/MoveException.java
index 9f21f17..4c87b70 100644
--- a/src/main/java/com/android/tools/r8/ir/code/MoveException.java
+++ b/src/main/java/com/android/tools/r8/ir/code/MoveException.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -87,7 +88,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forMoveException();
}
@@ -121,7 +122,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
index bd5c34f..c730efc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
@@ -107,8 +108,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forNewArrayEmpty(type, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forNewArrayEmpty(type, context.getHolder());
}
@Override
@@ -139,7 +140,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
index fd6cf65..aaa27dd 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayFilledData.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AbstractError;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -101,7 +101,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forNewArrayFilledData();
}
@@ -116,7 +116,7 @@
}
@Override
- public AbstractError instructionInstanceCanThrow(AppView<?> appView, DexType context) {
+ public AbstractError instructionInstanceCanThrow(AppView<?> appView, ProgramMethod context) {
if (appView.options().debug) {
return AbstractError.top();
}
@@ -130,7 +130,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
// Treat the instruction as possibly having side-effects if it may throw or the array is used.
if (instructionInstanceCanThrow(appView, context).isThrowing()
|| src().numberOfAllUsers() > 1) {
@@ -145,12 +145,12 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index e30cdf1..5141ff7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
@@ -100,8 +101,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forNewInstance(clazz, invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forNewInstance(clazz, context.getHolder());
}
@Override
@@ -132,7 +133,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -142,7 +143,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
DexItemFactory dexItemFactory = appView.dexItemFactory();
if (!appView.enableWholeProgramOptimizations()) {
return !(dexItemFactory.libraryTypesAssumedToBePresent.contains(clazz)
@@ -175,7 +176,7 @@
if (definition.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet())) {
return true;
}
@@ -196,7 +197,7 @@
@Override
public boolean canBeDeadCode(AppView<?> appView, IRCode code) {
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
public void markNoSpilling() {
@@ -208,19 +209,19 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
if (appView.enableWholeProgramOptimizations()) {
// In R8, check if the class initialization of the holder or any of its ancestor types may
// have side effects.
return clazz.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet());
} else {
// In D8, this instruction may trigger class initialization if the holder of the field is
// different from the current context.
- return clazz != context;
+ return clazz != context.getHolderType();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Pop.java b/src/main/java/com/android/tools/r8/ir/code/Pop.java
index ab07480..0124c45 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Pop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Pop.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -66,7 +66,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forPop();
}
@@ -97,7 +97,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Return.java b/src/main/java/com/android/tools/r8/ir/code/Return.java
index 0adf292..19c9887 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Return.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Return.java
@@ -11,7 +11,7 @@
import com.android.tools.r8.code.ReturnWide;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -110,7 +110,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forReturn();
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticFieldInstruction.java b/src/main/java/com/android/tools/r8/ir/code/StaticFieldInstruction.java
index 286b470..9b0e28a 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticFieldInstruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticFieldInstruction.java
@@ -5,7 +5,7 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.Instruction.SideEffectAssumption;
public interface StaticFieldInstruction {
@@ -14,10 +14,10 @@
Value outValue();
- boolean instructionMayHaveSideEffects(AppView<?> appView, DexType context);
+ boolean instructionMayHaveSideEffects(AppView<?> appView, ProgramMethod context);
boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption);
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption);
FieldInstruction asFieldInstruction();
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
index de66cba..ec7c00d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -136,13 +137,13 @@
}
@Override
- public boolean instructionMayHaveSideEffects(AppView<?> appView, DexType context) {
+ public boolean instructionMayHaveSideEffects(AppView<?> appView, ProgramMethod context) {
return instructionMayHaveSideEffects(appView, context, SideEffectAssumption.NONE);
}
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
return instructionInstanceCanThrow(appView, context, assumption).isThrowing();
}
@@ -153,7 +154,7 @@
// * IncompatibleClassChangeError (static-* instruction for instance fields)
// * IllegalAccessError (not visible from the access context)
// * side-effects in <clinit>
- return !instructionMayHaveSideEffects(appView, code.method().holder());
+ return !instructionMayHaveSideEffects(appView, code.context());
}
@Override
@@ -177,8 +178,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forStaticGet(getField(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forStaticGet(getField(), context.getHolder());
}
@Override
@@ -226,7 +227,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -240,7 +241,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
DexType holder = getField().holder;
if (appView.enableWholeProgramOptimizations()) {
// In R8, check if the class initialization of the holder or any of its ancestor types may
@@ -248,12 +249,12 @@
return holder.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet());
} else {
// In D8, this instruction may trigger class initialization if the holder of the field is
// different from the current context.
- return holder != context;
+ return holder != context.getHolderType();
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticPut.java b/src/main/java/com/android/tools/r8/ir/code/StaticPut.java
index 29cd30d..9a8f158 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticPut.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticPut.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.Query;
@@ -95,7 +96,7 @@
@Override
public boolean instructionMayHaveSideEffects(
- AppView<?> appView, DexType context, SideEffectAssumption assumption) {
+ AppView<?> appView, ProgramMethod context, SideEffectAssumption assumption) {
if (appView.appInfo().hasLiveness()) {
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
AppInfoWithLiveness appInfoWithLiveness = appViewWithLiveness.appInfo();
@@ -140,7 +141,7 @@
// * IllegalAccessError (not visible from the access context)
// * side-effects in <clinit>
// * not read _globally_
- boolean haveSideEffects = instructionMayHaveSideEffects(appView, code.method().holder());
+ boolean haveSideEffects = instructionMayHaveSideEffects(appView, code.context());
assert appView.enableWholeProgramOptimizations() || haveSideEffects
: "Expected static-put instruction to have side effects in D8";
return !haveSideEffects;
@@ -188,8 +189,8 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
- return inliningConstraints.forStaticPut(getField(), invocationContext);
+ InliningConstraints inliningConstraints, ProgramMethod context) {
+ return inliningConstraints.forStaticPut(getField(), context.getHolder());
}
@Override
@@ -227,7 +228,7 @@
@Override
public boolean definitelyTriggersClassInitialization(
DexType clazz,
- DexType context,
+ ProgramMethod context,
AppView<?> appView,
Query mode,
AnalysisAssumption assumption) {
@@ -236,7 +237,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
DexType holder = getField().holder;
if (appView.enableWholeProgramOptimizations()) {
// In R8, check if the class initialization of the holder or any of its ancestor types may
@@ -244,12 +245,12 @@
return holder.classInitializationMayHaveSideEffects(
appView,
// Types that are a super type of `context` are guaranteed to be initialized already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(context.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet());
} else {
// In D8, this instruction may trigger class initialization if the holder of the field is
// different from the current context.
- return holder != context;
+ return holder != context.getHolderType();
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Store.java b/src/main/java/com/android/tools/r8/ir/code/Store.java
index 4fe63c0..ccd57ea 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Store.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Store.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -64,7 +65,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forStore();
}
@@ -111,7 +112,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Swap.java b/src/main/java/com/android/tools/r8/ir/code/Swap.java
index 2515934..5dfa623 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Swap.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Swap.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.cf.code.CfStackInstruction.Opcode;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
@@ -89,7 +89,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forSwap();
}
@@ -114,7 +114,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Throw.java b/src/main/java/com/android/tools/r8/ir/code/Throw.java
index 2b6b80d..6f47788 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Throw.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Throw.java
@@ -7,7 +7,7 @@
import com.android.tools.r8.cf.code.CfThrow;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.conversion.CfBuilder;
import com.android.tools.r8.ir.conversion.DexBuilder;
@@ -72,7 +72,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forThrow();
}
@@ -87,7 +87,7 @@
}
@Override
- public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, DexType context) {
+ public boolean throwsNpeIfValueIsNull(Value value, AppView<?> appView, ProgramMethod context) {
if (exception() == value) {
return true;
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Unop.java b/src/main/java/com/android/tools/r8/ir/code/Unop.java
index 1765626..9c65c4e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Unop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Unop.java
@@ -6,7 +6,7 @@
import com.android.tools.r8.cf.LoadStoreHelper;
import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.InliningConstraints;
@@ -47,7 +47,7 @@
@Override
public ConstraintWithTarget inliningConstraint(
- InliningConstraints inliningConstraints, DexType invocationContext) {
+ InliningConstraints inliningConstraints, ProgramMethod context) {
return inliningConstraints.forUnop();
}
@@ -68,7 +68,7 @@
}
@Override
- public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, DexType context) {
+ public boolean instructionMayTriggerMethodInvocation(AppView<?> appView, ProgramMethod context) {
return false;
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index bbe7f7f..48ffd21 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -20,6 +20,7 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -891,7 +892,7 @@
return definition.isOutConstant() && !hasLocalInfo();
}
- public AbstractValue getAbstractValue(AppView<?> appView, DexType context) {
+ public AbstractValue getAbstractValue(AppView<?> appView, ProgramMethod context) {
if (!appView.enableWholeProgramOptimizations()) {
return UnknownValue.getInstance();
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
index 4855f96..b678f63 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
@@ -165,10 +165,9 @@
}
private void processInvoke(Invoke.Type originalType, DexMethod originalMethod) {
- ProgramMethod source = currentMethod.getProgramMethod();
- DexMethod context = source.getReference();
+ ProgramMethod context = currentMethod.getProgramMethod();
GraphLenseLookupResult result =
- appView.graphLense().lookupMethod(originalMethod, context, originalType);
+ appView.graphLense().lookupMethod(originalMethod, context.getReference(), originalType);
DexMethod method = result.getMethod();
Invoke.Type type = result.getType();
if (type == Invoke.Type.INTERFACE || type == Invoke.Type.VIRTUAL) {
@@ -176,14 +175,14 @@
ResolutionResult resolutionResult = appView.appInfo().resolveMethod(method.holder, method);
DexEncodedMethod target = resolutionResult.getSingleTarget();
if (target != null) {
- processInvokeWithDynamicDispatch(type, target, context.holder);
+ processInvokeWithDynamicDispatch(type, target, context);
}
} else {
ProgramMethod singleTarget =
- appView.appInfo().lookupSingleProgramTarget(type, method, context.holder, appView);
+ appView.appInfo().lookupSingleProgramTarget(type, method, context, appView);
if (singleTarget != null) {
- assert !source.getDefinition().isBridge()
- || singleTarget.getDefinition() != source.getDefinition();
+ assert !context.getDefinition().isBridge()
+ || singleTarget.getDefinition() != context.getDefinition();
// For static invokes, the class could be initialized.
if (type == Invoke.Type.STATIC) {
addClassInitializerTarget(singleTarget.getHolder());
@@ -194,7 +193,7 @@
}
private void processInvokeWithDynamicDispatch(
- Invoke.Type type, DexEncodedMethod encodedTarget, DexType context) {
+ Invoke.Type type, DexEncodedMethod encodedTarget, ProgramMethod context) {
DexMethod target = encodedTarget.method;
DexClass clazz = appView.definitionFor(target.holder);
if (clazz == null) {
@@ -219,7 +218,7 @@
if (resolution.isVirtualTarget()) {
LookupResult lookupResult =
resolution.lookupVirtualDispatchTargets(
- appView.definitionForProgramType(context), appView.appInfo());
+ context.getHolder(), appView.appInfo());
if (lookupResult.isLookupResultSuccess()) {
ProgramMethodSet targets = ProgramMethodSet.create();
lookupResult
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index acb21d7..24b3df4 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1284,7 +1284,7 @@
if (devirtualizer != null) {
assert code.verifyTypes(appView);
timing.begin("Devirtualize invoke interface");
- devirtualizer.devirtualizeInvokeInterface(code, holder);
+ devirtualizer.devirtualizeInvokeInterface(code);
timing.end();
}
@@ -1372,7 +1372,7 @@
timing.begin("Optimize class initializers");
ClassInitializerDefaultsResult classInitializerDefaultsResult =
- classInitializerDefaultsOptimization.optimize(method, code, feedback);
+ classInitializerDefaultsOptimization.optimize(code, feedback);
timing.end();
if (Log.ENABLED) {
@@ -1637,11 +1637,11 @@
if (method.isInitializer()) {
if (method.isClassInitializer()) {
StaticFieldValueAnalysis.run(
- appView, code, classInitializerDefaultsResult, feedback, code.method(), timing);
+ appView, code, classInitializerDefaultsResult, feedback, timing);
} else {
instanceFieldInitializationInfos =
InstanceFieldValueAnalysis.run(
- appView, code, classInitializerDefaultsResult, feedback, code.method(), timing);
+ appView, code, classInitializerDefaultsResult, feedback, timing);
}
}
methodOptimizationInfoCollector.collectMethodOptimizationInfo(
@@ -1716,7 +1716,7 @@
ProgramMethod method = code.context();
ConstraintWithTarget state =
shouldComputeInliningConstraint(method)
- ? inliner.computeInliningConstraint(code, method)
+ ? inliner.computeInliningConstraint(code)
: ConstraintWithTarget.NEVER;
feedback.markProcessed(method.getDefinition(), state);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index a640fb6..a45bc26 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -136,7 +136,7 @@
appView
.appInfo()
.withClassHierarchy()
- .lookupSuperTarget(invoke.getInvokedMethod(), code.method().holder());
+ .lookupSuperTarget(invoke.getInvokedMethod(), code.context());
// Final methods can be rewritten as a normal invoke.
if (dexEncodedMethod != null && !dexEncodedMethod.isFinal()) {
DexMethod retargetMethod =
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 5d494bb..a7827eb 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -317,7 +317,7 @@
DexEncodedMethod dexEncodedMethod =
appView
.appInfo()
- .lookupSuperTarget(invokeSuper.getInvokedMethod(), code.method().holder());
+ .lookupSuperTarget(invokeSuper.getInvokedMethod(), code.context());
if (dexEncodedMethod != null) {
DexClass dexClass = appView.definitionFor(dexEncodedMethod.holder());
if (dexClass != null && dexClass.isLibraryClass()) {
@@ -1123,7 +1123,7 @@
DexMethod method = appView.graphLense().getOriginalMethodSignature(referencedFrom);
Origin origin = getMethodOrigin(method);
MethodPosition position = new MethodPosition(method);
- options.warningMissingTypeForDesugar(origin, position, missing, method.holder);
+ options.warningMissingTypeForDesugar(origin, position, missing, method);
}
private Origin getMethodOrigin(DexMethod method) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 05c9c66..ab75872 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -75,7 +75,7 @@
LambdaClass(
LambdaRewriter rewriter,
- DexType accessedFrom,
+ ProgramMethod accessedFrom,
DexType lambdaClassType,
LambdaDescriptor descriptor) {
assert rewriter != null;
@@ -108,16 +108,16 @@
// Generate unique lambda class type for lambda descriptor and instantiation point context.
static DexType createLambdaClassType(
- LambdaRewriter rewriter, DexType accessedFrom, LambdaDescriptor match) {
+ LambdaRewriter rewriter, ProgramMethod accessedFrom, LambdaDescriptor match) {
return createLambdaClassType(rewriter.getFactory(), accessedFrom, match);
}
public static DexType createLambdaClassType(
- DexItemFactory factory, DexType accessedFrom, LambdaDescriptor match) {
+ DexItemFactory factory, ProgramMethod accessedFrom, LambdaDescriptor match) {
StringBuilder lambdaClassDescriptor = new StringBuilder("L");
// We always create lambda class in the same package where it is referenced.
- String packageDescriptor = accessedFrom.getPackageDescriptor();
+ String packageDescriptor = accessedFrom.getHolderType().getPackageDescriptor();
if (!packageDescriptor.isEmpty()) {
lambdaClassDescriptor.append(packageDescriptor).append('/');
}
@@ -129,7 +129,7 @@
// just add the name of this type to make lambda class name unique.
// It also helps link the class lambda originated from in some cases.
if (match.delegatesToLambdaImplMethod() || match.needsAccessor(accessedFrom)) {
- lambdaClassDescriptor.append(accessedFrom.getName()).append('$');
+ lambdaClassDescriptor.append(accessedFrom.getHolderType().getName()).append('$');
}
// Add unique lambda descriptor id
@@ -337,7 +337,7 @@
// Creates a delegation target for this particular lambda class. Note that we
// should always be able to create targets for the lambdas we support.
- private Target createTarget(DexType accessedFrom) {
+ private Target createTarget(ProgramMethod accessedFrom) {
if (descriptor.delegatesToLambdaImplMethod()) {
return createLambdaImplMethodTarget(accessedFrom);
}
@@ -360,14 +360,14 @@
}
}
- private Target createLambdaImplMethodTarget(DexType accessedFrom) {
+ private Target createLambdaImplMethodTarget(ProgramMethod accessedFrom) {
DexMethodHandle implHandle = descriptor.implHandle;
assert implHandle != null;
DexMethod implMethod = implHandle.asMethod();
// Lambda$ method. We must always find it.
- assert implMethod.holder == accessedFrom;
- assert descriptor.verifyTargetFoundInClass(accessedFrom);
+ assert implMethod.holder == accessedFrom.getHolderType();
+ assert descriptor.verifyTargetFoundInClass(accessedFrom.getHolderType());
if (implHandle.type.isInvokeStatic()) {
SingleResolutionResult resolution =
rewriter.getAppInfo().resolveMethod(implMethod.holder, implMethod).asSingleResolution();
@@ -412,7 +412,7 @@
// Create targets for instance method referenced directly without
// lambda$ methods. It may require creation of accessors in some cases.
- private Target createInstanceMethodTarget(DexType accessedFrom) {
+ private Target createInstanceMethodTarget(ProgramMethod accessedFrom) {
assert descriptor.implHandle.type.isInvokeInstance() ||
descriptor.implHandle.type.isInvokeDirect();
@@ -437,14 +437,15 @@
DexMethod accessorMethod =
rewriter
.getFactory()
- .createMethod(accessedFrom, accessorProto, generateUniqueLambdaMethodName());
+ .createMethod(
+ accessedFrom.getHolderType(), accessorProto, generateUniqueLambdaMethodName());
return new ClassMethodWithAccessorTarget(accessorMethod);
}
// Create targets for static method referenced directly without
// lambda$ methods. It may require creation of accessors in some cases.
- private Target createStaticMethodTarget(DexType accessedFrom) {
+ private Target createStaticMethodTarget(ProgramMethod accessedFrom) {
assert descriptor.implHandle.type.isInvokeStatic();
if (!descriptor.needsAccessor(accessedFrom)) {
@@ -458,7 +459,7 @@
rewriter
.getFactory()
.createMethod(
- accessedFrom,
+ accessedFrom.getHolderType(),
descriptor.implHandle.asMethod().proto,
generateUniqueLambdaMethodName());
return new ClassMethodWithAccessorTarget(accessorMethod);
@@ -466,7 +467,7 @@
// Create targets for constructor referenced directly without lambda$ methods.
// It may require creation of accessors in some cases.
- private Target createConstructorTarget(DexType accessedFrom) {
+ private Target createConstructorTarget(ProgramMethod accessedFrom) {
DexMethodHandle implHandle = descriptor.implHandle;
assert implHandle != null;
assert implHandle.type.isInvokeConstructor();
@@ -486,12 +487,13 @@
DexMethod accessorMethod =
rewriter
.getFactory()
- .createMethod(accessedFrom, accessorProto, generateUniqueLambdaMethodName());
+ .createMethod(
+ accessedFrom.getHolderType(), accessorProto, generateUniqueLambdaMethodName());
return new ClassMethodWithAccessorTarget(accessorMethod);
}
// Create targets for interface methods.
- private Target createInterfaceMethodTarget(DexType accessedFrom) {
+ private Target createInterfaceMethodTarget(ProgramMethod accessedFrom) {
assert descriptor.implHandle.type.isInvokeInterface();
assert !descriptor.needsAccessor(accessedFrom);
return new NoAccessorMethodTarget(Invoke.Type.INTERFACE);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
index bfc9362..49c19f4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaDescriptor.java
@@ -11,13 +11,13 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
-import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.graph.ProgramMethod;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
@@ -67,7 +67,7 @@
private LambdaDescriptor(
AppInfoWithClassHierarchy appInfo,
- DexType invocationContext,
+ ProgramMethod context,
DexCallSite callSite,
DexString name,
DexProto erasedProto,
@@ -92,8 +92,7 @@
this.captures = captures;
this.interfaces.add(mainInterface);
- DexEncodedMethod targetMethod =
- invocationContext == null ? null : lookupTargetMethod(appInfo, invocationContext);
+ DexEncodedMethod targetMethod = context == null ? null : lookupTargetMethod(appInfo, context);
if (targetMethod != null) {
targetAccessFlags = targetMethod.accessFlags.copy();
targetHolder = targetMethod.holder();
@@ -113,8 +112,8 @@
}
private DexEncodedMethod lookupTargetMethod(
- AppInfoWithClassHierarchy appInfo, DexType invocationContext) {
- assert invocationContext != null;
+ AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
+ assert context != null;
// Find the lambda's impl-method target.
DexMethod method = implHandle.asMethod();
switch (implHandle.type) {
@@ -123,7 +122,7 @@
DexEncodedMethod target =
appInfo.resolveMethod(getImplReceiverType(), method).getSingleTarget();
if (target == null) {
- target = appInfo.lookupDirectTarget(method, invocationContext);
+ target = appInfo.lookupDirectTarget(method, context);
}
assert target == null
|| (implHandle.type.isInvokeInstance() && isInstanceMethod(target))
@@ -133,13 +132,13 @@
}
case INVOKE_STATIC: {
- DexEncodedMethod target = appInfo.lookupStaticTarget(method, invocationContext);
+ DexEncodedMethod target = appInfo.lookupStaticTarget(method, context);
assert target == null || target.accessFlags.isStatic();
return target;
}
case INVOKE_CONSTRUCTOR: {
- DexEncodedMethod target = appInfo.lookupDirectTarget(method, invocationContext);
+ DexEncodedMethod target = appInfo.lookupDirectTarget(method, context);
assert target == null || target.accessFlags.isConstructor();
return target;
}
@@ -187,7 +186,7 @@
}
/** Checks if call site needs a accessor when referenced from `accessedFrom`. */
- boolean needsAccessor(DexType accessedFrom) {
+ boolean needsAccessor(ProgramMethod accessedFrom) {
if (delegatesToLambdaImplMethod()) {
return false;
}
@@ -217,8 +216,10 @@
// because the method being called must be present in method holder,
// and not in one from its supertypes.
boolean accessedFromSamePackage =
- accessedFrom.getPackageDescriptor().equals(
- implHandle.asMethod().holder.getPackageDescriptor());
+ accessedFrom
+ .getHolderType()
+ .getPackageDescriptor()
+ .equals(implHandle.asMethod().holder.getPackageDescriptor());
return !accessedFromSamePackage;
}
@@ -238,7 +239,10 @@
}
boolean accessedFromSamePackage =
- accessedFrom.getPackageDescriptor().equals(targetHolder.getPackageDescriptor());
+ accessedFrom
+ .getHolderType()
+ .getPackageDescriptor()
+ .equals(targetHolder.getPackageDescriptor());
assert flags.isProtected() || accessedFromSamePackage;
return flags.isProtected() && !accessedFromSamePackage;
}
@@ -248,8 +252,8 @@
* information, or null if match failed.
*/
public static LambdaDescriptor tryInfer(
- DexCallSite callSite, AppInfoWithClassHierarchy appInfo, DexProgramClass invocationContext) {
- LambdaDescriptor descriptor = infer(callSite, appInfo, invocationContext.type);
+ DexCallSite callSite, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
+ LambdaDescriptor descriptor = infer(callSite, appInfo, context);
return descriptor == MATCH_FAILED ? null : descriptor;
}
@@ -265,7 +269,7 @@
* information, or MATCH_FAILED if match failed.
*/
static LambdaDescriptor infer(
- DexCallSite callSite, AppInfoWithClassHierarchy appInfo, DexType invocationContext) {
+ DexCallSite callSite, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
if (!isLambdaMetafactoryMethod(callSite, appInfo.dexItemFactory())) {
return LambdaDescriptor.MATCH_FAILED;
}
@@ -309,7 +313,7 @@
LambdaDescriptor match =
new LambdaDescriptor(
appInfo,
- invocationContext,
+ context,
callSite,
funcMethodName,
funcErasedSignature.value,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index 6b41818..2bbfb30 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -138,7 +138,7 @@
*/
public void desugarLambdas(DexEncodedMethod encodedMethod, IRCode code) {
Set<Value> affectedValues = Sets.newIdentityHashSet();
- DexType currentType = encodedMethod.holder();
+ ProgramMethod context = code.context();
ListIterator<BasicBlock> blocks = code.listIterator();
while (blocks.hasNext()) {
BasicBlock block = blocks.next();
@@ -147,8 +147,7 @@
Instruction instruction = instructions.next();
if (instruction.isInvokeCustom()) {
InvokeCustom invoke = instruction.asInvokeCustom();
- LambdaDescriptor descriptor =
- inferLambdaDescriptor(invoke.getCallSite(), encodedMethod.holder());
+ LambdaDescriptor descriptor = inferLambdaDescriptor(invoke.getCallSite(), context);
if (descriptor == LambdaDescriptor.MATCH_FAILED) {
continue;
}
@@ -157,8 +156,8 @@
// during IR processing, and therefore we may need to create it now.
LambdaClass lambdaClass =
getAppView().enableWholeProgramOptimizations()
- ? getKnownLambdaClass(descriptor, currentType)
- : getOrCreateLambdaClass(descriptor, currentType);
+ ? getKnownLambdaClass(descriptor, context)
+ : getOrCreateLambdaClass(descriptor, context);
assert lambdaClass != null;
// We rely on patch performing its work in a way which
@@ -214,7 +213,7 @@
// corresponding to this lambda invocation point.
//
// Returns the lambda descriptor or `MATCH_FAILED`.
- private LambdaDescriptor inferLambdaDescriptor(DexCallSite callSite, DexType invocationContext) {
+ private LambdaDescriptor inferLambdaDescriptor(DexCallSite callSite, ProgramMethod context) {
// We check the map before and after inferring lambda descriptor to minimize time
// spent in synchronized block. As a result we may throw away calculated descriptor
// in rare case when another thread has same call site processed concurrently,
@@ -223,9 +222,7 @@
return descriptor != null
? descriptor
: putIfAbsent(
- knownCallSites,
- callSite,
- LambdaDescriptor.infer(callSite, getAppInfo(), invocationContext));
+ knownCallSites, callSite, LambdaDescriptor.infer(callSite, getAppInfo(), context));
}
private boolean isInMainDexList(DexType type) {
@@ -234,7 +231,8 @@
// Returns a lambda class corresponding to the lambda descriptor and context,
// creates the class if it does not yet exist.
- public LambdaClass getOrCreateLambdaClass(LambdaDescriptor descriptor, DexType accessedFrom) {
+ public LambdaClass getOrCreateLambdaClass(
+ LambdaDescriptor descriptor, ProgramMethod accessedFrom) {
DexType lambdaClassType = LambdaClass.createLambdaClassType(this, accessedFrom, descriptor);
// We check the map twice to to minimize time spent in synchronized block.
LambdaClass lambdaClass = getKnown(knownLambdaClasses, lambdaClassType);
@@ -246,35 +244,36 @@
new LambdaClass(this, accessedFrom, lambdaClassType, descriptor));
if (getAppView().options().isDesugaredLibraryCompilation()) {
DexType rewrittenType =
- getAppView().rewritePrefix.rewrittenType(accessedFrom, getAppView());
+ getAppView().rewritePrefix.rewrittenType(accessedFrom.getHolderType(), getAppView());
if (rewrittenType == null) {
rewrittenType =
getAppView()
.options()
.desugaredLibraryConfiguration
.getEmulateLibraryInterface()
- .get(accessedFrom);
+ .get(accessedFrom.getHolderType());
}
if (rewrittenType != null) {
addRewritingPrefix(accessedFrom, rewrittenType, lambdaClassType);
}
}
}
- lambdaClass.addSynthesizedFrom(getAppView().definitionFor(accessedFrom).asProgramClass());
- if (isInMainDexList(accessedFrom)) {
+ lambdaClass.addSynthesizedFrom(accessedFrom.getHolder());
+ if (isInMainDexList(accessedFrom.getHolderType())) {
lambdaClass.addToMainDexList.set(true);
}
return lambdaClass;
}
- private LambdaClass getKnownLambdaClass(LambdaDescriptor descriptor, DexType accessedFrom) {
+ private LambdaClass getKnownLambdaClass(LambdaDescriptor descriptor, ProgramMethod accessedFrom) {
DexType lambdaClassType = LambdaClass.createLambdaClassType(this, accessedFrom, descriptor);
return getKnown(knownLambdaClasses, lambdaClassType);
}
- private void addRewritingPrefix(DexType type, DexType rewritten, DexType lambdaClassType) {
+ private void addRewritingPrefix(
+ ProgramMethod context, DexType rewritten, DexType lambdaClassType) {
String javaName = lambdaClassType.toString();
- String typeString = type.toString();
+ String typeString = context.getHolderType().toString();
String actualPrefix = typeString.substring(0, typeString.lastIndexOf('.'));
String rewrittenString = rewritten.toString();
String actualRewrittenPrefix = rewrittenString.substring(0, rewrittenString.lastIndexOf('.'));
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CallSiteOptimizationInfoPropagator.java b/src/main/java/com/android/tools/r8/ir/optimize/CallSiteOptimizationInfoPropagator.java
index 8d1124b..a573863 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CallSiteOptimizationInfoPropagator.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CallSiteOptimizationInfoPropagator.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.ir.optimize;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProgramClass;
@@ -85,7 +84,7 @@
if (mode != Mode.COLLECT) {
return;
}
- DexEncodedMethod context = code.method();
+ ProgramMethod context = code.context();
for (Instruction instruction : code.instructions()) {
if (!instruction.isInvokeMethod() && !instruction.isInvokeCustom()) {
continue;
@@ -97,24 +96,26 @@
ResolutionResult resolutionResult =
appView.appInfo().resolveMethod(invokedMethod.holder, invokedMethod);
// For virtual and interface calls, proceed on valid results only (since it's enforced).
- if (!resolutionResult.isVirtualTarget()) {
+ if (!resolutionResult.isSingleResolution() || !resolutionResult.isVirtualTarget()) {
continue;
}
// If the resolution ended up with a single target, check if it is a library override.
// And if so, bail out early (to avoid expensive target lookup).
- if (resolutionResult.isSingleResolution()
- && isLibraryMethodOrLibraryMethodOverride(resolutionResult.getSingleTarget())) {
+ ProgramMethod resolutionTarget =
+ resolutionResult.asSingleResolution().getResolutionPair().asProgramMethod();
+ if (resolutionTarget == null
+ || isLibraryMethodOrLibraryMethodOverride(resolutionTarget)) {
continue;
}
}
- Collection<DexEncodedMethod> targets = invoke.lookupTargets(appView, context.holder());
+ ProgramMethodSet targets = invoke.lookupProgramDispatchTargets(appView, context);
assert invoke.isInvokeMethodWithDynamicDispatch()
// For other invocation types, the size of targets should be at most one.
|| targets == null || targets.size() <= 1;
if (targets == null || targets.isEmpty() || hasLibraryOverrides(targets)) {
continue;
}
- for (DexEncodedMethod target : targets) {
+ for (ProgramMethod target : targets) {
recordArgumentsIfNecessary(target, invoke.inValues());
}
}
@@ -147,8 +148,8 @@
// TODO(b/140204899): Instead of reprocessing here, pass stopping criteria to lookup?
// If any of target method is a library method override, bail out entirely/early.
- private boolean hasLibraryOverrides(Collection<DexEncodedMethod> targets) {
- for (DexEncodedMethod target : targets) {
+ private boolean hasLibraryOverrides(ProgramMethodSet targets) {
+ for (ProgramMethod target : targets) {
if (isLibraryMethodOrLibraryMethodOverride(target)) {
return true;
}
@@ -156,54 +157,42 @@
return false;
}
- private boolean isLibraryMethodOrLibraryMethodOverride(DexEncodedMethod target) {
- // Not a program method.
- if (!target.isProgramMethod(appView)) {
- return true;
- }
+ private boolean isLibraryMethodOrLibraryMethodOverride(ProgramMethod target) {
// If the method overrides a library method, it is unsure how the method would be invoked by
// that library.
- if (target.isLibraryMethodOverride().isTrue()) {
- return true;
- }
- return false;
+ return target.getDefinition().isLibraryMethodOverride().isTrue();
}
// Record arguments for the given method if necessary.
// At the same time, if it decides to bail out, make the corresponding info immutable so that we
// can avoid recording arguments for the same method accidentally.
- private void recordArgumentsIfNecessary(DexEncodedMethod target, List<Value> inValues) {
- assert !target.isObsolete();
- if (appView.appInfo().neverReprocess.contains(target.method)) {
+ private void recordArgumentsIfNecessary(ProgramMethod target, List<Value> inValues) {
+ assert !target.getDefinition().isObsolete();
+ if (appView.appInfo().neverReprocess.contains(target.getReference())) {
return;
}
- if (target.getCallSiteOptimizationInfo().isTop()) {
+ if (target.getDefinition().getCallSiteOptimizationInfo().isTop()) {
return;
}
- target.joinCallSiteOptimizationInfo(
- computeCallSiteOptimizationInfoFromArguments(target, inValues), appView);
+ target
+ .getDefinition()
+ .joinCallSiteOptimizationInfo(
+ computeCallSiteOptimizationInfoFromArguments(target, inValues), appView);
}
private CallSiteOptimizationInfo computeCallSiteOptimizationInfoFromArguments(
- DexEncodedMethod target, List<Value> inValues) {
+ ProgramMethod target, List<Value> inValues) {
// No method body or no argument at all.
- if (target.shouldNotHaveCode() || inValues.size() == 0) {
+ if (target.getDefinition().shouldNotHaveCode() || inValues.size() == 0) {
return CallSiteOptimizationInfo.TOP;
}
// If pinned, that method could be invoked via reflection.
- if (appView.appInfo().isPinned(target.method)) {
- return CallSiteOptimizationInfo.TOP;
- }
- // Not a program method.
- if (!target.isProgramMethod(appView)) {
- // But, should not be reachable, since we already bail out.
- assert false
- : "Trying to compute call site optimization info for " + target.toSourceString();
+ if (appView.appInfo().isPinned(target.getReference())) {
return CallSiteOptimizationInfo.TOP;
}
// If the method overrides a library method, it is unsure how the method would be invoked by
// that library.
- if (target.isLibraryMethodOverride().isTrue()) {
+ if (target.getDefinition().isLibraryMethodOverride().isTrue()) {
// But, should not be reachable, since we already bail out.
assert false
: "Trying to compute call site optimization info for " + target.toSourceString();
@@ -212,8 +201,8 @@
// If the program already has illegal accesses, method resolution results will reflect that too.
// We should avoid recording arguments in that case. E.g., b/139823850: static methods can be a
// result of virtual call targets, if that's the only method that matches name and signature.
- int argumentOffset = target.isStatic() ? 0 : 1;
- if (inValues.size() != argumentOffset + target.method.getArity()) {
+ int argumentOffset = target.getDefinition().isStatic() ? 0 : 1;
+ if (inValues.size() != argumentOffset + target.getReference().getArity()) {
return CallSiteOptimizationInfo.BOTTOM;
}
return ConcreteCallSiteOptimizationInfo.fromArguments(appView, target, inValues);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
index baaed33e..e10d477 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ClassInitializerDefaultsOptimization.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
-import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
@@ -30,6 +29,7 @@
import com.android.tools.r8.graph.DexValue.DexValueShort;
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.FieldResolutionResult;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ValueMayDependOnEnvironmentAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.code.ArrayPut;
@@ -124,18 +124,17 @@
this.dexItemFactory = appView.dexItemFactory();
}
- public ClassInitializerDefaultsResult optimize(
- DexEncodedMethod method, IRCode code, OptimizationFeedback feedback) {
- if (appView.options().debug || method.getOptimizationInfo().isReachabilitySensitive()) {
+ public ClassInitializerDefaultsResult optimize(IRCode code, OptimizationFeedback feedback) {
+ if (appView.options().debug) {
return ClassInitializerDefaultsResult.empty();
}
- if (!method.isClassInitializer()) {
+ ProgramMethod context = code.context();
+ if (context.getDefinition().getOptimizationInfo().isReachabilitySensitive()) {
return ClassInitializerDefaultsResult.empty();
}
- DexClass clazz = appView.definitionFor(method.holder());
- if (clazz == null) {
+ if (!context.getDefinition().isClassInitializer()) {
return ClassInitializerDefaultsResult.empty();
}
@@ -144,7 +143,8 @@
// the field initial value.
Set<StaticPut> unnecessaryStaticPuts = Sets.newIdentityHashSet();
Collection<StaticPut> finalFieldPuts =
- findFinalFieldPutsWhileCollectingUnnecessaryStaticPuts(code, clazz, unnecessaryStaticPuts);
+ findFinalFieldPutsWhileCollectingUnnecessaryStaticPuts(
+ code, context, unnecessaryStaticPuts);
// Return eagerly if there is nothing to optimize.
if (finalFieldPuts.isEmpty()) {
@@ -161,7 +161,7 @@
Value value = put.value();
if (unnecessaryStaticPuts.contains(put)) {
if (fieldType == dexItemFactory.stringType) {
- fieldsWithStaticValues.put(field, getDexStringValue(value, method.holder()));
+ fieldsWithStaticValues.put(field, getDexStringValue(value, context.getHolderType()));
} else if (fieldType.isClassType() || fieldType.isArrayType()) {
if (value.isZero()) {
fieldsWithStaticValues.put(field, DexValueNull.NULL);
@@ -361,7 +361,7 @@
}
private Collection<StaticPut> findFinalFieldPutsWhileCollectingUnnecessaryStaticPuts(
- IRCode code, DexClass clazz, Set<StaticPut> unnecessaryStaticPuts) {
+ IRCode code, ProgramMethod context, Set<StaticPut> unnecessaryStaticPuts) {
ValueMayDependOnEnvironmentAnalysis environmentAnalysis =
new ValueMayDependOnEnvironmentAnalysis(appView, code);
Map<DexField, StaticPut> finalFieldPuts = Maps.newIdentityHashMap();
@@ -377,22 +377,22 @@
// Array stores do not impact our ability to move constants into the class definition,
// as long as the instructions do not throw.
ArrayPut arrayPut = instruction.asArrayPut();
- if (arrayPut.instructionInstanceCanThrow(appView, clazz.type).isThrowing()) {
+ if (arrayPut.instructionInstanceCanThrow(appView, context).isThrowing()) {
return validateFinalFieldPuts(finalFieldPuts, isWrittenBefore);
}
} else if (instruction.isStaticGet()) {
StaticGet get = instruction.asStaticGet();
DexEncodedField field =
appView.appInfo().resolveField(get.getField()).getResolvedField();
- if (field != null && field.holder() == clazz.type) {
+ if (field != null && field.holder() == context.getHolderType()) {
isReadBefore.add(field.field);
- } else if (instruction.instructionMayHaveSideEffects(appView, clazz.type)) {
+ } else if (instruction.instructionMayHaveSideEffects(appView, context)) {
// Reading another field is only OK if the read does not have side-effects.
return validateFinalFieldPuts(finalFieldPuts, isWrittenBefore);
}
} else if (instruction.isStaticPut()) {
StaticPut put = instruction.asStaticPut();
- if (put.getField().holder != clazz.type) {
+ if (put.getField().holder != context.getHolderType()) {
// Can cause clinit on another class which can read uninitialized static fields
// of this class.
return validateFinalFieldPuts(finalFieldPuts, isWrittenBefore);
@@ -400,7 +400,7 @@
DexField field = put.getField();
Value value = put.value();
TypeElement valueType = value.getType();
- if (clazz.definesStaticField(field)) {
+ if (context.getHolder().definesStaticField(field)) {
if (isReadBefore.contains(field)) {
// Promoting this put to a class constant would cause a previous static-get
// instruction to read a different value.
@@ -434,7 +434,7 @@
// Still constant, but not able to represent it as static encoded values, e.g.,
// const-class, const-method-handle, etc. This static-put can be redundant if the
// field is rewritten with another constant. Will fall through and track static-put.
- } else if (isClassNameConstantOf(clazz, put)) {
+ } else if (isClassNameConstantOf(context.getHolder(), put)) {
// Collect put of class name constant as a potential default value.
finalFieldPuts.put(field, put);
unnecessaryStaticPuts.add(put);
@@ -458,13 +458,13 @@
// Writing another field is not OK.
return validateFinalFieldPuts(finalFieldPuts, isWrittenBefore);
}
- } else if (instruction.instructionMayHaveSideEffects(appView, clazz.type)) {
+ } else if (instruction.instructionMayHaveSideEffects(appView, context)) {
// Some other instruction that has side-effects. Stop here.
return validateFinalFieldPuts(finalFieldPuts, isWrittenBefore);
} else {
// TODO(b/120138731): This check should be removed when the Class.get*Name()
// optimizations become enabled.
- if (isClassNameConstantOf(clazz, instruction)) {
+ if (isClassNameConstantOf(context.getHolder(), instruction)) {
// OK, this does not read one of the fields in the enclosing class.
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 3dbe05d..29a0c32 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -24,6 +24,7 @@
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.equivalence.BasicBlockBehavioralSubsumption;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -312,7 +313,7 @@
boolean canDetachValueIsNullTarget = true;
for (Instruction i : valueIsNullTarget.instructionsBefore(throwInstruction)) {
- if (!i.isBlockLocalInstructionWithoutSideEffects(appView, code.method().holder())) {
+ if (!i.isBlockLocalInstructionWithoutSideEffects(appView, code.context())) {
canDetachValueIsNullTarget = false;
break;
}
@@ -1133,7 +1134,7 @@
BasicBlock defaultTarget = theSwitch.fallthroughBlock();
SwitchCaseEliminator eliminator = null;
BasicBlockBehavioralSubsumption behavioralSubsumption =
- new BasicBlockBehavioralSubsumption(appView, code.method().holder());
+ new BasicBlockBehavioralSubsumption(appView, code.context());
// Compute the set of switch cases that can be removed.
int alwaysHitCase = -1;
@@ -1258,7 +1259,7 @@
}
// Check if the invoked method is known to return one of its arguments.
- DexEncodedMethod target = invoke.lookupSingleTarget(appView, code.method().holder());
+ DexEncodedMethod target = invoke.lookupSingleTarget(appView, code.context());
if (target != null && target.getOptimizationInfo().returnsArgument()) {
int argumentIndex = target.getOptimizationInfo().getReturnedArgument();
// Replace the out value of the invoke with the argument and ignore the out value.
@@ -1380,7 +1381,7 @@
// If the cast type is not accessible in the current context, we should not remove the cast
// in order to preserve IllegalAccessError. Note that JVM and ART behave differently: see
// {@link com.android.tools.r8.ir.optimize.checkcast.IllegalAccessErrorTest}.
- if (!isTypeVisibleFromContext(appView, code.method().holder(), castType)) {
+ if (!isTypeVisibleFromContext(appView, code.context(), castType)) {
return RemoveCheckCastInstructionIfTrivialResult.NO_REMOVALS;
}
@@ -1437,7 +1438,7 @@
InstanceOf instanceOf, InstructionListIterator it, IRCode code) {
// If the instance-of type is not accessible in the current context, we should not remove the
// instance-of instruction in order to preserve IllegalAccessError.
- if (!isTypeVisibleFromContext(appView, code.method().holder(), instanceOf.type())) {
+ if (!isTypeVisibleFromContext(appView, code.context(), instanceOf.type())) {
return false;
}
@@ -2505,7 +2506,7 @@
}
}
} else {
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
AbstractValue abstractValue = lhs.getAbstractValue(appView, context);
if (abstractValue.isSingleConstClassValue()) {
AbstractValue otherAbstractValue = rhs.getAbstractValue(appView, context);
@@ -2822,7 +2823,7 @@
InvokeMethod invoke = insn.asInvokeMethod();
DexEncodedMethod singleTarget =
- invoke.lookupSingleTarget(appView.withLiveness(), code.method().holder());
+ invoke.lookupSingleTarget(appView.withLiveness(), code.context());
if (singleTarget == null || !singleTarget.getOptimizationInfo().neverReturnsNormally()) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
index 691de34..36fba35 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ConstantCanonicalizer.java
@@ -11,8 +11,7 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
import com.android.tools.r8.ir.analysis.value.SingleFieldValue;
import com.android.tools.r8.ir.code.BasicBlock;
@@ -87,8 +86,7 @@
}
public void canonicalize(AppView<?> appView, IRCode code) {
- DexEncodedMethod method = code.method();
- DexType context = method.holder();
+ ProgramMethod context = code.context();
Object2ObjectLinkedOpenCustomHashMap<Instruction, List<Value>> valuesDefinedByConstant =
new Object2ObjectLinkedOpenCustomHashMap<>(
new Strategy<Instruction>() {
@@ -149,7 +147,8 @@
continue;
}
SingleFieldValue singleFieldValue = abstractValue.asSingleFieldValue();
- if (method.isClassInitializer() && method.holder() == singleFieldValue.getField().holder) {
+ if (context.getDefinition().isClassInitializer()
+ && context.getHolderType() == singleFieldValue.getField().holder) {
// Avoid that canonicalization inserts a read before the unique write in the class
// initializer, as that would change the program behavior.
continue;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index e0066a7..4b8ee00 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -9,7 +9,6 @@
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -328,11 +327,7 @@
ClassInitializationAnalysis classInitializationAnalysis,
WhyAreYouNotInliningReporter whyAreYouNotInliningReporter) {
InlineAction action = new InlineAction(singleTarget, invoke, reason);
- if (isTargetClassInitialized(
- invoke,
- method.getDefinition(),
- singleTarget.getDefinition(),
- classInitializationAnalysis)) {
+ if (isTargetClassInitialized(invoke, method, singleTarget, classInitializationAnalysis)) {
return action;
}
if (appView.canUseInitClass()
@@ -346,8 +341,8 @@
private boolean isTargetClassInitialized(
InvokeStatic invoke,
- DexEncodedMethod method,
- DexEncodedMethod target,
+ ProgramMethod context,
+ ProgramMethod target,
ClassInitializationAnalysis classInitializationAnalysis) {
// Only proceed with inlining a static invoke if:
// - the holder for the target is a subtype of the holder for the method,
@@ -356,28 +351,24 @@
// - the current method has already triggered the holder for the target method to be
// initialized, or
// - there is no non-trivial class initializer.
- DexType targetHolder = target.holder();
- if (appView.appInfo().isSubtype(method.holder(), targetHolder)) {
+ if (appView.appInfo().isSubtype(context.getHolderType(), target.getHolderType())) {
return true;
}
- DexClass clazz = appView.definitionFor(targetHolder);
- assert clazz != null;
- if (target.getOptimizationInfo().triggersClassInitBeforeAnySideEffect()) {
+ if (target.getDefinition().getOptimizationInfo().triggersClassInitBeforeAnySideEffect()) {
return true;
}
- if (!method.isStatic()) {
+ if (!context.getDefinition().isStatic()) {
boolean targetIsGuaranteedToBeInitialized =
appView.withInitializedClassesInInstanceMethods(
analysis ->
- analysis.isClassDefinitelyLoadedInInstanceMethodsOn(
- target.holder(), method.holder()),
+ analysis.isClassDefinitelyLoadedInInstanceMethod(target.getHolder(), context),
false);
if (targetIsGuaranteedToBeInitialized) {
return true;
}
}
if (classInitializationAnalysis.isClassDefinitelyLoadedBeforeInstruction(
- target.holder(), invoke)) {
+ target.getHolderType(), invoke)) {
return true;
}
// Check for class initializer side effects when loading this class, as inlining might remove
@@ -387,11 +378,11 @@
//
// For simplicity, we are conservative and consider all interfaces, not only the ones with
// default methods.
- if (!clazz.classInitializationMayHaveSideEffects(appView)) {
+ if (!target.getHolder().classInitializationMayHaveSideEffects(appView)) {
return true;
}
- if (appView.rootSet().bypassClinitForInlining.contains(target.method)) {
+ if (appView.rootSet().bypassClinitForInlining.contains(target.getReference())) {
return true;
}
@@ -488,7 +479,7 @@
// Final fields may not be initialized outside of a constructor in the enclosing class.
InstancePut instancePut = instruction.asInstancePut();
DexField field = instancePut.getField();
- DexEncodedField target = appView.appInfo().lookupInstanceTarget(field.holder, field);
+ DexEncodedField target = appView.appInfo().lookupInstanceTarget(field);
if (target == null || target.accessFlags.isFinal()) {
whyAreYouNotInliningReporter.reportUnsafeConstructorInliningDueToFinalFieldAssignment(
instancePut);
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 0366798..8b46005 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
@@ -7,8 +7,8 @@
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -52,8 +52,9 @@
this.appView = appView;
}
- public void devirtualizeInvokeInterface(IRCode code, DexProgramClass context) {
+ public void devirtualizeInvokeInterface(IRCode code) {
Set<Value> affectedValues = Sets.newIdentityHashSet();
+ ProgramMethod context = code.context();
Map<InvokeInterface, InvokeVirtual> devirtualizedCall = new IdentityHashMap<>();
DominatorTree dominatorTree = new DominatorTree(code);
Map<Value, Map<DexType, Value>> castedReceiverCache = new IdentityHashMap<>();
@@ -118,14 +119,14 @@
if (appView.options().testing.enableInvokeSuperToInvokeVirtualRewriting) {
if (current.isInvokeSuper()) {
InvokeSuper invoke = current.asInvokeSuper();
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context.type);
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget != null) {
DexClass holder = appView.definitionForHolder(singleTarget);
assert holder != null;
DexMethod invokedMethod = invoke.getInvokedMethod();
DexEncodedMethod newSingleTarget =
InvokeVirtual.lookupSingleTarget(
- appView, context.type, invokedMethod, invoke.getReceiver());
+ appView, context, invokedMethod, invoke.getReceiver());
if (newSingleTarget == singleTarget) {
it.replaceCurrentInstruction(
new InvokeVirtual(invokedMethod, invoke.outValue(), invoke.arguments()));
@@ -139,7 +140,7 @@
InvokeVirtual invoke = current.asInvokeVirtual();
DexMethod invokedMethod = invoke.getInvokedMethod();
DexMethod reboundTarget =
- rebindVirtualInvokeToMostSpecific(invokedMethod, invoke.getReceiver(), context.type);
+ rebindVirtualInvokeToMostSpecific(invokedMethod, invoke.getReceiver(), context);
if (reboundTarget != invokedMethod) {
it.replaceCurrentInstruction(
new InvokeVirtual(reboundTarget, invoke.outValue(), invoke.arguments()));
@@ -151,7 +152,7 @@
continue;
}
InvokeInterface invoke = current.asInvokeInterface();
- DexEncodedMethod target = invoke.lookupSingleTarget(appView, context.type);
+ DexEncodedMethod target = invoke.lookupSingleTarget(appView, context);
if (target == null) {
continue;
}
@@ -163,7 +164,7 @@
}
// Due to the potential downcast below, make sure the new target holder is visible.
ConstraintWithTarget visibility =
- ConstraintWithTarget.classIsVisible(context.type, holderType, appView);
+ ConstraintWithTarget.classIsVisible(context.getHolder(), holderType, appView);
if (visibility == ConstraintWithTarget.NEVER) {
continue;
}
@@ -279,7 +280,7 @@
* entirely. Without this rewriting, we would have to keep A.foo() because the method is targeted.
*/
private DexMethod rebindVirtualInvokeToMostSpecific(
- DexMethod target, Value receiver, DexType context) {
+ DexMethod target, Value receiver, ProgramMethod context) {
if (!receiver.getType().isClassType()) {
return target;
}
@@ -318,10 +319,11 @@
return target.isNonPrivateVirtualMethod() && appView.isInterface(target.holder()).isFalse();
}
- private boolean hasAccessToInvokeTargetFromContext(DexEncodedMethod target, DexType context) {
+ private boolean hasAccessToInvokeTargetFromContext(
+ DexEncodedMethod target, ProgramMethod context) {
assert !target.accessFlags.isPrivate();
DexType holder = target.holder();
- if (holder == context) {
+ if (holder == context.getHolderType()) {
// It is always safe to invoke a method from the same enclosing class.
return true;
}
@@ -330,7 +332,7 @@
// Conservatively report an illegal access.
return false;
}
- if (holder.isSamePackage(context)) {
+ if (holder.isSamePackage(context.getHolderType())) {
// The class must be accessible (note that we have already established that the method is not
// private).
return !clazz.accessFlags.isPrivate();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java
index f2e3092..cbcbd2e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DynamicTypeOptimization.java
@@ -78,8 +78,7 @@
TypeElement.fromDexType(invokedMethod.holder, definitelyNotNull(), appView);
dynamicLowerBoundType = null;
} else {
- DexEncodedMethod singleTarget =
- invoke.lookupSingleTarget(appView, code.method().holder());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
if (singleTarget == null) {
continue;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
index 62b5ab3..b1af390 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/IdempotentFunctionCallCanonicalizer.java
@@ -9,7 +9,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
@@ -110,7 +110,7 @@
}
});
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
// Collect invocations along with arguments.
for (BasicBlock block : code.blocks) {
for (Instruction current : block.getInstructions()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 6db2341..bb58ce1 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -147,22 +147,22 @@
}
private ConstraintWithTarget instructionAllowedForInlining(
- Instruction instruction, InliningConstraints inliningConstraints, DexType invocationContext) {
- ConstraintWithTarget result =
- instruction.inliningConstraint(inliningConstraints, invocationContext);
+ Instruction instruction, InliningConstraints inliningConstraints, ProgramMethod context) {
+ ConstraintWithTarget result = instruction.inliningConstraint(inliningConstraints, context);
if (result == ConstraintWithTarget.NEVER && instruction.isDebugInstruction()) {
return ConstraintWithTarget.ALWAYS;
}
return result;
}
- public ConstraintWithTarget computeInliningConstraint(IRCode code, ProgramMethod method) {
+ public ConstraintWithTarget computeInliningConstraint(IRCode code) {
if (containsPotentialCatchHandlerVerificationError(code)) {
return ConstraintWithTarget.NEVER;
}
+ ProgramMethod context = code.context();
if (appView.options().canHaveDalvikIntUsedAsNonIntPrimitiveTypeBug()
- && returnsIntAsBoolean(code, method)) {
+ && returnsIntAsBoolean(code, context)) {
return ConstraintWithTarget.NEVER;
}
@@ -171,7 +171,7 @@
new InliningConstraints(appView, GraphLense.getIdentityLense());
for (Instruction instruction : code.instructions()) {
ConstraintWithTarget state =
- instructionAllowedForInlining(instruction, inliningConstraints, method.getHolderType());
+ instructionAllowedForInlining(instruction, inliningConstraints, context);
if (state == ConstraintWithTarget.NEVER) {
result = state;
break;
@@ -198,28 +198,27 @@
return false;
}
- boolean hasInliningAccess(ProgramMethod method, ProgramMethod target) {
- if (!isVisibleWithFlags(
- target.getHolderType(), method.getHolderType(), target.getDefinition().accessFlags)) {
+ boolean hasInliningAccess(ProgramMethod context, ProgramMethod target) {
+ if (!isVisibleWithFlags(target.getHolderType(), context, target.getDefinition().accessFlags)) {
return false;
}
// The class needs also to be visible for us to have access.
- return isVisibleWithFlags(
- target.getHolderType(), method.getHolderType(), target.getHolder().accessFlags);
+ return isVisibleWithFlags(target.getHolderType(), context, target.getHolder().accessFlags);
}
- private boolean isVisibleWithFlags(DexType target, DexType context, AccessFlags<?> flags) {
+ private boolean isVisibleWithFlags(DexType target, ProgramMethod context, AccessFlags<?> flags) {
if (flags.isPublic()) {
return true;
}
if (flags.isPrivate()) {
- return NestUtils.sameNest(target, context, appView);
+ return NestUtils.sameNest(target, context.getHolderType(), appView);
}
if (flags.isProtected()) {
- return appView.appInfo().isSubtype(context, target) || target.isSamePackage(context);
+ return appView.appInfo().isSubtype(context.getHolderType(), target)
+ || target.isSamePackage(context.getHolderType());
}
// package-private
- return target.isSamePackage(context);
+ return target.isSamePackage(context.getHolderType());
}
public synchronized boolean isDoubleInlineSelectedTarget(ProgramMethod method) {
@@ -367,36 +366,36 @@
}
public static ConstraintWithTarget deriveConstraint(
- DexType contextHolder, DexType targetHolder, AccessFlags flags, AppView<?> appView) {
+ DexProgramClass context, DexType targetHolder, AccessFlags<?> flags, AppView<?> appView) {
if (flags.isPublic()) {
return ALWAYS;
} else if (flags.isPrivate()) {
- DexClass contextHolderClass = appView.definitionFor(contextHolder);
- assert contextHolderClass != null;
- if (contextHolderClass.isInANest()) {
- return NestUtils.sameNest(contextHolder, targetHolder, appView)
+ if (context.isInANest()) {
+ return NestUtils.sameNest(context.getType(), targetHolder, appView)
? new ConstraintWithTarget(Constraint.SAMENEST, targetHolder)
: NEVER;
}
- return targetHolder == contextHolder
- ? new ConstraintWithTarget(Constraint.SAMECLASS, targetHolder) : NEVER;
+ return targetHolder == context.type
+ ? new ConstraintWithTarget(Constraint.SAMECLASS, targetHolder)
+ : NEVER;
} else if (flags.isProtected()) {
- if (targetHolder.isSamePackage(contextHolder)) {
+ if (targetHolder.isSamePackage(context.type)) {
// Even though protected, this is visible via the same package from the context.
return new ConstraintWithTarget(Constraint.PACKAGE, targetHolder);
- } else if (appView.isSubtype(contextHolder, targetHolder).isTrue()) {
+ } else if (appView.isSubtype(context.type, targetHolder).isTrue()) {
return new ConstraintWithTarget(Constraint.SUBCLASS, targetHolder);
}
return NEVER;
} else {
/* package-private */
- return targetHolder.isSamePackage(contextHolder)
- ? new ConstraintWithTarget(Constraint.PACKAGE, targetHolder) : NEVER;
+ return targetHolder.isSamePackage(context.type)
+ ? new ConstraintWithTarget(Constraint.PACKAGE, targetHolder)
+ : NEVER;
}
}
public static ConstraintWithTarget classIsVisible(
- DexType context, DexType clazz, AppView<?> appView) {
+ DexProgramClass context, DexType clazz, AppView<?> appView) {
if (clazz.isArrayType()) {
return classIsVisible(context, clazz.toArrayElementType(appView.dexItemFactory()), appView);
}
@@ -966,8 +965,7 @@
// TODO(b/142116551): This should be equivalent to invoke.lookupSingleTarget()!
ProgramMethod singleTarget = oracle.lookupSingleTarget(invoke, context);
if (singleTarget == null) {
- WhyAreYouNotInliningReporter.handleInvokeWithUnknownTarget(
- invoke, appView, context.getDefinition());
+ WhyAreYouNotInliningReporter.handleInvokeWithUnknownTarget(invoke, appView, context);
continue;
}
@@ -975,8 +973,7 @@
WhyAreYouNotInliningReporter whyAreYouNotInliningReporter =
oracle.isForcedInliningOracle()
? NopWhyAreYouNotInliningReporter.getInstance()
- : WhyAreYouNotInliningReporter.createFor(
- singleTargetMethod, appView, context.getDefinition());
+ : WhyAreYouNotInliningReporter.createFor(singleTarget, appView, context);
InlineAction action =
oracle.computeInlining(
invoke,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
index ea77caf..6fb87b6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/InliningConstraints.java
@@ -90,16 +90,16 @@
}
public ConstraintWithTarget forDexItemBasedConstString(
- DexReference type, DexType invocationContext) {
+ DexReference type, DexProgramClass context) {
return ConstraintWithTarget.ALWAYS;
}
- public ConstraintWithTarget forCheckCast(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forCheckCast(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
- public ConstraintWithTarget forConstClass(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forConstClass(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
public ConstraintWithTarget forConstInstruction() {
@@ -126,42 +126,40 @@
return ConstraintWithTarget.ALWAYS;
}
- public ConstraintWithTarget forInitClass(DexType clazz, DexType context) {
+ public ConstraintWithTarget forInitClass(DexType clazz, DexProgramClass context) {
return ConstraintWithTarget.classIsVisible(context, clazz, appView);
}
- public ConstraintWithTarget forInstanceGet(DexField field, DexType invocationContext) {
+ public ConstraintWithTarget forInstanceGet(DexField field, DexProgramClass context) {
DexField lookup = graphLense.lookupField(field);
- return forFieldInstruction(
- lookup, appView.appInfo().lookupInstanceTarget(lookup.holder, lookup), invocationContext);
+ return forFieldInstruction(lookup, appView.appInfo().lookupInstanceTarget(lookup), context);
}
- public ConstraintWithTarget forInstanceOf(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forInstanceOf(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
- public ConstraintWithTarget forInstancePut(DexField field, DexType invocationContext) {
+ public ConstraintWithTarget forInstancePut(DexField field, DexProgramClass context) {
DexField lookup = graphLense.lookupField(field);
- return forFieldInstruction(
- lookup, appView.appInfo().lookupInstanceTarget(lookup.holder, lookup), invocationContext);
+ return forFieldInstruction(lookup, appView.appInfo().lookupInstanceTarget(lookup), context);
}
- public ConstraintWithTarget forInvoke(DexMethod method, Type type, DexType invocationContext) {
+ public ConstraintWithTarget forInvoke(DexMethod method, Type type, DexProgramClass context) {
switch (type) {
case DIRECT:
- return forInvokeDirect(method, invocationContext);
+ return forInvokeDirect(method, context);
case INTERFACE:
- return forInvokeInterface(method, invocationContext);
+ return forInvokeInterface(method, context);
case STATIC:
- return forInvokeStatic(method, invocationContext);
+ return forInvokeStatic(method, context);
case SUPER:
- return forInvokeSuper(method, invocationContext);
+ return forInvokeSuper(method, context);
case VIRTUAL:
- return forInvokeVirtual(method, invocationContext);
+ return forInvokeVirtual(method, context);
case CUSTOM:
return forInvokeCustom();
case POLYMORPHIC:
- return forInvokePolymorphic(method, invocationContext);
+ return forInvokePolymorphic(method, context);
default:
throw new Unreachable("Unexpected type: " + type);
}
@@ -174,17 +172,13 @@
private DexEncodedMethod lookupWhileVerticalClassMerging(
DexMethod method,
- DexType invocationContext,
+ DexProgramClass context,
BiFunction<SingleResolutionResult, DexProgramClass, DexEncodedMethod> lookupFunction) {
SingleResolutionResult singleResolutionResult =
appView.appInfo().resolveMethod(method.holder, method).asSingleResolution();
if (singleResolutionResult == null) {
return null;
}
- DexProgramClass context = appView.definitionForProgramType(invocationContext);
- if (context == null) {
- return null;
- }
DexEncodedMethod dexEncodedMethod = lookupFunction.apply(singleResolutionResult, context);
if (dexEncodedMethod != null) {
return dexEncodedMethod;
@@ -203,61 +197,55 @@
return null;
}
- public ConstraintWithTarget forInvokeDirect(DexMethod method, DexType invocationContext) {
+ public ConstraintWithTarget forInvokeDirect(DexMethod method, DexProgramClass context) {
DexMethod lookup = graphLense.lookupMethod(method);
DexEncodedMethod target =
isVerticalClassMerging()
? lookupWhileVerticalClassMerging(
lookup,
- invocationContext,
+ context,
(res, ctxt) -> res.lookupInvokeDirectTarget(ctxt, appView.appInfo()))
- : appView.appInfo().lookupDirectTarget(lookup, invocationContext);
- return forSingleTargetInvoke(lookup, target, invocationContext);
+ : appView.appInfo().lookupDirectTarget(lookup, context);
+ return forSingleTargetInvoke(lookup, target, context);
}
- public ConstraintWithTarget forInvokeInterface(DexMethod method, DexType invocationContext) {
+ public ConstraintWithTarget forInvokeInterface(DexMethod method, DexProgramClass context) {
DexMethod lookup = graphLense.lookupMethod(method);
- return forVirtualInvoke(
- lookup,
- invocationContext,
- true);
+ return forVirtualInvoke(lookup, context, true);
}
- public ConstraintWithTarget forInvokeMultiNewArray(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forInvokeMultiNewArray(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
- public ConstraintWithTarget forInvokeNewArray(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forInvokeNewArray(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
- public ConstraintWithTarget forInvokePolymorphic(DexMethod method, DexType invocationContext) {
+ public ConstraintWithTarget forInvokePolymorphic(DexMethod method, DexProgramClass context) {
return ConstraintWithTarget.NEVER;
}
- public ConstraintWithTarget forInvokeStatic(DexMethod method, DexType invocationContext) {
+ public ConstraintWithTarget forInvokeStatic(DexMethod method, DexProgramClass context) {
DexMethod lookup = graphLense.lookupMethod(method);
DexEncodedMethod target =
isVerticalClassMerging()
? lookupWhileVerticalClassMerging(
lookup,
- invocationContext,
+ context,
(res, ctxt) -> res.lookupInvokeStaticTarget(ctxt, appView.appInfo()))
- : appView.appInfo().lookupStaticTarget(lookup, invocationContext);
- return forSingleTargetInvoke(lookup, target, invocationContext);
+ : appView.appInfo().lookupStaticTarget(lookup, context);
+ return forSingleTargetInvoke(lookup, target, context);
}
- public ConstraintWithTarget forInvokeSuper(DexMethod method, DexType invocationContext) {
+ public ConstraintWithTarget forInvokeSuper(DexMethod method, DexProgramClass context) {
// The semantics of invoke super depend on the context.
- return new ConstraintWithTarget(Constraint.SAMECLASS, invocationContext);
+ return new ConstraintWithTarget(Constraint.SAMECLASS, context.type);
}
- public ConstraintWithTarget forInvokeVirtual(DexMethod method, DexType invocationContext) {
+ public ConstraintWithTarget forInvokeVirtual(DexMethod method, DexProgramClass context) {
DexMethod lookup = graphLense.lookupMethod(method);
- return forVirtualInvoke(
- lookup,
- invocationContext,
- false);
+ return forVirtualInvoke(lookup, context, false);
}
public ConstraintWithTarget forJumpInstruction() {
@@ -280,16 +268,16 @@
return ConstraintWithTarget.ALWAYS;
}
- public ConstraintWithTarget forNewArrayEmpty(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forNewArrayEmpty(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
public ConstraintWithTarget forNewArrayFilledData() {
return ConstraintWithTarget.ALWAYS;
}
- public ConstraintWithTarget forNewInstance(DexType type, DexType invocationContext) {
- return ConstraintWithTarget.classIsVisible(invocationContext, type, appView);
+ public ConstraintWithTarget forNewInstance(DexType type, DexProgramClass context) {
+ return ConstraintWithTarget.classIsVisible(context, type, appView);
}
public ConstraintWithTarget forAssume() {
@@ -304,16 +292,14 @@
return ConstraintWithTarget.ALWAYS;
}
- public ConstraintWithTarget forStaticGet(DexField field, DexType invocationContext) {
+ public ConstraintWithTarget forStaticGet(DexField field, DexProgramClass context) {
DexField lookup = graphLense.lookupField(field);
- return forFieldInstruction(
- lookup, appView.appInfo().lookupStaticTarget(lookup.holder, lookup), invocationContext);
+ return forFieldInstruction(lookup, appView.appInfo().lookupStaticTarget(lookup), context);
}
- public ConstraintWithTarget forStaticPut(DexField field, DexType invocationContext) {
+ public ConstraintWithTarget forStaticPut(DexField field, DexProgramClass context) {
DexField lookup = graphLense.lookupField(field);
- return forFieldInstruction(
- lookup, appView.appInfo().lookupStaticTarget(lookup.holder, lookup), invocationContext);
+ return forFieldInstruction(lookup, appView.appInfo().lookupStaticTarget(lookup), context);
}
public ConstraintWithTarget forStore() {
@@ -341,17 +327,16 @@
}
private ConstraintWithTarget forFieldInstruction(
- DexField field, DexEncodedField target, DexType invocationContext) {
+ DexField field, DexEncodedField target, DexProgramClass context) {
// Resolve the field if possible and decide whether the instruction can inlined.
DexType fieldHolder = graphLense.lookupType(field.holder);
DexClass fieldClass = appView.definitionFor(fieldHolder);
if (target != null && fieldClass != null) {
ConstraintWithTarget fieldConstraintWithTarget =
- ConstraintWithTarget.deriveConstraint(
- invocationContext, fieldHolder, target.accessFlags, appView);
+ ConstraintWithTarget.deriveConstraint(context, fieldHolder, target.accessFlags, appView);
// If the field has not been member-rebound, then we also need to make sure that the
- // `invocationContext` has access to the definition of the field.
+ // `context` has access to the definition of the field.
//
// See, for example, InlineNonReboundFieldTest (b/128604123).
if (field.holder != target.holder()) {
@@ -360,13 +345,13 @@
ConstraintWithTarget.meet(
fieldConstraintWithTarget,
ConstraintWithTarget.deriveConstraint(
- invocationContext, actualFieldHolder, target.accessFlags, appView),
+ context, actualFieldHolder, target.accessFlags, appView),
appView);
}
ConstraintWithTarget classConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, fieldHolder, fieldClass.accessFlags, appView);
+ context, fieldHolder, fieldClass.accessFlags, appView);
return ConstraintWithTarget.meet(
fieldConstraintWithTarget, classConstraintWithTarget, appView);
}
@@ -374,7 +359,7 @@
}
private ConstraintWithTarget forSingleTargetInvoke(
- DexMethod method, DexEncodedMethod target, DexType invocationContext) {
+ DexMethod method, DexEncodedMethod target, DexProgramClass context) {
if (method.holder.isArrayType()) {
return ConstraintWithTarget.ALWAYS;
}
@@ -389,11 +374,11 @@
ConstraintWithTarget methodConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, target.accessFlags, appView);
+ context, methodHolder, target.accessFlags, appView);
// We also have to take the constraint of the enclosing class into account.
ConstraintWithTarget classConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, methodClass.accessFlags, appView);
+ context, methodHolder, methodClass.accessFlags, appView);
return ConstraintWithTarget.meet(
methodConstraintWithTarget, classConstraintWithTarget, appView);
}
@@ -402,9 +387,7 @@
}
private ConstraintWithTarget forVirtualInvoke(
- DexMethod method,
- DexType invocationContext,
- boolean isInterface) {
+ DexMethod method, DexProgramClass context, boolean isInterface) {
if (method.holder.isArrayType()) {
return ConstraintWithTarget.ALWAYS;
}
@@ -428,7 +411,7 @@
assert methodClass != null;
ConstraintWithTarget methodConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, resolutionTarget.accessFlags, appView);
+ context, methodHolder, resolutionTarget.accessFlags, appView);
// We also have to take the constraint of the enclosing class of the resolution result
// into account. We do not allow inlining this method if it is calling something that
// is inaccessible. Inlining in that case could move the code to another package making a
@@ -436,7 +419,7 @@
// we have to make sure that inlining cannot make it inaccessible.
ConstraintWithTarget classConstraintWithTarget =
ConstraintWithTarget.deriveConstraint(
- invocationContext, methodHolder, methodClass.accessFlags, appView);
+ context, methodHolder, methodClass.accessFlags, appView);
return ConstraintWithTarget.meet(
methodConstraintWithTarget, classConstraintWithTarget, appView);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index 900d62a..a2072ee 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -146,7 +146,7 @@
DexField field = returnValueRule.getField();
assert instruction.getOutType() == TypeElement.fromDexType(field.type, maybeNull(), appView);
- DexEncodedField staticField = appView.appInfo().lookupStaticTarget(field.holder, field);
+ DexEncodedField staticField = appView.appInfo().lookupStaticTarget(field);
if (staticField == null) {
if (warnedFields.add(field)) {
reporter.warning(
@@ -212,7 +212,7 @@
if (current.isStaticGet()) {
StaticGet staticGet = current.asStaticGet();
replaceInstructionByInitClassIfPossible(
- staticGet, staticGet.getField().holder, code, iterator, code.method().holder());
+ staticGet, staticGet.getField().holder, code, iterator, code.context());
}
replacement.setPosition(position);
if (block.hasCatchHandlers()) {
@@ -236,7 +236,7 @@
if (!invokedHolder.isClassType()) {
return;
}
- DexEncodedMethod target = current.lookupSingleTarget(appView, context.getHolderType());
+ DexEncodedMethod target = current.lookupSingleTarget(appView, context);
if (target != null && target.isInstanceInitializer()) {
// Member value propagation does not apply to constructors. Removing a call to a constructor
// that is marked as having no side effects could lead to verification errors, due to
@@ -303,10 +303,10 @@
current.setOutValue(null);
if (current.isInvokeMethodWithReceiver()) {
- replaceInstructionByNullCheckIfPossible(current, iterator, context.getHolderType());
+ replaceInstructionByNullCheckIfPossible(current, iterator, context);
} else if (current.isInvokeStatic()) {
replaceInstructionByInitClassIfPossible(
- current, target.holder(), code, iterator, context.getHolderType());
+ current, target.holder(), code, iterator, context);
}
// Insert the definition of the replacement.
@@ -367,7 +367,7 @@
abstractValue = target.getOptimizationInfo().getAbstractValue();
if (abstractValue.isUnknown() && !target.isStatic()) {
AbstractValue abstractReceiverValue =
- current.asInstanceGet().object().getAbstractValue(appView, code.method().holder());
+ current.asInstanceGet().object().getAbstractValue(appView, code.context());
if (abstractReceiverValue.isSingleFieldValue()) {
abstractValue =
abstractReceiverValue.asSingleFieldValue().getState().getAbstractFieldValue(target);
@@ -393,7 +393,7 @@
}
if (singleValue.isMaterializableInContext(appView, code.context())) {
BasicBlock block = current.getBlock();
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
Position position = current.getPosition();
// All usages are replaced by the replacement value.
@@ -425,7 +425,7 @@
}
private void replaceInstructionByNullCheckIfPossible(
- Instruction instruction, InstructionListIterator iterator, DexType context) {
+ Instruction instruction, InstructionListIterator iterator, ProgramMethod context) {
assert instruction.isInstanceFieldInstruction() || instruction.isInvokeMethodWithReceiver();
assert !instruction.hasOutValue() || !instruction.outValue().hasAnyUsers();
if (instruction.instructionMayHaveSideEffects(
@@ -456,7 +456,7 @@
DexType holder,
IRCode code,
InstructionListIterator iterator,
- DexType context) {
+ ProgramMethod context) {
assert instruction.isStaticFieldInstruction() || instruction.isInvokeStatic();
if (instruction.instructionMayHaveSideEffects(
appView, context, Instruction.SideEffectAssumption.CLASS_ALREADY_INITIALIZED)) {
@@ -467,7 +467,7 @@
appView,
// Types that are a super type of `context` are guaranteed to be initialized
// already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.appInfo().isSubtype(context.getHolderType(), type),
Sets.newIdentityHashSet());
if (!classInitializationMayHaveSideEffects) {
iterator.removeOrReplaceByDebugLocalRead();
@@ -494,7 +494,7 @@
return;
}
- replaceInstructionByNullCheckIfPossible(current, iterator, code.method().holder());
+ replaceInstructionByNullCheckIfPossible(current, iterator, code.context());
}
private void replaceStaticPutByInitClassIfNeverRead(
@@ -509,7 +509,7 @@
}
replaceInstructionByInitClassIfPossible(
- current, field.holder(), code, iterator, code.method().holder());
+ current, field.holder(), code, iterator, code.context());
}
/**
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
index 9bee381..d0047d3 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
@@ -89,8 +89,7 @@
InvokeMethod invoke = current.asInvokeMethod();
DexMethod invokedMethod = invoke.getInvokedMethod();
- DexEncodedMethod singleTarget =
- invoke.lookupSingleTarget(appView, code.method().holder());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
if (singleTarget != null) {
MethodOptimizationInfo optimizationInfo = singleTarget.getOptimizationInfo();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 2b9456a..92ba7c6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -863,8 +863,7 @@
// See whether we could move this invoke somewhere else. We reuse the logic from inlining
// here, as the constraints are the same.
- ConstraintWithTarget constraint =
- invoke.inliningConstraint(inliningConstraints, method.getHolderType());
+ ConstraintWithTarget constraint = invoke.inliningConstraint(inliningConstraints, method);
if (constraint != ConstraintWithTarget.ALWAYS) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
index 512e33d..7330d11 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/RedundantFieldLoadElimination.java
@@ -161,7 +161,6 @@
}
public void run() {
- DexType context = method.getHolderType();
Reference2IntMap<BasicBlock> pendingNormalSuccessors = new Reference2IntOpenHashMap<>();
for (BasicBlock block : code.blocks) {
if (!block.hasUniqueNormalSuccessor()) {
@@ -274,14 +273,14 @@
appView,
// Types that are a super type of `context` are guaranteed to be initialized
// already.
- type -> appView.isSubtype(context, type).isTrue(),
+ type -> appView.isSubtype(method.getHolderType(), type).isTrue(),
Sets.newIdentityHashSet())) {
killAllNonFinalActiveFields();
}
} else {
// If the current instruction could trigger a method invocation, it could also cause
// field values to change. In that case, it must be handled above.
- assert !instruction.instructionMayTriggerMethodInvocation(appView, context);
+ assert !instruction.instructionMayTriggerMethodInvocation(appView, method);
// If this assertion fails for a new instruction we need to determine if that
// instruction has side-effects that can change the value of fields. If so, it must be
@@ -348,7 +347,7 @@
return;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method.getHolderType());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method);
if (singleTarget == null || !singleTarget.isInstanceInitializer()) {
killAllNonFinalActiveFields();
return;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java
index 1f410ef..fd270a4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ReflectionOptimizer.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.analysis.type.TypeElement;
@@ -39,7 +40,7 @@
return;
}
Set<Value> affectedValues = Sets.newIdentityHashSet();
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
ClassInitializationAnalysis classInitializationAnalysis =
new ClassInitializationAnalysis(appView, code);
for (BasicBlock block : code.blocks) {
@@ -84,9 +85,7 @@
}
private static DexType getTypeForGetClass(
- AppView<AppInfoWithLiveness> appView,
- DexType context,
- InvokeVirtual invoke) {
+ AppView<AppInfoWithLiveness> appView, ProgramMethod context, InvokeVirtual invoke) {
DexItemFactory dexItemFactory = appView.dexItemFactory();
DexMethod invokedMethod = invoke.getInvokedMethod();
// Class<?> Object#getClass() is final and cannot be overridden.
@@ -126,7 +125,7 @@
}
// Make sure the target (base) type is visible.
ConstraintWithTarget constraints =
- ConstraintWithTarget.classIsVisible(context, baseType, appView);
+ ConstraintWithTarget.classIsVisible(context.getHolder(), baseType, appView);
if (constraints == ConstraintWithTarget.NEVER) {
return null;
}
@@ -136,7 +135,7 @@
private static DexType getTypeForClassForName(
AppView<AppInfoWithLiveness> appView,
ClassInitializationAnalysis classInitializationAnalysis,
- DexType context,
+ ProgramMethod context,
InvokeStatic invoke) {
DexItemFactory dexItemFactory = appView.dexItemFactory();
DexMethod invokedMethod = invoke.getInvokedMethod();
@@ -203,7 +202,7 @@
}
// Make sure the (base) type is visible.
ConstraintWithTarget constraints =
- ConstraintWithTarget.classIsVisible(context, baseType, appView);
+ ConstraintWithTarget.classIsVisible(context.getHolder(), baseType, appView);
if (constraints == ConstraintWithTarget.NEVER) {
return null;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
index 6a59224..32bea32 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/UninstantiatedTypeOptimization.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLense.NestedGraphLense;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.RewrittenPrototypeDescription;
import com.android.tools.r8.graph.RewrittenPrototypeDescription.ArgumentInfoCollection;
import com.android.tools.r8.graph.RewrittenPrototypeDescription.RemovedArgumentInfo;
@@ -351,8 +352,7 @@
Instruction instruction = instructionIterator.next();
if (instruction.throwsOnNullInput()) {
Value couldBeNullValue = instruction.getNonNullInput();
- if (isThrowNullCandidate(
- couldBeNullValue, instruction, appView, code.method().holder())) {
+ if (isThrowNullCandidate(couldBeNullValue, instruction, appView, code.context())) {
if (instruction.isInstanceGet() || instruction.isInstancePut()) {
++numberOfInstanceGetOrInstancePutWithNullReceiver;
} else if (instruction.isInvokeMethodWithReceiver()) {
@@ -405,7 +405,7 @@
Value couldBeNullValue,
Instruction current,
AppView<? extends AppInfoWithClassHierarchy> appView,
- DexType context) {
+ ProgramMethod context) {
if (!couldBeNullValue.isAlwaysNull(appView)) {
return false;
}
@@ -451,7 +451,7 @@
IRCode code,
AssumeDynamicTypeRemover assumeDynamicTypeRemover,
Set<Value> affectedValues) {
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
DexField field = instruction.getField();
DexType fieldType = field.type;
if (fieldType.isAlwaysNull(appView)) {
@@ -507,7 +507,7 @@
AssumeDynamicTypeRemover assumeDynamicTypeRemover,
Set<BasicBlock> blocksToBeRemoved,
Set<Value> affectedValues) {
- DexEncodedMethod target = invoke.lookupSingleTarget(appView, code.method().holder());
+ DexEncodedMethod target = invoke.lookupSingleTarget(appView, code.context());
if (target == null) {
return;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 24fc2f7..ceee8d2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -172,7 +172,7 @@
assert root.isStaticGet();
StaticGet staticGet = root.asStaticGet();
- if (staticGet.instructionMayHaveSideEffects(appView, method.getHolderType())) {
+ if (staticGet.instructionMayHaveSideEffects(appView, method)) {
return EligibilityStatus.RETRIEVAL_MAY_HAVE_SIDE_EFFECTS;
}
DexEncodedField field = appView.appInfo().resolveField(staticGet.getField()).getResolvedField();
@@ -273,8 +273,7 @@
if (user.isInvokeMethod()) {
InvokeMethod invokeMethod = user.asInvokeMethod();
- DexEncodedMethod singleTargetMethod =
- invokeMethod.lookupSingleTarget(appView, method.getHolderType());
+ DexEncodedMethod singleTargetMethod = invokeMethod.lookupSingleTarget(appView, method);
if (singleTargetMethod == null) {
return user; // Not eligible.
}
@@ -580,7 +579,7 @@
continue;
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method.getHolderType());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method);
if (singleTarget != null) {
Predicate<InvokeMethod> noSideEffectsPredicate =
dexItemFactory.libraryMethodsWithoutSideEffects.getOrDefault(
@@ -1175,7 +1174,7 @@
}
// Check if the method is inline-able by standard inliner.
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method.getHolderType());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method);
if (singleTarget == null) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
index 608ba09..b601000 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxer.java
@@ -394,7 +394,7 @@
return Reason.INVALID_INVOKE_ON_ARRAY;
}
DexEncodedMethod encodedSingleTarget =
- invokeMethod.lookupSingleTarget(appView, code.method().holder());
+ invokeMethod.lookupSingleTarget(appView, code.context());
if (encodedSingleTarget == null) {
return Reason.INVALID_INVOKE;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java b/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
index f4d341b..c1064a6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/ConcreteCallSiteOptimizationInfo.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.ir.analysis.type.TypeElement;
import com.android.tools.r8.ir.analysis.value.AbstractValue;
@@ -154,11 +155,11 @@
public static CallSiteOptimizationInfo fromArguments(
AppView<? extends AppInfoWithClassHierarchy> appView,
- DexEncodedMethod method,
+ ProgramMethod target,
List<Value> inValues) {
boolean allowConstantPropagation = appView.options().enablePropagationOfConstantsAtCallSites;
ConcreteCallSiteOptimizationInfo newCallSiteInfo =
- new ConcreteCallSiteOptimizationInfo(method, allowConstantPropagation);
+ new ConcreteCallSiteOptimizationInfo(target.getDefinition(), allowConstantPropagation);
assert newCallSiteInfo.size == inValues.size();
assert newCallSiteInfo.dynamicUpperBoundTypes != null;
for (int i = 0; i < newCallSiteInfo.size; i++) {
@@ -167,8 +168,7 @@
assert newCallSiteInfo.constants != null;
Value aliasedValue = arg.getAliasedValue();
if (!aliasedValue.isPhi()) {
- AbstractValue abstractValue =
- aliasedValue.definition.getAbstractValue(appView, method.holder());
+ AbstractValue abstractValue = aliasedValue.definition.getAbstractValue(appView, target);
if (abstractValue.isNonTrivial()) {
newCallSiteInfo.constants.put(i, abstractValue);
}
@@ -181,7 +181,7 @@
assert arg.getType().isReferenceType();
newCallSiteInfo.dynamicUpperBoundTypes.put(i, arg.getDynamicUpperBoundType(appView));
}
- if (newCallSiteInfo.hasUsefulOptimizationInfo(appView, method)) {
+ if (newCallSiteInfo.hasUsefulOptimizationInfo(appView, target.getDefinition())) {
return newCallSiteInfo;
}
// As soon as we know the current call site does not have any useful optimization info,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 2464952..b06b4a8 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -44,13 +44,14 @@
import static com.android.tools.r8.ir.code.Opcodes.XOR;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis.AnalysisAssumption;
import com.android.tools.r8.ir.analysis.DeterminismAnalysis;
@@ -128,9 +129,9 @@
InstanceFieldInitializationInfoCollection instanceFieldInitializationInfos,
Timing timing) {
identifyBridgeInfo(method, code, feedback, timing);
- identifyClassInlinerEligibility(method, code, feedback, timing);
+ identifyClassInlinerEligibility(code, feedback, timing);
identifyParameterUsages(method, code, feedback, timing);
- identifyReturnsArgument(method, code, feedback, timing);
+ identifyReturnsArgument(code, feedback, timing);
if (options.enableInlining) {
identifyInvokeSemanticsForInlining(method, code, feedback, timing);
}
@@ -152,14 +153,13 @@
}
private void identifyClassInlinerEligibility(
- DexEncodedMethod method, IRCode code, OptimizationFeedback feedback, Timing timing) {
+ IRCode code, OptimizationFeedback feedback, Timing timing) {
timing.begin("Identify class inliner eligibility");
- identifyClassInlinerEligibility(method, code, feedback);
+ identifyClassInlinerEligibility(code, feedback);
timing.end();
}
- private void identifyClassInlinerEligibility(
- DexEncodedMethod method, IRCode code, OptimizationFeedback feedback) {
+ private void identifyClassInlinerEligibility(IRCode code, OptimizationFeedback feedback) {
// Method eligibility is calculated in similar way for regular method
// and for the constructor. To be eligible method should only be using its
// receiver in the following ways:
@@ -173,24 +173,21 @@
//
// Note that (4) can safely be removed as the receiver is guaranteed not to escape when we class
// inline it, and hence any monitor instructions are no-ops.
- boolean instanceInitializer = method.isInstanceInitializer();
- if (method.accessFlags.isNative()
- || (!method.isNonAbstractVirtualMethod() && !instanceInitializer)) {
+ ProgramMethod context = code.context();
+ DexEncodedMethod definition = context.getDefinition();
+ boolean instanceInitializer = definition.isInstanceInitializer();
+ if (definition.isNative()
+ || (!definition.isNonAbstractVirtualMethod() && !instanceInitializer)) {
return;
}
- feedback.setClassInlinerEligibility(method, null); // To allow returns below.
+ feedback.setClassInlinerEligibility(definition, null); // To allow returns below.
Value receiver = code.getThis();
if (receiver.numberOfPhiUsers() > 0) {
return;
}
- DexClass clazz = appView.definitionFor(method.holder());
- if (clazz == null) {
- return;
- }
-
List<Pair<Invoke.Type, DexMethod>> callsReceiver = new ArrayList<>();
boolean seenSuperInitCall = false;
boolean seenMonitor = false;
@@ -224,7 +221,7 @@
}
}
DexField field = insn.asFieldInstruction().getField();
- if (appView.appInfo().resolveFieldOn(clazz, field).isSuccessfulResolution()) {
+ if (appView.appInfo().resolveField(field).isSuccessfulResolution()) {
// Require only accessing direct or indirect instance fields of the current class.
break;
}
@@ -236,7 +233,7 @@
InvokeDirect invoke = insn.asInvokeDirect();
DexMethod invokedMethod = invoke.getInvokedMethod();
if (dexItemFactory.isConstructor(invokedMethod)
- && invokedMethod.holder == clazz.superType
+ && invokedMethod.holder == context.getHolder().superType
&& ListUtils.lastIndexMatching(invoke.arguments(), isReceiverAlias) == 0
&& !seenSuperInitCall
&& instanceInitializer) {
@@ -250,7 +247,7 @@
case INVOKE_STATIC:
{
InvokeStatic invoke = insn.asInvokeStatic();
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, method.holder());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
return; // Not allowed.
}
@@ -271,7 +268,7 @@
DexMethod invokedMethod = invoke.getInvokedMethod();
DexType returnType = invokedMethod.proto.returnType;
if (returnType.isClassType()
- && appView.appInfo().inSameHierarchy(returnType, method.holder())) {
+ && appView.appInfo().inSameHierarchy(returnType, context.getHolderType())) {
return; // Not allowed, could introduce an alias of the receiver.
}
callsReceiver.add(new Pair<>(Invoke.Type.VIRTUAL, invokedMethod));
@@ -289,13 +286,13 @@
return;
}
- boolean synchronizedVirtualMethod = method.isSynchronized() && method.isVirtualMethod();
+ boolean synchronizedVirtualMethod = definition.isSynchronized() && definition.isVirtualMethod();
feedback.setClassInlinerEligibility(
- method,
+ definition,
new ClassInlinerEligibilityInfo(
callsReceiver,
- new ClassInlinerReceiverAnalysis(appView, method, code).computeReturnsReceiver(),
+ new ClassInlinerReceiverAnalysis(appView, definition, code).computeReturnsReceiver(),
seenMonitor || synchronizedVirtualMethod));
}
@@ -345,15 +342,15 @@
return builder.build();
}
- private void identifyReturnsArgument(
- DexEncodedMethod method, IRCode code, OptimizationFeedback feedback, Timing timing) {
+ private void identifyReturnsArgument(IRCode code, OptimizationFeedback feedback, Timing timing) {
timing.begin("Identify returns argument");
- identifyReturnsArgument(method, code, feedback);
+ identifyReturnsArgument(code, feedback);
timing.end();
}
- private void identifyReturnsArgument(
- DexEncodedMethod method, IRCode code, OptimizationFeedback feedback) {
+ private void identifyReturnsArgument(IRCode code, OptimizationFeedback feedback) {
+ ProgramMethod context = code.context();
+ DexEncodedMethod method = context.getDefinition();
List<BasicBlock> normalExits = code.computeNormalExitBlocks();
if (normalExits.isEmpty()) {
feedback.methodNeverReturnsNormally(method);
@@ -380,7 +377,6 @@
if (definition.isArgument()) {
feedback.methodReturnsArgument(method, definition.asArgument().getIndex());
}
- DexType context = method.holder();
AbstractValue abstractReturnValue = definition.getAbstractValue(appView, context);
if (abstractReturnValue.isNonTrivial()) {
feedback.methodReturnsAbstractValue(method, appView, abstractReturnValue);
@@ -424,16 +420,9 @@
return;
}
- DexClass clazz = appView.appInfo().definitionFor(method.holder());
- if (clazz == null) {
- assert false;
- return;
- }
-
NonTrivialInstanceInitializerInfo.Builder builder =
NonTrivialInstanceInitializerInfo.builder(instanceFieldInitializationInfos);
- InstanceInitializerInfo instanceInitializerInfo =
- analyzeInstanceInitializer(code, clazz, builder);
+ InstanceInitializerInfo instanceInitializerInfo = analyzeInstanceInitializer(code, builder);
feedback.setInstanceInitializerInfo(
method,
instanceInitializerInfo != null
@@ -457,8 +446,9 @@
//
// (Note that this initializer does not have to have zero arguments.)
private InstanceInitializerInfo analyzeInstanceInitializer(
- IRCode code, DexClass clazz, NonTrivialInstanceInitializerInfo.Builder builder) {
- if (clazz.definesFinalizer(options.itemFactory)) {
+ IRCode code, NonTrivialInstanceInitializerInfo.Builder builder) {
+ ProgramMethod context = code.context();
+ if (context.getHolder().definesFinalizer(options.itemFactory)) {
// Defining a finalize method can observe the side-effect of Object.<init> GC registration.
return null;
}
@@ -510,7 +500,7 @@
// instructions can trigger class initialization side effects, hence it is not necessary
// to mark all fields as potentially being read. Also, none of the instruction types
// can cause the receiver to escape.
- if (instruction.instructionMayHaveSideEffects(appView, clazz.type)) {
+ if (instruction.instructionMayHaveSideEffects(appView, context)) {
builder.setMayHaveOtherSideEffectsThanInstanceFieldAssignments();
}
break;
@@ -525,7 +515,7 @@
return null;
}
builder.markFieldAsRead(field);
- if (fieldGet.instructionMayHaveSideEffects(appView, clazz.type)) {
+ if (fieldGet.instructionMayHaveSideEffects(appView, context)) {
builder.setMayHaveOtherSideEffectsThanInstanceFieldAssignments();
if (fieldGet.isStaticGet()) {
// It could trigger a class initializer.
@@ -546,7 +536,7 @@
Value object =
instancePut.object().getAliasedValue(aliasesThroughAssumeAndCheckCasts);
if (object != receiver
- || instancePut.instructionInstanceCanThrow(appView, clazz.type).isThrowing()) {
+ || instancePut.instructionInstanceCanThrow(appView, context).isThrowing()) {
builder.setMayHaveOtherSideEffectsThanInstanceFieldAssignments();
}
@@ -614,7 +604,7 @@
case INVOKE_NEW_ARRAY:
{
InvokeNewArray invoke = instruction.asInvokeNewArray();
- if (invoke.instructionMayHaveSideEffects(appView, clazz.type)) {
+ if (invoke.instructionMayHaveSideEffects(appView, context)) {
builder.setMayHaveOtherSideEffectsThanInstanceFieldAssignments();
}
for (Value argument : invoke.arguments()) {
@@ -646,7 +636,7 @@
case NEW_INSTANCE:
{
NewInstance newInstance = instruction.asNewInstance();
- if (newInstance.instructionMayHaveSideEffects(appView, clazz.type)) {
+ if (newInstance.instructionMayHaveSideEffects(appView, context)) {
// It could trigger a class initializer.
builder
.markAllFieldsAsRead()
@@ -696,7 +686,7 @@
if (method.isStatic()) {
// Identifies if the method preserves class initialization after inlining.
feedback.markTriggerClassInitBeforeAnySideEffect(
- method, triggersClassInitializationBeforeSideEffect(method.holder(), code, appView));
+ method, triggersClassInitializationBeforeSideEffect(code, appView));
} else {
// Identifies if the method preserves null check of the receiver after inlining.
final Value receiver = code.getThis();
@@ -712,13 +702,17 @@
* <p>Note: we do not track phis so we may return false negative. This is a conservative approach.
*/
private static boolean triggersClassInitializationBeforeSideEffect(
- DexType clazz, IRCode code, AppView<?> appView) {
+ IRCode code, AppView<?> appView) {
return alwaysTriggerExpectedEffectBeforeAnythingElse(
code,
(instruction, it) -> {
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
if (instruction.definitelyTriggersClassInitialization(
- clazz, context, appView, DIRECTLY, AnalysisAssumption.INSTRUCTION_DOES_NOT_THROW)) {
+ context.getHolderType(),
+ context,
+ appView,
+ DIRECTLY,
+ AnalysisAssumption.INSTRUCTION_DOES_NOT_THROW)) {
// In order to preserve class initialization semantic, the exception must not be caught
// by any handler. Therefore, we must ignore this instruction if it is covered by a
// catch handler.
@@ -728,7 +722,7 @@
// We found an instruction that preserves initialization of the class.
return InstructionEffect.DESIRED_EFFECT;
}
- } else if (instruction.instructionMayHaveSideEffects(appView, clazz)) {
+ } else if (instruction.instructionMayHaveSideEffects(appView, context)) {
// We found a side effect before class initialization.
return InstructionEffect.OTHER_EFFECT;
}
@@ -849,7 +843,7 @@
if (isInstantiationOfNullPointerException(instr, it, appView.dexItemFactory())) {
it.next(); // Skip call to NullPointerException.<init>.
return InstructionEffect.NO_EFFECT;
- } else if (instr.throwsNpeIfValueIsNull(value, appView, code.method().holder())) {
+ } else if (instr.throwsNpeIfValueIsNull(value, appView, code.context())) {
// In order to preserve NPE semantic, the exception must not be caught by any handler.
// Therefore, we must ignore this instruction if it is covered by a catch handler.
// Note: this is a conservative approach where we consider that any catch handler could
@@ -858,7 +852,7 @@
// We found a NPE check on the value.
return InstructionEffect.DESIRED_EFFECT;
}
- } else if (instr.instructionMayHaveSideEffects(appView, code.method().holder())) {
+ } else if (instr.instructionMayHaveSideEffects(appView, code.context())) {
// If the current instruction is const-string, this could load the parameter name.
// Just make sure it is indeed not throwing.
if (instr.isConstString() && !instr.instructionInstanceCanThrow()) {
@@ -1023,7 +1017,7 @@
if (appView.appInfo().mayHaveSideEffects.containsKey(method.method)) {
return;
}
- DexType context = method.holder();
+ ProgramMethod context = code.context();
if (method.isClassInitializer()) {
// For class initializers, we also wish to compute if the class initializer has observable
// side effects.
@@ -1035,9 +1029,9 @@
} else if (classInitializerSideEffect.canBePostponed()) {
feedback.classInitializerMayBePostponed(method);
} else {
- assert !context.isD8R8SynthesizedLambdaClassType()
+ assert !context.getHolderType().isD8R8SynthesizedLambdaClassType()
|| options.debug
- || appView.appInfo().hasPinnedInstanceInitializer(context)
+ || appView.appInfo().hasPinnedInstanceInitializer(context.getHolderType())
: "Unexpected observable side effects from lambda `" + context.toSourceString() + "`";
}
return;
@@ -1046,7 +1040,7 @@
if (method.isSynchronized()) {
// If the method is synchronized then it acquires a lock.
mayHaveSideEffects = true;
- } else if (method.isInstanceInitializer() && hasNonTrivialFinalizeMethod(context)) {
+ } else if (method.isInstanceInitializer() && hasNonTrivialFinalizeMethod(context.getHolder())) {
// If a class T overrides java.lang.Object.finalize(), then treat the constructor as having
// side effects. This ensures that we won't remove instructions on the form `new-instance
// {v0}, T`.
@@ -1066,31 +1060,20 @@
}
}
- // Returns true if `method` is an initializer and the enclosing class overrides the method
- // `void java.lang.Object.finalize()`.
- private boolean hasNonTrivialFinalizeMethod(DexType type) {
- DexClass clazz = appView.definitionFor(type);
- if (clazz != null) {
- if (clazz.isProgramClass() && !clazz.isInterface()) {
- DexItemFactory dexItemFactory = appView.dexItemFactory();
- ResolutionResult resolutionResult =
- appView
- .appInfo()
- .resolveMethodOnClass(clazz, appView.dexItemFactory().objectMembers.finalize);
-
- DexEncodedMethod target = resolutionResult.getSingleTarget();
- if (target != null
- && target.method != dexItemFactory.enumMethods.finalize
- && target.method != dexItemFactory.objectMembers.finalize) {
- return true;
- }
- return false;
- } else {
- // Conservatively report that the library class could implement finalize().
- return true;
- }
+ // Returns true if the given class overrides the method `void java.lang.Object.finalize()`.
+ private boolean hasNonTrivialFinalizeMethod(DexProgramClass clazz) {
+ if (clazz.isInterface()) {
+ return false;
}
- return false;
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
+ ResolutionResult resolutionResult =
+ appView
+ .appInfo()
+ .resolveMethodOnClass(clazz, appView.dexItemFactory().objectMembers.finalize);
+ DexEncodedMethod target = resolutionResult.getSingleTarget();
+ return target != null
+ && target.method != dexItemFactory.enumMethods.finalize
+ && target.method != dexItemFactory.objectMembers.finalize;
}
private void computeReturnValueOnlyDependsOnArguments(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
index 091a5e5..05d9b49 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporter.java
@@ -5,21 +5,21 @@
package com.android.tools.r8.ir.optimize.inliner;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.optimize.Inliner.Reason;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import java.util.Collection;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.Set;
public abstract class WhyAreYouNotInliningReporter {
public static WhyAreYouNotInliningReporter createFor(
- DexEncodedMethod callee, AppView<AppInfoWithLiveness> appView, DexEncodedMethod context) {
- if (appView.appInfo().whyAreYouNotInlining.contains(callee.method)) {
+ ProgramMethod callee, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
+ if (appView.appInfo().whyAreYouNotInlining.contains(callee.getReference())) {
return new WhyAreYouNotInliningReporterImpl(
callee, context, appView.options().testing.whyAreYouNotInliningConsumer);
}
@@ -27,20 +27,20 @@
}
public static void handleInvokeWithUnknownTarget(
- InvokeMethod invoke, AppView<AppInfoWithLiveness> appView, DexEncodedMethod context) {
+ InvokeMethod invoke, AppView<AppInfoWithLiveness> appView, ProgramMethod context) {
if (appView.appInfo().whyAreYouNotInlining.isEmpty()) {
return;
}
- Collection<DexEncodedMethod> possibleTargets = invoke.lookupTargets(appView, context.holder());
- if (possibleTargets == null) {
+ ProgramMethodSet possibleProgramTargets = invoke.lookupProgramDispatchTargets(appView, context);
+ if (possibleProgramTargets == null) {
// In principle, this invoke might target any method in the program, but we do not want to
// report a message for each of the methods in `AppInfoWithLiveness#whyAreYouNotInlining`,
// since that would almost never be useful.
return;
}
- for (DexEncodedMethod possibleTarget : possibleTargets) {
+ for (ProgramMethod possibleTarget : possibleProgramTargets) {
createFor(possibleTarget, appView, context).reportUnknownTarget();
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java
index b141817..934651c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/WhyAreYouNotInliningReporterImpl.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.ir.optimize.inliner;
-import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
@@ -15,14 +15,14 @@
class WhyAreYouNotInliningReporterImpl extends WhyAreYouNotInliningReporter {
- private final DexEncodedMethod callee;
- private final DexEncodedMethod context;
+ private final ProgramMethod callee;
+ private final ProgramMethod context;
private final PrintStream output;
private boolean reasonHasBeenReported = false;
WhyAreYouNotInliningReporterImpl(
- DexEncodedMethod callee, DexEncodedMethod context, PrintStream output) {
+ ProgramMethod callee, ProgramMethod context, PrintStream output) {
this.callee = callee;
this.context = context;
this.output = output;
@@ -30,9 +30,9 @@
private void print(String reason) {
output.print("Method `");
- output.print(callee.method.toSourceString());
+ output.print(callee.toSourceString());
output.print("` was not inlined into `");
- output.print(context.method.toSourceString());
+ output.print(context.toSourceString());
if (reason != null) {
output.print("`: ");
output.println(reason);
@@ -220,7 +220,7 @@
"final field `"
+ instancePut.getField()
+ "` must be initialized in a constructor of `"
- + callee.holder().toSourceString()
+ + callee.getHolderType().toSourceString()
+ "`.");
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java
index 76e81ac..a560844 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/BooleanMethodOptimizer.java
@@ -70,7 +70,7 @@
InvokeMethod invoke,
Set<Value> affectedValues) {
Value argument = invoke.arguments().get(0);
- AbstractValue abstractValue = argument.getAbstractValue(appView, code.method().holder());
+ AbstractValue abstractValue = argument.getAbstractValue(appView, code.context());
if (abstractValue.isSingleNumberValue()) {
instructionIterator.replaceCurrentInstructionWithStaticGet(
appView,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java
index 6566187..0c7393b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryMemberOptimizer.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory.LibraryMembers;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
@@ -86,12 +87,12 @@
*
* <p>In order for library modeling to work in D8, we return a definition for invoke instructions
* that are guaranteed to dispatch to a library method in {@link
- * InvokeMethod#lookupSingleTarget(AppView, DexType)}. As part of that, we bail-out if the holder
- * of the targeted method is not a library class. However, what is usually on the library path
- * will be on the program path when compiling the framework itself. To ensure that our library
- * modeling works also for the framework compilation, we maintain the set of types that we model,
- * and treat these types as library types in {@link InvokeMethod#lookupSingleTarget(AppView,
- * DexType)} although they are on the program path.
+ * InvokeMethod#lookupSingleTarget(AppView, ProgramMethod)}. As part of that, we bail-out if the
+ * holder of the targeted method is not a library class. However, what is usually on the library
+ * path will be on the program path when compiling the framework itself. To ensure that our
+ * library modeling works also for the framework compilation, we maintain the set of types that we
+ * model, and treat these types as library types in {@link
+ * InvokeMethod#lookupSingleTarget(AppView, ProgramMethod)} although they are on the program path.
*/
public boolean isModeled(DexType type) {
return modeledLibraryTypes.contains(type);
@@ -114,7 +115,7 @@
Instruction instruction = instructionIterator.next();
if (instruction.isInvokeMethod()) {
InvokeMethod invoke = instruction.asInvokeMethod();
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, code.method().holder());
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, code.context());
if (singleTarget != null) {
optimizeInvoke(code, instructionIterator, invoke, singleTarget, affectedValues);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java
index 1283bf4..64dce88 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/StringMethodOptimizer.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.DexItemBasedConstString;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
@@ -47,7 +48,7 @@
private void optimizeEquals(
IRCode code, InstructionListIterator instructionIterator, InvokeMethod invoke) {
if (appView.appInfo().hasLiveness()) {
- DexType context = code.method().holder();
+ ProgramMethod context = code.context();
Value first = invoke.arguments().get(0).getAliasedValue();
Value second = invoke.arguments().get(1).getAliasedValue();
if (isPrunedClassNameComparison(first, second, context)
@@ -63,7 +64,7 @@
* has been pruned by the {@link com.android.tools.r8.shaking.Enqueuer}.
*/
private boolean isPrunedClassNameComparison(
- Value classNameValue, Value constStringValue, DexType context) {
+ Value classNameValue, Value constStringValue, ProgramMethod context) {
if (classNameValue.isPhi() || constStringValue.isPhi()) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
index 041cf09..907db14 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
@@ -82,8 +82,8 @@
candidates.put(candidate.type, this);
}
- boolean isHostClassInitializer(DexEncodedMethod method) {
- return factory.isClassConstructor(method.method) && method.holder() == hostType();
+ boolean isHostClassInitializer(ProgramMethod method) {
+ return method.getDefinition().isClassInitializer() && method.getHolderType() == hostType();
}
DexType hostType() {
@@ -217,10 +217,10 @@
//
// NOTE: can be called concurrently.
public final void examineMethodCode(IRCode code) {
- ProgramMethod method = code.context();
+ ProgramMethod context = code.context();
Set<Instruction> alreadyProcessed = Sets.newIdentityHashSet();
- CandidateInfo receiverClassCandidateInfo = candidates.get(method.getHolderType());
+ CandidateInfo receiverClassCandidateInfo = candidates.get(context.getHolderType());
Value receiverValue = code.getThis(); // NOTE: is null for static methods.
if (receiverClassCandidateInfo != null) {
if (receiverValue != null) {
@@ -230,26 +230,26 @@
analyzeAllValueUsers(
receiverClassCandidateInfo,
receiverValue,
- factory.isConstructor(method.getReference()));
+ factory.isConstructor(context.getReference()));
// If the candidate is still valid, ignore all instructions
// we treat as valid usages on receiver.
- if (candidates.get(method.getHolderType()) != null) {
+ if (candidates.get(context.getHolderType()) != null) {
alreadyProcessed.addAll(receiverValue.uniqueUsers());
}
} else {
// We are inside a static method of candidate class.
// Check if this is a valid getter of the singleton field.
- if (method.getDefinition().returnType() == method.getHolderType()) {
+ if (context.getDefinition().returnType() == context.getHolderType()) {
List<Instruction> examined = isValidGetter(receiverClassCandidateInfo, code);
if (examined != null) {
DexEncodedMethod getter = receiverClassCandidateInfo.getter.get();
if (getter == null) {
- receiverClassCandidateInfo.getter.set(method.getDefinition());
+ receiverClassCandidateInfo.getter.set(context.getDefinition());
// Except for static-get and return, iterate other remaining instructions if any.
alreadyProcessed.addAll(examined);
} else {
- assert getter != method.getDefinition();
+ assert getter != context.getDefinition();
// Not sure how to deal with many getters.
receiverClassCandidateInfo.invalidate();
}
@@ -275,8 +275,7 @@
if (instruction.isNewInstance()) {
// Check the class being initialized against valid staticizing candidates.
NewInstance newInstance = instruction.asNewInstance();
- CandidateInfo candidateInfo =
- processInstantiation(method.getDefinition(), iterator, newInstance);
+ CandidateInfo candidateInfo = processInstantiation(context, iterator, newInstance);
if (candidateInfo != null) {
alreadyProcessed.addAll(newInstance.outValue().aliasedUsers());
// For host class initializers having eligible instantiation we also want to
@@ -284,7 +283,7 @@
// This must guarantee that removing field access will not result in missing side
// effects, otherwise we can still staticize, but cannot remove singleton reads.
while (iterator.hasNext()) {
- if (!isAllowedInHostClassInitializer(method.getHolderType(), iterator.next(), code)) {
+ if (!isAllowedInHostClassInitializer(context.getHolderType(), iterator.next(), code)) {
candidateInfo.preserveRead.set(true);
iterator.previous();
break;
@@ -293,7 +292,7 @@
}
referencedFrom
.computeIfAbsent(candidateInfo, ignore -> new LongLivedProgramMethodSetBuilder())
- .add(method);
+ .add(context);
}
continue;
}
@@ -315,7 +314,7 @@
if (info != null) {
referencedFrom
.computeIfAbsent(info, ignore -> new LongLivedProgramMethodSetBuilder())
- .add(method);
+ .add(context);
// If the candidate is still valid, ignore all usages in further analysis.
Value value = instruction.outValue();
if (value != null) {
@@ -331,7 +330,7 @@
if (info != null) {
referencedFrom
.computeIfAbsent(info, ignore -> new LongLivedProgramMethodSetBuilder())
- .add(method);
+ .add(context);
// If the candidate is still valid, ignore all usages in further analysis.
Value value = instruction.outValue();
if (value != null) {
@@ -380,8 +379,7 @@
}
private CandidateInfo processInstantiation(
- DexEncodedMethod method, ListIterator<Instruction> iterator, NewInstance newInstance) {
-
+ ProgramMethod context, ListIterator<Instruction> iterator, NewInstance newInstance) {
DexType candidateType = newInstance.clazz;
CandidateInfo candidateInfo = candidates.get(candidateType);
if (candidateInfo == null) {
@@ -393,7 +391,7 @@
return candidateInfo.invalidate();
}
- if (!candidateInfo.isHostClassInitializer(method)) {
+ if (!candidateInfo.isHostClassInitializer(context)) {
// A valid candidate must only have one instantiation which is
// done in the static initializer of the host class.
return candidateInfo.invalidate();
@@ -445,7 +443,7 @@
}
Set<Instruction> users = SetUtils.newIdentityHashSet(candidateValue.uniqueUsers());
Instruction constructorCall = iterator.next();
- if (!isValidInitCall(candidateInfo, constructorCall, candidateValue, candidateType)) {
+ if (!isValidInitCall(candidateInfo, constructorCall, candidateValue, context)) {
iterator.previous();
return candidateInfo.invalidate();
}
@@ -475,7 +473,7 @@
}
private boolean isValidInitCall(
- CandidateInfo info, Instruction instruction, Value candidateValue, DexType candidateType) {
+ CandidateInfo info, Instruction instruction, Value candidateValue, ProgramMethod context) {
if (!instruction.isInvokeDirect()) {
return false;
}
@@ -483,12 +481,12 @@
// Check constructor.
InvokeDirect invoke = instruction.asInvokeDirect();
DexEncodedMethod methodInvoked =
- appView.appInfo().lookupDirectTarget(invoke.getInvokedMethod(), info.candidate);
+ appView.appInfo().lookupDirectTarget(invoke.getInvokedMethod(), context);
List<Value> values = invoke.inValues();
if (ListUtils.lastIndexMatching(values, v -> v.getAliasedValue() == candidateValue) != 0
|| methodInvoked == null
- || methodInvoked.holder() != candidateType) {
+ || methodInvoked.holder() != info.candidate.type) {
return false;
}
@@ -511,8 +509,7 @@
}
// Allow single assignment to a singleton field.
StaticPut staticPut = instruction.asStaticPut();
- DexEncodedField fieldAccessed =
- appView.appInfo().lookupStaticTarget(staticPut.getField().holder, staticPut.getField());
+ DexEncodedField fieldAccessed = appView.appInfo().lookupStaticTarget(staticPut.getField());
return fieldAccessed == info.singletonField;
}
@@ -529,8 +526,7 @@
for (Instruction instr : code.instructions()) {
if (instr.isStaticGet()) {
staticGet = instr.asStaticGet();
- DexEncodedField fieldAccessed =
- appView.appInfo().lookupStaticTarget(staticGet.getField().holder, staticGet.getField());
+ DexEncodedField fieldAccessed = appView.appInfo().lookupStaticTarget(staticGet.getField());
if (fieldAccessed != info.singletonField) {
return null;
}
@@ -562,7 +558,7 @@
return null;
}
- assert candidateInfo.singletonField == appView.appInfo().lookupStaticTarget(field.holder, field)
+ assert candidateInfo.singletonField == appView.appInfo().lookupStaticTarget(field)
: "Added reference after collectCandidates(...)?";
Value singletonValue = staticGet.dest();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
index 07d330b..53122b0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringBuilderOptimizer.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.escape.EscapeAnalysis;
import com.android.tools.r8.ir.analysis.escape.EscapeAnalysisConfiguration;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
@@ -882,7 +883,7 @@
AppView<?> appView,
EscapeAnalysis escapeAnalysis,
Instruction escapeRoute,
- DexMethod context) {
+ ProgramMethod context) {
if (escapeRoute.isReturn() || escapeRoute.isThrow() || escapeRoute.isStaticPut()) {
logEscapingRoute(false);
return false;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
index ae94194..d00100a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/string/StringOptimizer.java
@@ -17,6 +17,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.escape.EscapeAnalysis;
import com.android.tools.r8.ir.analysis.escape.EscapeAnalysisConfiguration;
import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
@@ -589,7 +590,7 @@
AppView<?> appView,
EscapeAnalysis escapeAnalysis,
Instruction escapeRoute,
- DexMethod context) {
+ ProgramMethod context) {
if (escapeRoute.isReturn() || escapeRoute.isThrow() || escapeRoute.isStaticPut()) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index dc9d272..029cd51 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -15,12 +15,13 @@
import com.android.tools.r8.graph.FieldAccessInfo;
import com.android.tools.r8.graph.FieldAccessInfoCollection;
import com.android.tools.r8.graph.GraphLense;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.Invoke.Type;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.Map;
-import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -126,7 +127,7 @@
}
private void computeMethodRebinding(
- Map<DexMethod, Set<DexEncodedMethod>> methodsWithContexts,
+ Map<DexMethod, ProgramMethodSet> methodsWithContexts,
Function<DexMethod, DexEncodedMethod> lookupTarget,
Type invokeType) {
for (DexMethod method : methodsWithContexts.keySet()) {
@@ -158,9 +159,9 @@
// If the target class is not public but the targeted method is, we might run into
// visibility problems when rebinding.
final DexEncodedMethod finalTarget = target;
- Set<DexEncodedMethod> contexts = methodsWithContexts.get(method);
+ ProgramMethodSet contexts = methodsWithContexts.get(method);
if (contexts.stream()
- .anyMatch(context -> mayNeedBridgeForVisibility(context.holder(), finalTarget))) {
+ .anyMatch(context -> mayNeedBridgeForVisibility(context, finalTarget))) {
target =
insertBridgeForVisibilityIfNeeded(
method, target, originalClass, targetClass, lookupTarget);
@@ -216,16 +217,18 @@
return findHolderForInterfaceMethodBridge(superClass.asProgramClass(), iface);
}
- private boolean mayNeedBridgeForVisibility(DexType context, DexEncodedMethod method) {
+ private boolean mayNeedBridgeForVisibility(ProgramMethod context, DexEncodedMethod method) {
DexType holderType = method.holder();
DexClass holder = appView.definitionFor(holderType);
if (holder == null) {
return false;
}
ConstraintWithTarget classVisibility =
- ConstraintWithTarget.deriveConstraint(context, holderType, holder.accessFlags, appView);
+ ConstraintWithTarget.deriveConstraint(
+ context.getHolder(), holderType, holder.accessFlags, appView);
ConstraintWithTarget methodVisibility =
- ConstraintWithTarget.deriveConstraint(context, holderType, method.accessFlags, appView);
+ ConstraintWithTarget.deriveConstraint(
+ context.getHolder(), holderType, method.accessFlags, appView);
// We may need bridge for visibility if the target class is not visible while the target method
// is visible from the calling context.
return classVisibility == ConstraintWithTarget.NEVER
@@ -297,7 +300,7 @@
}
private void computeFieldRebindingForIndirectAccessWithContexts(
- DexField field, Set<DexEncodedMethod> contexts) {
+ DexField field, ProgramMethodSet contexts) {
DexEncodedField target = appView.appInfo().resolveField(field).getResolvedField();
if (target == null) {
assert false;
@@ -315,14 +318,14 @@
.allMatch(
context ->
isMemberVisibleFromOriginalContext(
- appView, context.holder(), target.holder(), target.accessFlags))) {
+ appView, context, target.holder(), target.accessFlags))) {
builder.map(
field, lense.lookupField(validTargetFor(target.field, field, DexClass::lookupField)));
}
}
public static boolean isTypeVisibleFromContext(
- AppView<?> appView, DexType context, DexType type) {
+ AppView<?> appView, ProgramMethod context, DexType type) {
DexType baseType = type.toBaseType(appView.dexItemFactory());
if (baseType.isPrimitiveType()) {
return true;
@@ -331,26 +334,28 @@
}
public static boolean isClassTypeVisibleFromContext(
- AppView<?> appView, DexType context, DexType type) {
+ AppView<?> appView, ProgramMethod context, DexType type) {
assert type.isClassType();
DexClass clazz = appView.definitionFor(type);
return clazz != null && isClassTypeVisibleFromContext(appView, context, clazz);
}
public static boolean isClassTypeVisibleFromContext(
- AppView<?> appView, DexType context, DexClass clazz) {
+ AppView<?> appView, ProgramMethod context, DexClass clazz) {
ConstraintWithTarget classVisibility =
- ConstraintWithTarget.deriveConstraint(context, clazz.type, clazz.accessFlags, appView);
+ ConstraintWithTarget.deriveConstraint(
+ context.getHolder(), clazz.type, clazz.accessFlags, appView);
return classVisibility != ConstraintWithTarget.NEVER;
}
public static boolean isMemberVisibleFromOriginalContext(
- AppView<?> appView, DexType context, DexType holder, AccessFlags<?> memberAccessFlags) {
+ AppView<?> appView, ProgramMethod context, DexType holder, AccessFlags<?> memberAccessFlags) {
if (!isClassTypeVisibleFromContext(appView, context, holder)) {
return false;
}
ConstraintWithTarget memberVisibility =
- ConstraintWithTarget.deriveConstraint(context, holder, memberAccessFlags, appView);
+ ConstraintWithTarget.deriveConstraint(
+ context.getHolder(), holder, memberAccessFlags, appView);
return memberVisibility != ConstraintWithTarget.NEVER;
}
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 77edcc6..919be25 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -50,6 +50,7 @@
import com.android.tools.r8.utils.PredicateSet;
import com.android.tools.r8.utils.TraversalContinuation;
import com.android.tools.r8.utils.Visibility;
+import com.android.tools.r8.utils.collections.ProgramMethodSet;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableSortedSet.Builder;
@@ -121,15 +122,15 @@
/** Information about instantiated classes and their allocation sites. */
private final ObjectAllocationInfoCollectionImpl objectAllocationInfoCollection;
/** Set of all methods referenced in virtual invokes, along with calling context. */
- public final SortedMap<DexMethod, Set<DexEncodedMethod>> virtualInvokes;
+ public final SortedMap<DexMethod, ProgramMethodSet> virtualInvokes;
/** Set of all methods referenced in interface invokes, along with calling context. */
- public final SortedMap<DexMethod, Set<DexEncodedMethod>> interfaceInvokes;
+ public final SortedMap<DexMethod, ProgramMethodSet> interfaceInvokes;
/** Set of all methods referenced in super invokes, along with calling context. */
- public final SortedMap<DexMethod, Set<DexEncodedMethod>> superInvokes;
+ public final SortedMap<DexMethod, ProgramMethodSet> superInvokes;
/** Set of all methods referenced in direct invokes, along with calling context. */
- public final SortedMap<DexMethod, Set<DexEncodedMethod>> directInvokes;
+ public final SortedMap<DexMethod, ProgramMethodSet> directInvokes;
/** Set of all methods referenced in static invokes, along with calling context. */
- public final SortedMap<DexMethod, Set<DexEncodedMethod>> staticInvokes;
+ public final SortedMap<DexMethod, ProgramMethodSet> staticInvokes;
/**
* Set of live call sites in the code. Note that if desugaring has taken place call site objects
* will have been removed from the code.
@@ -208,11 +209,11 @@
SortedSet<DexMethod> liveMethods,
FieldAccessInfoCollectionImpl fieldAccessInfoCollection,
ObjectAllocationInfoCollectionImpl objectAllocationInfoCollection,
- SortedMap<DexMethod, Set<DexEncodedMethod>> virtualInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> interfaceInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> superInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> directInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> staticInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> virtualInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> interfaceInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> superInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> directInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> staticInvokes,
Set<DexCallSite> callSites,
Set<DexReference> pinnedItems,
Map<DexReference, ProguardMemberRule> mayHaveSideEffects,
@@ -293,11 +294,11 @@
SortedSet<DexMethod> liveMethods,
FieldAccessInfoCollectionImpl fieldAccessInfoCollection,
ObjectAllocationInfoCollectionImpl objectAllocationInfoCollection,
- SortedMap<DexMethod, Set<DexEncodedMethod>> virtualInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> interfaceInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> superInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> directInvokes,
- SortedMap<DexMethod, Set<DexEncodedMethod>> staticInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> virtualInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> interfaceInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> superInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> directInvokes,
+ SortedMap<DexMethod, ProgramMethodSet> staticInvokes,
Set<DexCallSite> callSites,
Set<DexReference> pinnedItems,
Map<DexReference, ProguardMemberRule> mayHaveSideEffects,
@@ -853,7 +854,8 @@
}
DexType holder = field.holder();
return fieldAccessInfo.isWrittenOnlyInMethodSatisfying(
- method -> method.isInstanceInitializer() && method.holder() == holder);
+ method ->
+ method.getDefinition().isInstanceInitializer() && method.getHolderType() == holder);
}
public boolean isStaticFieldWrittenOnlyInEnclosingStaticInitializer(DexEncodedField field) {
@@ -885,15 +887,15 @@
return builder.build();
}
- private static <T extends PresortedComparable<T>, S>
- SortedMap<T, Set<S>> rewriteKeysConservativelyWhileMergingValues(
- Map<T, Set<S>> original, Function<T, Set<T>> rewrite) {
- SortedMap<T, Set<S>> result = new TreeMap<>(PresortedComparable::slowCompare);
+ private static <T extends PresortedComparable<T>>
+ SortedMap<T, ProgramMethodSet> rewriteKeysConservativelyWhileMergingValues(
+ Map<T, ProgramMethodSet> original, Function<T, Set<T>> rewrite) {
+ SortedMap<T, ProgramMethodSet> result = new TreeMap<>(PresortedComparable::slowCompare);
for (T item : original.keySet()) {
Set<T> rewrittenKeys = rewrite.apply(item);
for (T rewrittenKey : rewrittenKeys) {
result
- .computeIfAbsent(rewrittenKey, k -> Sets.newIdentityHashSet())
+ .computeIfAbsent(rewrittenKey, k -> ProgramMethodSet.create())
.addAll(original.get(item));
}
}
@@ -1053,7 +1055,7 @@
public DexEncodedMethod lookupSingleTarget(
Type type,
DexMethod target,
- DexType invocationContext,
+ ProgramMethod context,
LibraryModeledPredicate modeledPredicate) {
assert checkIfObsolete();
DexType holder = target.holder;
@@ -1062,15 +1064,15 @@
}
switch (type) {
case VIRTUAL:
- return lookupSingleVirtualTarget(target, invocationContext, false, modeledPredicate);
+ return lookupSingleVirtualTarget(target, context, false, modeledPredicate);
case INTERFACE:
- return lookupSingleVirtualTarget(target, invocationContext, true, modeledPredicate);
+ return lookupSingleVirtualTarget(target, context, true, modeledPredicate);
case DIRECT:
- return lookupDirectTarget(target, invocationContext);
+ return lookupDirectTarget(target, context);
case STATIC:
- return lookupStaticTarget(target, invocationContext);
+ return lookupStaticTarget(target, context);
case SUPER:
- return lookupSuperTarget(target, invocationContext);
+ return lookupSuperTarget(target, context);
default:
return null;
}
@@ -1079,44 +1081,39 @@
public ProgramMethod lookupSingleProgramTarget(
Type type,
DexMethod target,
- DexType invocationContext,
+ ProgramMethod context,
LibraryModeledPredicate modeledPredicate) {
- return asProgramMethodOrNull(
- lookupSingleTarget(type, target, invocationContext, modeledPredicate), this);
+ return asProgramMethodOrNull(lookupSingleTarget(type, target, context, modeledPredicate), this);
}
/** For mapping invoke virtual instruction to single target method. */
public DexEncodedMethod lookupSingleVirtualTarget(
- DexMethod method, DexType invocationContext, boolean isInterface) {
+ DexMethod method, ProgramMethod context, boolean isInterface) {
assert checkIfObsolete();
return lookupSingleVirtualTarget(
- method, invocationContext, isInterface, type -> false, method.holder, null);
+ method, context, isInterface, type -> false, method.holder, null);
}
/** For mapping invoke virtual instruction to single target method. */
public DexEncodedMethod lookupSingleVirtualTarget(
DexMethod method,
- DexType invocationContext,
+ ProgramMethod context,
boolean isInterface,
LibraryModeledPredicate modeledPredicate) {
assert checkIfObsolete();
return lookupSingleVirtualTarget(
- method, invocationContext, isInterface, modeledPredicate, method.holder, null);
+ method, context, isInterface, modeledPredicate, method.holder, null);
}
public DexEncodedMethod lookupSingleVirtualTarget(
DexMethod method,
- DexType invocationContext,
+ ProgramMethod context,
boolean isInterface,
LibraryModeledPredicate modeledPredicate,
DexType refinedReceiverType,
ClassTypeElement receiverLowerBoundType) {
assert checkIfObsolete();
assert refinedReceiverType != null;
-
- DexProgramClass invocationClass = asProgramClassOrNull(definitionFor(invocationContext));
- assert invocationClass != null;
-
if (!refinedReceiverType.isClassType()) {
// The refined receiver is not of class type and we will not be able to find a single target
// (it is either primitive or array).
@@ -1140,7 +1137,7 @@
SingleResolutionResult resolution =
resolveMethod(initialResolutionHolder, method).asSingleResolution();
if (resolution == null
- || resolution.isAccessibleForVirtualDispatchFrom(invocationClass, this).isFalse()) {
+ || resolution.isAccessibleForVirtualDispatchFrom(context.getHolder(), this).isFalse()) {
return null;
}
// If the method is modeled, return the resolution.
@@ -1189,7 +1186,7 @@
LookupResultSuccess lookupResult =
resolution
.lookupVirtualDispatchTargets(
- invocationClass, this, refinedReceiverClass.asProgramClass(), refinedLowerBound)
+ context.getHolder(), this, refinedReceiverClass.asProgramClass(), refinedLowerBound)
.asLookupResultSuccess();
if (lookupResult != null && !lookupResult.isIncomplete()) {
LookupTarget singleTarget = lookupResult.getSingleLookupTarget();
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index f8dcf90..3288a39 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -191,11 +191,11 @@
private AnnotationRemover.Builder annotationRemoverBuilder;
private final DexDefinitionSupplier enqueuerDefinitionSupplier;
- private final Map<DexMethod, Set<DexEncodedMethod>> virtualInvokes = new IdentityHashMap<>();
- private final Map<DexMethod, Set<DexEncodedMethod>> interfaceInvokes = new IdentityHashMap<>();
- private final Map<DexMethod, Set<DexEncodedMethod>> superInvokes = new IdentityHashMap<>();
- private final Map<DexMethod, Set<DexEncodedMethod>> directInvokes = new IdentityHashMap<>();
- private final Map<DexMethod, Set<DexEncodedMethod>> staticInvokes = new IdentityHashMap<>();
+ private final Map<DexMethod, ProgramMethodSet> virtualInvokes = new IdentityHashMap<>();
+ private final Map<DexMethod, ProgramMethodSet> interfaceInvokes = new IdentityHashMap<>();
+ private final Map<DexMethod, ProgramMethodSet> superInvokes = new IdentityHashMap<>();
+ private final Map<DexMethod, ProgramMethodSet> directInvokes = new IdentityHashMap<>();
+ private final Map<DexMethod, ProgramMethodSet> staticInvokes = new IdentityHashMap<>();
private final FieldAccessInfoCollectionImpl fieldAccessInfoCollection =
new FieldAccessInfoCollectionImpl();
private final ObjectAllocationInfoCollectionImpl.Builder objectAllocationInfoCollection;
@@ -705,44 +705,39 @@
//
private boolean registerMethodWithTargetAndContext(
- Map<DexMethod, Set<DexEncodedMethod>> seen, DexMethod method, ProgramMethod context) {
+ Map<DexMethod, ProgramMethodSet> seen, DexMethod method, ProgramMethod context) {
DexType baseHolder = method.holder.toBaseType(appView.dexItemFactory());
if (baseHolder.isClassType()) {
markTypeAsLive(baseHolder, clazz -> graphReporter.reportClassReferencedFrom(clazz, context));
- return seen.computeIfAbsent(method, ignore -> Sets.newIdentityHashSet())
- .add(context.getDefinition());
+ return seen.computeIfAbsent(method, ignore -> ProgramMethodSet.create()).add(context);
}
return false;
}
public boolean registerFieldRead(DexField field, ProgramMethod context) {
- return registerFieldAccess(field, context.getDefinition(), true, false);
- }
-
- public boolean registerFieldReadFromAnnotation(DexField field) {
- return registerFieldAccess(field, DexEncodedMethod.ANNOTATION_REFERENCE, true, false);
+ return registerFieldAccess(field, context, true, false);
}
public boolean registerReflectiveFieldRead(DexField field, ProgramMethod context) {
- return registerFieldAccess(field, context.getDefinition(), true, true);
+ return registerFieldAccess(field, context, true, true);
}
public boolean registerFieldWrite(DexField field, ProgramMethod context) {
- return registerFieldAccess(field, context.getDefinition(), false, false);
+ return registerFieldAccess(field, context, false, false);
}
public boolean registerReflectiveFieldWrite(DexField field, ProgramMethod context) {
- return registerFieldAccess(field, context.getDefinition(), false, true);
+ return registerFieldAccess(field, context, false, true);
}
public boolean registerReflectiveFieldAccess(DexField field, ProgramMethod context) {
- boolean changed = registerFieldAccess(field, context.getDefinition(), true, true);
- changed |= registerFieldAccess(field, context.getDefinition(), false, true);
+ boolean changed = registerFieldAccess(field, context, true, true);
+ changed |= registerFieldAccess(field, context, false, true);
return changed;
}
private boolean registerFieldAccess(
- DexField field, DexEncodedMethod context, boolean isRead, boolean isReflective) {
+ DexField field, ProgramMethod context, boolean isRead, boolean isReflective) {
FieldAccessInfoImpl info = fieldAccessInfoCollection.get(field);
if (info == null) {
DexEncodedField encodedField = resolveField(field).getResolvedField();
@@ -784,8 +779,7 @@
bootstrapMethods.add(callSite.bootstrapMethod.asMethod());
}
- DexProgramClass contextHolder = context.getHolder();
- LambdaDescriptor descriptor = LambdaDescriptor.tryInfer(callSite, appInfo, contextHolder);
+ LambdaDescriptor descriptor = LambdaDescriptor.tryInfer(callSite, appInfo, context);
if (descriptor == null) {
return;
}
@@ -795,14 +789,13 @@
assert contextMethod.getCode().isCfCode() : "Unexpected input type with lambdas";
CfCode code = contextMethod.getCode().asCfCode();
if (code != null) {
- LambdaClass lambdaClass =
- lambdaRewriter.getOrCreateLambdaClass(descriptor, contextMethod.holder());
+ LambdaClass lambdaClass = lambdaRewriter.getOrCreateLambdaClass(descriptor, context);
lambdaClasses.put(lambdaClass.type, new Pair<>(lambdaClass, context));
lambdaCallSites
.computeIfAbsent(contextMethod, k -> new IdentityHashMap<>())
.put(callSite, lambdaClass);
if (lambdaClass.descriptor.interfaces.contains(appView.dexItemFactory().serializableType)) {
- classesWithSerializableLambdas.add(contextHolder);
+ classesWithSerializableLambdas.add(context.getHolder());
}
}
if (descriptor.delegatesToLambdaImplMethod()) {
@@ -2301,7 +2294,7 @@
}
public boolean isFieldWrittenInMethodSatisfying(
- ProgramField field, Predicate<DexEncodedMethod> predicate) {
+ ProgramField field, Predicate<ProgramMethod> predicate) {
FieldAccessInfoImpl info = fieldAccessInfoCollection.get(field.getReference());
return info != null && info.isWrittenInMethodSatisfying(predicate);
}
@@ -2426,9 +2419,9 @@
DexEncodedMethod resolvedMethod = resolution.getResolvedMethod();
markMethodAsTargeted(new ProgramMethod(resolvedHolder, resolvedMethod), reason);
- DexProgramClass context = contextOrNull == null ? null : contextOrNull.getHolder();
+ DexProgramClass contextHolder = contextOrNull != null ? contextOrNull.getHolder() : null;
if (contextOrNull != null
- && resolution.isAccessibleForVirtualDispatchFrom(context, appInfo).isFalse()) {
+ && resolution.isAccessibleForVirtualDispatchFrom(contextHolder, appInfo).isFalse()) {
// Not accessible from this context, so this call will cause a runtime exception.
return;
}
@@ -2436,7 +2429,7 @@
// If the resolved method is not a virtual target, eg, is static, dispatch will fail too.
if (!resolvedMethod.isVirtualMethod()) {
// This can only happen when context is null, otherwise the access check above will fail.
- assert context == null;
+ assert contextOrNull == null;
return;
}
@@ -2445,7 +2438,7 @@
resolution
.lookupVirtualDispatchTargets(
- context,
+ contextHolder,
appInfo,
(type, subTypeConsumer, lambdaConsumer) ->
objectAllocationInfoCollection.forEachInstantiatedSubType(
@@ -3953,9 +3946,12 @@
return false;
}
if (field.getDefinition().isStatic()) {
- if (!registerFieldReadFromAnnotation(fieldReference)) {
- return false;
- }
+ FieldAccessInfoImpl fieldAccessInfo =
+ fieldAccessInfoCollection.contains(fieldReference)
+ ? fieldAccessInfoCollection.get(fieldReference)
+ : fieldAccessInfoCollection.extend(
+ fieldReference, new FieldAccessInfoImpl(fieldReference));
+ fieldAccessInfo.setReadFromAnnotation();
markStaticFieldAsLive(field, KeepReason.referencedInAnnotation(annotationHolder));
// When an annotation has a field of an enum type with a default value then Java VM
// will use the values() method on that enum class.
diff --git a/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java b/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java
index f73139d..0979ef9 100644
--- a/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java
+++ b/src/main/java/com/android/tools/r8/shaking/LibraryMethodOverrideAnalysis.java
@@ -7,10 +7,10 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.TopDownClassHierarchyTraversal;
import com.android.tools.r8.ir.analysis.escape.EscapeAnalysis;
import com.android.tools.r8.ir.analysis.escape.EscapeAnalysisConfiguration;
@@ -193,7 +193,7 @@
AppView<?> appView,
EscapeAnalysis escapeAnalysis,
Instruction escapeRoute,
- DexMethod context) {
+ ProgramMethod context) {
if (appView.appInfo().hasLiveness()) {
return isLegitimateConstructorInvocation(
appView.withLiveness(), escapeAnalysis, escapeRoute, context);
@@ -205,7 +205,7 @@
AppView<AppInfoWithLiveness> appView,
EscapeAnalysis escapeAnalysis,
Instruction instruction,
- DexMethod context) {
+ ProgramMethod context) {
if (!instruction.isInvokeDirect()) {
return false;
}
@@ -221,7 +221,7 @@
}
}
- DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context.holder);
+ DexEncodedMethod singleTarget = invoke.lookupSingleTarget(appView, context);
if (singleTarget == null) {
return false;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 31d8074..603cb9d 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -382,7 +382,7 @@
TraversalContinuation result =
sourceClass.traverseProgramInstanceInitializers(
method -> {
- AbortReason reason = disallowInlining(method, targetClass.type);
+ AbortReason reason = disallowInlining(method, targetClass);
if (reason != null) {
// Cannot guarantee that markForceInline() will work.
if (Log.ENABLED) {
@@ -1182,7 +1182,7 @@
// Resolution would have succeeded if the method used to be in [type], or if one of
// its super classes declared the method.
boolean resolutionSucceededBeforeMerge =
- renamedMembersLense.hasMappingForSignatureInContext(holder.type, signatureInType)
+ renamedMembersLense.hasMappingForSignatureInContext(holder, signatureInType)
|| appInfo.lookupSuperTarget(signatureInHolder, holder) != null;
if (resolutionSucceededBeforeMerge) {
deferredRenamings.mapVirtualMethodToDirectInType(
@@ -1655,7 +1655,7 @@
}
}
- private AbortReason disallowInlining(ProgramMethod method, DexType invocationContext) {
+ private AbortReason disallowInlining(ProgramMethod method, DexProgramClass context) {
if (appView.options().enableInlining) {
Code code = method.getDefinition().getCode();
if (code.isCfCode()) {
@@ -1664,14 +1664,14 @@
cfCode.computeInliningConstraint(
method,
appView,
- new SingleTypeMapperGraphLense(method.getHolderType(), invocationContext),
- invocationContext);
+ new SingleTypeMapperGraphLense(method.getHolderType(), context),
+ context);
if (constraint == ConstraintWithTarget.NEVER) {
return AbortReason.UNSAFE_INLINING;
}
// Constructors can have references beyond the root main dex classes. This can increase the
// size of the main dex dependent classes and we should bail out.
- if (mainDexClasses.getRoots().contains(invocationContext)
+ if (mainDexClasses.getRoots().contains(context.type)
&& MainDexDirectReferenceTracer.hasReferencesOutsideFromCode(
appView.appInfo(), method, mainDexClasses.getRoots())) {
return AbortReason.MAIN_DEX_ROOT_OUTSIDE_REFERENCE;
@@ -1686,9 +1686,9 @@
private class SingleTypeMapperGraphLense extends GraphLense {
private final DexType source;
- private final DexType target;
+ private final DexProgramClass target;
- public SingleTypeMapperGraphLense(DexType source, DexType target) {
+ public SingleTypeMapperGraphLense(DexType source, DexProgramClass target) {
this.source = source;
this.target = target;
}
@@ -1720,7 +1720,7 @@
@Override
public DexType lookupType(DexType type) {
- return type == source ? target : mergedClasses.getOrDefault(type, type);
+ return type == source ? target.type : mergedClasses.getOrDefault(type, type);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
index 1013539..1202384 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMergerGraphLense.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLense;
@@ -303,9 +304,9 @@
return mergedClasses.getOrDefault(type, type);
}
- public boolean hasMappingForSignatureInContext(DexType context, DexMethod signature) {
+ public boolean hasMappingForSignatureInContext(DexProgramClass context, DexMethod signature) {
Map<DexMethod, GraphLenseLookupResult> virtualToDirectMethodMap =
- contextualVirtualToDirectMethodMaps.get(context);
+ contextualVirtualToDirectMethodMaps.get(context.type);
if (virtualToDirectMethodMap != null) {
return virtualToDirectMethodMap.containsKey(signature);
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index e4b20c6..e92effc 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -839,14 +839,14 @@
}
public void warningMissingTypeForDesugar(
- Origin origin, Position position, DexType missingType, DexType contextType) {
+ Origin origin, Position position, DexType missingType, DexMethod context) {
if (reportedMissingForDesugaring.add(missingType)) {
reporter.warning(
new InterfaceDesugarMissingTypeDiagnostic(
origin,
position,
Reference.classFromDescriptor(missingType.toDescriptorString()),
- Reference.classFromDescriptor(contextType.toDescriptorString()),
+ Reference.classFromDescriptor(context.holder.toDescriptorString()),
null));
}
}
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 7938666..000ffbc 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -33,6 +33,7 @@
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.SmaliWriter;
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.jasmin.JasminBuilder;
@@ -1294,13 +1295,14 @@
return getMethodSubject(application, className, returnType, methodName, parameters).getMethod();
}
- protected DexEncodedMethod getMethod(
+ protected ProgramMethod getMethod(
CodeInspector inspector,
String className,
String returnType,
String methodName,
List<String> parameters) {
- return getMethodSubject(inspector, className, returnType, methodName, parameters).getMethod();
+ return getMethodSubject(inspector, className, returnType, methodName, parameters)
+ .getProgramMethod();
}
protected static void checkInstructions(
diff --git a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
index 945f3c2..71d5ffb 100644
--- a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
+++ b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
@@ -25,6 +25,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -127,13 +128,15 @@
.addDexProgramData(Files.toByteArray(originalDexFile.toFile()), Origin.unknown())
.build();
CodeInspector inspector = new CodeInspector(application);
- DexEncodedMethod method = getMethod(
- inspector,
- "android.databinding.DataBinderMapperImpl",
- "android.databinding.ViewDataBinding",
- "getDataBinder",
- ImmutableList.of("android.databinding.DataBindingComponent", "android.view.View", "int"));
- Instruction[] instructions = method.getCode().asDexCode().instructions;
+ ProgramMethod method =
+ getMethod(
+ inspector,
+ "android.databinding.DataBinderMapperImpl",
+ "android.databinding.ViewDataBinding",
+ "getDataBinder",
+ ImmutableList.of(
+ "android.databinding.DataBindingComponent", "android.view.View", "int"));
+ Instruction[] instructions = method.getDefinition().getCode().asDexCode().instructions;
assertEquals(0, countJumboStrings(instructions));
assertEquals(1, countSimpleNops(instructions));
diff --git a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
index 8524677..7ec4a08 100644
--- a/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/graph/TargetLookupTest.java
@@ -80,12 +80,14 @@
AndroidApp application = buildApplication(builder);
AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
CodeInspector inspector = new CodeInspector(appInfo.app());
- DexEncodedMethod method = getMethod(inspector, DEFAULT_CLASS_NAME, "int", "x",
- ImmutableList.of());
+ ProgramMethod method = getMethod(inspector, DEFAULT_CLASS_NAME, "int", "x", ImmutableList.of());
assertFalse(
- appInfo.resolveMethod(method.holder(), method.method).getSingleTarget().isVirtualMethod());
- assertNull(appInfo.lookupDirectTarget(method.method, method.holder()));
- assertNotNull(appInfo.lookupStaticTarget(method.method, method.holder()));
+ appInfo
+ .resolveMethod(method.getHolderType(), method.getReference())
+ .getSingleTarget()
+ .isVirtualMethod());
+ assertNull(appInfo.lookupDirectTarget(method.getReference(), method));
+ assertNotNull(appInfo.lookupStaticTarget(method.getReference(), method));
if (ToolHelper.getDexVm().getVersion().isOlderThanOrEqual(DexVm.Version.V4_4_4)) {
// Dalvik rejects at verification time instead of producing the
@@ -152,32 +154,35 @@
AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
CodeInspector inspector = new CodeInspector(appInfo.app());
- DexMethod methodXOnTestSuper =
- getMethod(inspector, "TestSuper", "int", "x", ImmutableList.of()).method;
- DexMethod methodYOnTest =
- getMethod(inspector, "Test", "int", "y", ImmutableList.of()).method;
+ ProgramMethod methodXOnTestSuper =
+ getMethod(inspector, "TestSuper", "int", "x", ImmutableList.of());
+ ProgramMethod methodYOnTest = getMethod(inspector, "Test", "int", "y", ImmutableList.of());
- DexType classTestSuper = methodXOnTestSuper.holder;
- DexType classTest = methodYOnTest.holder;
- DexProto methodXProto = methodXOnTestSuper.proto;
- DexString methodXName = methodXOnTestSuper.name;
- DexMethod methodXOnTest =
+ DexType classTestSuper = methodXOnTestSuper.getHolderType();
+ DexType classTest = methodYOnTest.getHolderType();
+ DexProto methodXProto = methodXOnTestSuper.getReference().proto;
+ DexString methodXName = methodXOnTestSuper.getReference().name;
+ DexMethod methodXOnTestReference =
appInfo.dexItemFactory().createMethod(classTest, methodXProto, methodXName);
+ ProgramMethod methodXOnTest =
+ methodYOnTest.getHolder().lookupProgramMethod(methodXOnTestReference);
assertFalse(
appInfo
- .resolveMethod(classTestSuper, methodXOnTestSuper)
+ .resolveMethod(classTestSuper, methodXOnTestSuper.getReference())
.getSingleTarget()
.isVirtualMethod());
- assertNull(appInfo.resolveMethod(classTest, methodXOnTestSuper).getSingleTarget());
- assertNull(appInfo.resolveMethod(classTest, methodXOnTest).getSingleTarget());
+ assertNull(
+ appInfo.resolveMethod(classTest, methodXOnTestSuper.getReference()).getSingleTarget());
+ assertNull(appInfo.resolveMethod(classTest, methodXOnTestReference).getSingleTarget());
- assertNull(appInfo.lookupDirectTarget(methodXOnTestSuper, methodXOnTestSuper.holder));
- assertNull(appInfo.lookupDirectTarget(methodXOnTest, methodXOnTest.holder));
+ assertNull(appInfo.lookupDirectTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper));
+ assertNull(appInfo.lookupDirectTarget(methodXOnTestReference, methodXOnTest));
- assertNotNull(appInfo.lookupStaticTarget(methodXOnTestSuper, methodXOnTestSuper.holder));
+ assertNotNull(
+ appInfo.lookupStaticTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper));
// Accessing a private target on a different type will fail resolution outright.
- assertNull(appInfo.lookupStaticTarget(methodXOnTest, methodXOnTest.holder));
+ assertNull(appInfo.lookupStaticTarget(methodXOnTestReference, methodXOnTest));
assertEquals("OK", runArt(application));
}
@@ -211,8 +216,7 @@
DexField aFieldOnInterface = factory
.createField(factory.createType("LInterface;"), factory.intType, "aField");
- assertEquals(aFieldOnInterface,
- appInfo.lookupStaticTarget(aFieldOnSubClass.holder, aFieldOnSubClass).field);
+ assertEquals(aFieldOnInterface, appInfo.lookupStaticTarget(aFieldOnSubClass).field);
assertEquals("42", runArt(application));
@@ -244,13 +248,13 @@
DexType i3 = factory.createType("L" + pkg + "/I3;");
DexType i4 = factory.createType("L" + pkg + "/I4;");
DexType c0 = factory.createType("L" + pkg + "/C0;");
- DexType c1 = factory.createType("L" + pkg + "/C1;");
- DexType c2 = factory.createType("L" + pkg + "/C2;");
+ DexProgramClass c1 = appInfo.definitionForProgramType(factory.createType("L" + pkg + "/C1;"));
+ DexProgramClass c2 = appInfo.definitionForProgramType(factory.createType("L" + pkg + "/C2;"));
DexProto mProto = factory.createProto(factory.intType);
DexString m = factory.createString("m");
DexMethod mOnC0 = factory.createMethod(c0, mProto, m);
- DexMethod mOnC1 = factory.createMethod(c1, mProto, m);
+ DexMethod mOnC1 = factory.createMethod(c1.type, mProto, m);
DexMethod mOnI0 = factory.createMethod(i0, mProto, m);
DexMethod mOnI1 = factory.createMethod(i1, mProto, m);
DexMethod mOnI2 = factory.createMethod(i2, mProto, m);
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisForNameReflectionTest.java b/src/test/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisForNameReflectionTest.java
index c337379..9362432 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisForNameReflectionTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/escape/EscapeAnalysisForNameReflectionTest.java
@@ -12,6 +12,7 @@
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.AnalysisTestBase;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
@@ -176,14 +177,14 @@
AppView<?> appView,
EscapeAnalysis escapeAnalysis,
Instruction escapeRoute,
- DexMethod context) {
+ ProgramMethod context) {
if (escapeRoute.isReturn() || escapeRoute.isThrow() || escapeRoute.isStaticPut()) {
return false;
}
if (escapeRoute.isInvokeMethod()) {
DexMethod invokedMethod = escapeRoute.asInvokeMethod().getInvokedMethod();
// Heuristic: if the call target has the same method name, it could be still local.
- if (invokedMethod.name == context.name) {
+ if (invokedMethod.name == context.getReference().name) {
return true;
}
// It's not legitimate during testing, except for recursion calls.
diff --git a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
index 7bd9cc9..ac07b70 100644
--- a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.LookupResult;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.resolution.singletarget.Main;
import com.android.tools.r8.resolution.singletarget.one.AbstractSubClass;
@@ -32,9 +33,8 @@
import com.android.tools.r8.resolution.singletarget.two.OtherSubSubClassTwo;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.ImmutableList;
-import java.io.IOException;
+import com.google.common.collect.Sets;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
@@ -76,9 +76,9 @@
public SingleTargetLookupTest(
String methodName,
- Class invokeReceiver,
- Class singleTargetHolderOrNull,
- List<Class> virtualTargetHolders) {
+ Class<?> invokeReceiver,
+ Class<?> singleTargetHolderOrNull,
+ List<Class<?>> virtualTargetHolders) {
this.methodName = methodName;
this.invokeReceiver = invokeReceiver;
this.singleTargetHolderOrNull = singleTargetHolderOrNull;
@@ -166,22 +166,25 @@
});
}
- private static DexType toType(Class clazz, AppInfo appInfo) {
+ private static DexType toType(Class<?> clazz, AppInfo appInfo) {
return buildType(clazz, appInfo.dexItemFactory());
}
private final String methodName;
- private final Class invokeReceiver;
- private final Class singleTargetHolderOrNull;
- private final List<Class> virtualTargetHolders;
+ private final Class<?> invokeReceiver;
+ private final Class<?> singleTargetHolderOrNull;
+ private final List<Class<?>> virtualTargetHolders;
@Test
public void lookupSingleTarget() {
- DexMethod method = buildNullaryVoidMethod(invokeReceiver, methodName, appInfo.dexItemFactory());
+ DexMethod reference =
+ buildNullaryVoidMethod(invokeReceiver, methodName, appInfo.dexItemFactory());
+ ProgramMethod context =
+ appInfo.definitionForProgramType(reference.holder).getProgramDefaultInitializer();
Assert.assertNotNull(
- appInfo.resolveMethod(toType(invokeReceiver, appInfo), method).getSingleTarget());
+ appInfo.resolveMethod(toType(invokeReceiver, appInfo), reference).getSingleTarget());
DexEncodedMethod singleVirtualTarget =
- appInfo.lookupSingleVirtualTarget(method, method.holder, false);
+ appInfo.lookupSingleVirtualTarget(reference, context, false);
if (singleTargetHolderOrNull == null) {
Assert.assertNull(singleVirtualTarget);
} else {
@@ -191,7 +194,7 @@
}
@Test
- public void lookupVirtualTargets() throws IOException {
+ public void lookupVirtualTargets() {
DexMethod method = buildNullaryVoidMethod(invokeReceiver, methodName, appInfo.dexItemFactory());
Assert.assertNotNull(
appInfo.resolveMethod(toType(invokeReceiver, appInfo), method).getSingleTarget());
@@ -203,7 +206,7 @@
appInfo);
assertTrue(lookupResult.isLookupResultSuccess());
assertFalse(lookupResult.asLookupResultSuccess().hasLambdaTargets());
- Set<DexType> targetHolders = new HashSet<>();
+ Set<DexType> targetHolders = Sets.newIdentityHashSet();
lookupResult
.asLookupResultSuccess()
.forEach(
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java
index eb40786..5b08461 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest.java
@@ -14,6 +14,8 @@
import com.android.tools.r8.TestRunResult;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.AndroidApiLevel;
@@ -108,9 +110,9 @@
}
private final TestParameters parameters;
- private final DexMethod methodOnA = buildMethod(A.class, "f");
- private final DexMethod methodOnB = buildMethod(B.class, "f");
- private final DexMethod methodOnC = buildMethod(C.class, "f");
+ private final DexMethod methodOnAReference = buildMethod(A.class, "f");
+ private final DexMethod methodOnBReference = buildMethod(B.class, "f");
+ private final DexMethod methodOnCReference = buildMethod(C.class, "f");
public VirtualOverrideOfStaticMethodWithVirtualParentInterfaceTest(TestParameters parameters) {
this.parameters = parameters;
@@ -118,21 +120,24 @@
@Test
public void lookupSingleTarget() {
+ DexProgramClass bClass = appInfo.definitionForProgramType(methodOnBReference.holder);
+ ProgramMethod methodOnB = bClass.lookupProgramMethod(methodOnBReference);
ResolutionResult resolutionResult =
- appInfo.resolveMethodOnInterface(methodOnB.holder, methodOnB);
+ appInfo.resolveMethodOnInterface(methodOnBReference.holder, methodOnBReference);
DexEncodedMethod resolved = resolutionResult.getSingleTarget();
- assertEquals(methodOnB, resolved.method);
+ assertEquals(methodOnBReference, resolved.method);
assertFalse(resolutionResult.isVirtualTarget());
DexEncodedMethod singleVirtualTarget =
- appInfo.lookupSingleVirtualTarget(methodOnB, methodOnB.holder, false);
+ appInfo.lookupSingleVirtualTarget(methodOnBReference, methodOnB, false);
Assert.assertNull(singleVirtualTarget);
}
@Test
public void lookupVirtualTargets() {
- ResolutionResult resolutionResult = appInfo.resolveMethodOnInterface(methodOnB.holder, methodOnB);
+ ResolutionResult resolutionResult =
+ appInfo.resolveMethodOnInterface(methodOnBReference.holder, methodOnBReference);
DexEncodedMethod resolved = resolutionResult.getSingleTarget();
- assertEquals(methodOnB, resolved.method);
+ assertEquals(methodOnBReference, resolved.method);
assertFalse(resolutionResult.isVirtualTarget());
}
diff --git a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java
index 1f24983..7c91900 100644
--- a/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/VirtualOverrideOfStaticMethodWithVirtualParentTest.java
@@ -16,6 +16,7 @@
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.google.common.collect.ImmutableList;
@@ -165,12 +166,13 @@
@Test
public void lookupSingleTarget() {
+ DexProgramClass bClass = appInfo.definitionForProgramType(methodOnB.holder);
ResolutionResult resolutionResult = appInfo.resolveMethodOnClass(methodOnB.holder, methodOnB);
DexEncodedMethod resolved = resolutionResult.getSingleTarget();
assertEquals(methodOnA, resolved.method);
assertFalse(resolutionResult.isVirtualTarget());
DexEncodedMethod singleVirtualTarget =
- appInfo.lookupSingleVirtualTarget(methodOnB, methodOnB.holder, false);
+ appInfo.lookupSingleVirtualTarget(methodOnB, bClass.getProgramDefaultInitializer(), false);
Assert.assertNull(singleVirtualTarget);
}
diff --git a/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java
index 6faf65f..4d0f445 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/indirectfield/IndirectFieldAccessTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.FieldResolutionResult;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.resolution.access.indirectfield.pkg.C;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -52,6 +53,9 @@
AppInfoWithLiveness appInfo = appView.appInfo();
DexProgramClass cClass =
appInfo.definitionFor(buildType(C.class, appInfo.dexItemFactory())).asProgramClass();
+ ProgramMethod barMethod =
+ cClass.lookupProgramMethod(
+ buildMethod(C.class.getDeclaredMethod("bar"), appInfo.dexItemFactory()));
DexField f =
buildField(
// Reflecting on B.class.getField("f") will give A.f, so manually create the reference.
@@ -59,7 +63,7 @@
appInfo.dexItemFactory());
FieldResolutionResult resolutionResult = appInfo.resolveField(f);
assertTrue(resolutionResult.isSuccessfulResolution());
- assertEquals(OptionalBool.TRUE, resolutionResult.isAccessibleFrom(cClass, appInfo));
+ assertEquals(OptionalBool.TRUE, resolutionResult.isAccessibleFrom(barMethod, appInfo));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java b/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java
index c15c379..48cbcbd 100644
--- a/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/singletarget/InstantiatedLowerBoundTest.java
@@ -18,6 +18,7 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.LookupResult;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ResolutionResult;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.Nullability;
@@ -52,11 +53,15 @@
DexType typeA = buildType(A.class, appInfo.dexItemFactory());
DexType typeB = buildType(B.class, appInfo.dexItemFactory());
DexType typeMain = buildType(Main.class, appInfo.dexItemFactory());
+ DexMethod mainMethodReference =
+ buildMethod(Main.class.getDeclaredMethod("main", String[].class), appInfo.dexItemFactory());
+ ProgramMethod mainMethod =
+ appInfo.definitionForProgramType(typeMain).lookupProgramMethod(mainMethodReference);
DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
ClassTypeElement latticeB =
ClassTypeElement.create(typeB, Nullability.definitelyNotNull(), appView);
DexEncodedMethod singleTarget =
- appInfo.lookupSingleVirtualTarget(fooA, typeMain, false, t -> false, typeA, latticeB);
+ appInfo.lookupSingleVirtualTarget(fooA, mainMethod, false, t -> false, typeA, latticeB);
assertNotNull(singleTarget);
DexMethod fooB = buildNullaryVoidMethod(B.class, "foo", appInfo.dexItemFactory());
assertEquals(fooB, singleTarget.method);
@@ -72,11 +77,15 @@
DexType typeA = buildType(A.class, appInfo.dexItemFactory());
DexType typeB = buildType(B.class, appInfo.dexItemFactory());
DexType typeMain = buildType(Main.class, appInfo.dexItemFactory());
+ DexMethod mainMethodReference =
+ buildMethod(Main.class.getDeclaredMethod("main", String[].class), appInfo.dexItemFactory());
+ ProgramMethod mainMethod =
+ appInfo.definitionForProgramType(typeMain).lookupProgramMethod(mainMethodReference);
DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
ClassTypeElement latticeB =
ClassTypeElement.create(typeB, Nullability.definitelyNotNull(), appView);
DexEncodedMethod singleTarget =
- appInfo.lookupSingleVirtualTarget(fooA, typeMain, false, t -> false, typeA, latticeB);
+ appInfo.lookupSingleVirtualTarget(fooA, mainMethod, false, t -> false, typeA, latticeB);
assertNotNull(singleTarget);
DexMethod fooB = buildNullaryVoidMethod(B.class, "foo", appInfo.dexItemFactory());
assertEquals(fooB, singleTarget.method);
@@ -94,6 +103,10 @@
DexType typeA = buildType(A.class, appInfo.dexItemFactory());
DexType typeC = buildType(C.class, appInfo.dexItemFactory());
DexType typeMain = buildType(MainAllInstantiated.class, appInfo.dexItemFactory());
+ DexMethod mainMethodReference =
+ buildMethod(Main.class.getDeclaredMethod("main", String[].class), appInfo.dexItemFactory());
+ ProgramMethod mainMethod =
+ appInfo.definitionForProgramType(typeMain).lookupProgramMethod(mainMethodReference);
DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
DexMethod fooB = buildNullaryVoidMethod(B.class, "foo", appInfo.dexItemFactory());
DexMethod fooC = buildNullaryVoidMethod(C.class, "foo", appInfo.dexItemFactory());
@@ -120,7 +133,7 @@
ClassTypeElement latticeC =
ClassTypeElement.create(typeC, Nullability.definitelyNotNull(), appView);
DexEncodedMethod singleTarget =
- appInfo.lookupSingleVirtualTarget(fooA, typeMain, false, t -> false, typeA, latticeC);
+ appInfo.lookupSingleVirtualTarget(fooA, mainMethod, false, t -> false, typeA, latticeC);
assertNull(singleTarget);
}
diff --git a/src/test/java/com/android/tools/r8/resolution/singletarget/SuccessAndInvalidLookupTest.java b/src/test/java/com/android/tools/r8/resolution/singletarget/SuccessAndInvalidLookupTest.java
index 870c9cc..9489060 100644
--- a/src/test/java/com/android/tools/r8/resolution/singletarget/SuccessAndInvalidLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/singletarget/SuccessAndInvalidLookupTest.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.ArrayList;
import org.junit.Test;
@@ -42,14 +43,18 @@
factory -> new ArrayList<>(buildKeepRuleForClassAndMethods(Main.class, factory)));
AppInfoWithLiveness appInfo = appView.appInfo();
DexType typeMain = buildType(Main.class, appInfo.dexItemFactory());
+ DexMethod mainMethodReference =
+ buildMethod(Main.class.getDeclaredMethod("main", String[].class), appInfo.dexItemFactory());
+ ProgramMethod mainMethod =
+ appInfo.definitionForProgramType(typeMain).lookupProgramMethod(mainMethodReference);
DexType typeA = buildType(A.class, appInfo.dexItemFactory());
DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
DexEncodedMethod singleTarget =
- appInfo.lookupSingleVirtualTarget(fooA, typeMain, false, t -> false, typeA, null);
+ appInfo.lookupSingleVirtualTarget(fooA, mainMethod, false, t -> false, typeA, null);
assertNotNull(singleTarget);
assertEquals(fooA, singleTarget.method);
DexEncodedMethod invalidSingleTarget =
- appInfo.lookupSingleVirtualTarget(fooA, typeMain, true, t -> false, typeA, null);
+ appInfo.lookupSingleVirtualTarget(fooA, mainMethod, true, t -> false, typeA, null);
assertNull(invalidSingleTarget);
}
@@ -61,15 +66,19 @@
factory -> new ArrayList<>(buildKeepRuleForClassAndMethods(Main.class, factory)));
AppInfoWithLiveness appInfo = appView.appInfo();
DexType typeMain = buildType(Main.class, appInfo.dexItemFactory());
+ DexMethod mainMethodReference =
+ buildMethod(Main.class.getDeclaredMethod("main", String[].class), appInfo.dexItemFactory());
+ ProgramMethod mainMethod =
+ appInfo.definitionForProgramType(typeMain).lookupProgramMethod(mainMethodReference);
DexType typeA = buildType(I.class, appInfo.dexItemFactory());
DexMethod fooI = buildNullaryVoidMethod(I.class, "foo", appInfo.dexItemFactory());
DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
DexEncodedMethod singleTarget =
- appInfo.lookupSingleVirtualTarget(fooI, typeMain, true, t -> false, typeA, null);
+ appInfo.lookupSingleVirtualTarget(fooI, mainMethod, true, t -> false, typeA, null);
assertNotNull(singleTarget);
assertEquals(fooA, singleTarget.method);
DexEncodedMethod invalidSingleTarget =
- appInfo.lookupSingleVirtualTarget(fooI, typeMain, false, t -> false, typeA, null);
+ appInfo.lookupSingleVirtualTarget(fooI, mainMethod, false, t -> false, typeA, null);
assertNull(invalidSingleTarget);
}