Revert "Compute reachability sensitive when parsing program classes"
This reverts commit cebd7fa8add4216e1a11441a134ac7d845c97141.
Reason for revert: test failures
Change-Id: I83ebe28f9f543162ea732d9d2f3d219b8b115529
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index a7e37bc..c43043c 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -809,11 +809,8 @@
public final DexType annotationCovariantReturnTypes =
createStaticallyKnownType(
"Ldalvik/annotation/codegen/CovariantReturnType$CovariantReturnTypes;");
-
- public final String annotationReachabilitySensitiveDesc =
- "Ldalvik/annotation/optimization/ReachabilitySensitive;";
public final DexType annotationReachabilitySensitive =
- createStaticallyKnownType(annotationReachabilitySensitiveDesc);
+ createStaticallyKnownType("Ldalvik/annotation/optimization/ReachabilitySensitive;");
private static final String METAFACTORY_METHOD_NAME = "metafactory";
private static final String METAFACTORY_ALT_METHOD_NAME = "altMetafactory";
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 4669fdb..68bc137 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -204,14 +204,24 @@
* that is the case, dead reference elimination is disabled and locals are kept alive for their
* entire scope.
*/
- public boolean isReachabilitySensitive() {
- assert !reachabilitySensitive.isUnknown();
+ public boolean getOrComputeReachabilitySensitive(AppView<?> appView) {
+ if (reachabilitySensitive.isUnknown()) {
+ reachabilitySensitive = OptionalBool.of(internalComputeReachabilitySensitive(appView));
+ }
return reachabilitySensitive.isTrue();
}
- public void setReachabilitySensitive(boolean isReachabilitySensitive) {
- assert reachabilitySensitive.isUnknown();
- reachabilitySensitive = OptionalBool.of(isReachabilitySensitive);
+ @SuppressWarnings("ReferenceEquality")
+ private boolean internalComputeReachabilitySensitive(AppView<?> appView) {
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
+ for (DexEncodedMember<?, ?> member : members()) {
+ for (DexAnnotation annotation : member.annotations().annotations) {
+ if (annotation.annotation.type == dexItemFactory.annotationReachabilitySensitive) {
+ return true;
+ }
+ }
+ }
+ return false;
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index f53c0ed..089194a 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -51,6 +51,7 @@
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.Iterables;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
@@ -257,7 +258,7 @@
private final List<DexEncodedMethod> directMethods = new ArrayList<>();
private final List<DexEncodedMethod> virtualMethods = new ArrayList<>();
private final Set<Wrapper<DexMethod>> methodSignatures = new HashSet<>();
- private boolean hasReachabilitySensitiveMember = false;
+ private boolean hasReachabilitySensitiveMethod = false;
private SyntheticMarker syntheticMarker = null;
public CreateDexClassVisitor(
@@ -491,6 +492,7 @@
addAnnotation(DexAnnotation.createAnnotationDefaultAnnotation(
type, defaultAnnotations, application.getFactory()));
}
+ checkReachabilitySensitivity();
checkRecord();
T clazz =
classKind.create(
@@ -552,7 +554,6 @@
if (clazz.isProgramClass()) {
DexProgramClass programClass = clazz.asProgramClass();
programClass.setInitialClassFileVersion(version);
- programClass.setReachabilitySensitive(hasReachabilitySensitiveMember);
if (deprecated) {
programClass.setDeprecated();
}
@@ -598,6 +599,33 @@
}
}
+ // If anything is marked reachability sensitive, all methods need to be parsed including
+ // locals information. This propagates the reachability sensitivity bit so that if any field
+ // or method is annotated, all methods get parsed with locals information.
+ private void checkReachabilitySensitivity() {
+ if (hasReachabilitySensitiveMethod || hasReachabilitySensitiveField()) {
+ for (DexEncodedMethod method : Iterables.concat(directMethods, virtualMethods)) {
+ Code code = method.getCode();
+ if (code != null && code.isCfCode()) {
+ code.asLazyCfCode().markReachabilitySensitive();
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("ReferenceEquality")
+ private boolean hasReachabilitySensitiveField() {
+ DexType reachabilitySensitive = application.getFactory().annotationReachabilitySensitive;
+ for (DexEncodedField field : Iterables.concat(instanceFields, staticFields)) {
+ for (DexAnnotation annotation : field.annotations().annotations) {
+ if (annotation.annotation.type == reachabilitySensitive) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private void addDefaultAnnotation(String name, DexValue value) {
if (defaultAnnotations == null) {
defaultAnnotations = new ArrayList<>();
@@ -690,11 +718,6 @@
parsingContext,
parent.application::addKeepDeclaration);
}
-
- // Check for reachability sensitive annotation.
- parent.hasReachabilitySensitiveMember |=
- parent.application.getFactory().annotationReachabilitySensitiveDesc.equals(desc);
-
return createAnnotationVisitor(
desc, visible, getAnnotations(), parent.application, DexAnnotation::new);
}
@@ -858,11 +881,6 @@
parsingContext,
parent.application::addKeepDeclaration);
}
-
- // Check for reachability sensitive annotation.
- parent.hasReachabilitySensitiveMember |=
- parent.application.getFactory().annotationReachabilitySensitiveDesc.equals(desc);
-
return createAnnotationVisitor(
desc, visible, getAnnotations(), parent.application, DexAnnotation::new);
}
@@ -1012,6 +1030,7 @@
.build();
Wrapper<DexMethod> signature = MethodSignatureEquivalence.get().wrap(method);
if (parent.methodSignatures.add(signature)) {
+ parent.hasReachabilitySensitiveMethod |= isReachabilitySensitive();
if (flags.isStatic() || flags.isConstructor() || flags.isPrivate()) {
parent.directMethods.add(dexMethod);
} else {
@@ -1030,6 +1049,18 @@
}
}
+ @SuppressWarnings("ReferenceEquality")
+ private boolean isReachabilitySensitive() {
+ DexType reachabilitySensitive =
+ parent.application.getFactory().annotationReachabilitySensitive;
+ for (DexAnnotation annotation : getAnnotations()) {
+ if (annotation.annotation.type == reachabilitySensitive) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private List<DexAnnotation> getAnnotations() {
if (annotations == null) {
annotations = new ArrayList<>();
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
index 7a903b2..c41f8df 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -119,6 +119,12 @@
private JarApplicationReader application;
private CfCode code;
private ReparseContext context;
+ private boolean reachabilitySensitive = false;
+
+ public void markReachabilitySensitive() {
+ assert code == null;
+ reachabilitySensitive = true;
+ }
@Override
public boolean isCfCode() {
@@ -152,13 +158,11 @@
private void internalParseCode() {
ReparseContext context = this.context;
JarApplicationReader application = this.application;
- assert context != null;
assert application != null;
- boolean reachabilitySensitive = context.owner.asProgramClass().isReachabilitySensitive();
- DebugParsingOptions parsingOptions = getParsingOptions(application, reachabilitySensitive);
+ assert context != null;
// The ClassCodeVisitor is in charge of setting this.context to null.
try {
- parseCode(context, false, parsingOptions);
+ parseCode(context, false);
} catch (JsrEncountered e) {
for (Code code : context.codeList) {
code.asLazyCfCode().code = null;
@@ -166,7 +170,7 @@
code.asLazyCfCode().application = application;
}
try {
- parseCode(context, true, parsingOptions);
+ parseCode(context, true);
} catch (JsrEncountered e1) {
throw new Unreachable(e1);
}
@@ -200,8 +204,9 @@
}
}
- private void parseCode(
- ReparseContext context, boolean useJsrInliner, DebugParsingOptions parsingOptions) {
+ public void parseCode(ReparseContext context, boolean useJsrInliner) {
+ DebugParsingOptions parsingOptions = getParsingOptions(application, reachabilitySensitive);
+
ClassCodeVisitor classVisitor =
new ClassCodeVisitor(
context.owner,
@@ -296,8 +301,7 @@
@Override
public String toString() {
- // Don't force parsing in toString as it causes unexpected behavior when debugging.
- return code != null ? code.toString() : "<lazy-code>";
+ return asCfCode().toString();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/ProgramMethod.java b/src/main/java/com/android/tools/r8/graph/ProgramMethod.java
index 54dc05d..03758b2 100644
--- a/src/main/java/com/android/tools/r8/graph/ProgramMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/ProgramMethod.java
@@ -180,8 +180,8 @@
return getDefinition().getKotlinInfo();
}
- public boolean isReachabilitySensitive() {
- return getHolder().isReachabilitySensitive();
+ public boolean getOrComputeReachabilitySensitive(AppView<?> appView) {
+ return getHolder().getOrComputeReachabilitySensitive(appView);
}
public void setCode(Code newCode, AppView<?> appView) {
@@ -202,7 +202,7 @@
if (appView.testing().noLocalsTableOnInput) {
return false;
}
- return appView.options().debug || isReachabilitySensitive();
+ return appView.options().debug || getOrComputeReachabilitySensitive(appView);
}
public ProgramMethod rewrittenWithLens(
diff --git a/src/main/java/com/android/tools/r8/graph/fixup/TreeFixerBase.java b/src/main/java/com/android/tools/r8/graph/fixup/TreeFixerBase.java
index 5f6d96f..ec65897 100644
--- a/src/main/java/com/android/tools/r8/graph/fixup/TreeFixerBase.java
+++ b/src/main/java/com/android/tools/r8/graph/fixup/TreeFixerBase.java
@@ -113,6 +113,7 @@
return newProgramClasses;
}
+ @SuppressWarnings("ReferenceEquality")
// Should remain private as the correctness of the fixup requires the lazy 'newProgramClasses'.
private DexProgramClass fixupClass(DexProgramClass clazz) {
DexProgramClass newClass =
@@ -140,7 +141,6 @@
newClass.setInstanceFields(fixupFields(clazz.instanceFields()));
newClass.setStaticFields(fixupFields(clazz.staticFields()));
// Transfer properties that are not passed to the constructor.
- newClass.setReachabilitySensitive(clazz.isReachabilitySensitive());
if (clazz.hasClassFileVersion()) {
newClass.setInitialClassFileVersion(clazz.getInitialClassFileVersion());
}
@@ -151,7 +151,7 @@
newClass.setKotlinInfo(clazz.getKotlinInfo());
}
// If the class type changed, record the move in the lens.
- if (newClass.getType().isNotIdenticalTo(clazz.getType())) {
+ if (newClass.getType() != clazz.getType()) {
return recordClassChange(clazz, newClass);
}
return newClass;
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 5077746..7f7653b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -632,7 +632,7 @@
public boolean isConsistentSSABeforeTypesAreCorrectAllowingRedundantBlocks(AppView<?> appView) {
assert isConsistentGraph(appView, true);
- assert consistentBlockInstructions(true);
+ assert consistentBlockInstructions(appView, true);
assert consistentDefUseChains();
assert validThrowingInstructions();
assert noCriticalEdges();
@@ -689,7 +689,7 @@
assert consistentBlockNumbering();
assert consistentPredecessorSuccessors();
assert consistentCatchHandlers();
- assert consistentBlockInstructions(ssa);
+ assert consistentBlockInstructions(appView, ssa);
assert consistentMetadata();
assert verifyAllThrowingInstructionsHavePositions();
return true;
@@ -889,11 +889,13 @@
return true;
}
- private boolean consistentBlockInstructions(boolean ssa) {
+ private boolean consistentBlockInstructions(AppView<?> appView, boolean ssa) {
boolean argumentsAllowed = true;
for (BasicBlock block : blocks) {
assert block.consistentBlockInstructions(
- argumentsAllowed, options.debug || context().isReachabilitySensitive(), ssa);
+ argumentsAllowed,
+ options.debug || context().getOrComputeReachabilitySensitive(appView),
+ ssa);
argumentsAllowed = false;
}
return true;
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 4d73577..15082ac 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
@@ -87,7 +87,7 @@
public DeadInstructionResult canBeDeadCode(AppView<?> appView, IRCode code) {
InternalOptions options = appView.options();
if (options.debug
- || code.context().isReachabilitySensitive()
+ || code.context().getOrComputeReachabilitySensitive(appView)
|| !code.getConversionOptions().isGeneratingDex()) {
return DeadInstructionResult.notDead();
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 8d03811..b95529b 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -502,7 +502,7 @@
}
public boolean isDebugMode() {
- return appView.options().debug || getProgramMethod().isReachabilitySensitive();
+ return appView.options().debug || getProgramMethod().getOrComputeReachabilitySensitive(appView);
}
public Int2ReferenceSortedMap<BlockInfo> getCFG() {
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 e3e340b..733a207 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
@@ -522,7 +522,7 @@
previous = printMethod(code, "IR after disable assertions (SSA)", previous);
}
- boolean isDebugMode = options.debug || context.isReachabilitySensitive();
+ boolean isDebugMode = options.debug || context.getOrComputeReachabilitySensitive(appView);
assert !method.isProcessed() || !isDebugMode
: "Method already processed: "
+ context.toSourceString()
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPass.java b/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPass.java
index 44cf6e7..c56ddbf 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPass.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/passes/CodeRewriterPass.java
@@ -76,7 +76,7 @@
}
protected boolean isDebugMode(ProgramMethod context) {
- return options.debug || context.isReachabilitySensitive();
+ return options.debug || context.getOrComputeReachabilitySensitive(appView);
}
protected abstract String getRewriterId();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java
index b97b26e..8de8311 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java
@@ -90,7 +90,6 @@
MethodCollectionFactory.fromMethods(newDirectMethods, newVirtualMethods),
false,
emulatedInterface.getChecksumSupplier());
- newEmulatedInterface.setReachabilitySensitive(false);
newEmulatedInterface.addExtraInterfaces(
getRewrittenInterfacesOfEmulatedInterface(emulatedInterface), appView.dexItemFactory());
return newEmulatedInterface;
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 b6804e7..c6d8ac4 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
@@ -151,7 +151,7 @@
}
ProgramMethod context = code.context();
- if (context.isReachabilitySensitive()) {
+ if (context.getOrComputeReachabilitySensitive(appView)) {
return ClassInitializerDefaultsResult.empty();
}
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 4b9c547..3d78982 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
@@ -160,7 +160,7 @@
}
ProgramMethod method = code.context();
DexEncodedMethod definition = method.getDefinition();
- if (definition.isClassInitializer() || method.isReachabilitySensitive()) {
+ if (definition.isClassInitializer() || method.getOrComputeReachabilitySensitive(appView)) {
return ConstraintWithTarget.NEVER;
}
KeepMethodInfo keepInfo = appView.getKeepInfo(method);
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index c099750..2acd209 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -233,7 +233,7 @@
// and we do not actually want locals information in the output.
if (options().debug) {
computeDebugInfo(code, blocks, liveIntervals, this, liveAtEntrySets);
- } else if (code.context().isReachabilitySensitive()) {
+ } else if (code.context().getOrComputeReachabilitySensitive(appView)) {
InstructionListIterator it = code.instructionListIterator();
while (it.hasNext()) {
Instruction instruction = it.next();
@@ -1661,7 +1661,7 @@
// Set all free positions for possible registers to max integer.
RegisterPositions freePositions = new RegisterPositionsImpl(registerConstraint + 1);
- if ((options().debug || code.context().isReachabilitySensitive())
+ if ((options().debug || code.context().getOrComputeReachabilitySensitive(appView))
&& !code.method().accessFlags.isStatic()) {
// If we are generating debug information or if the method is reachability sensitive,
// we pin the this value register. The debugger expects to always be able to find it in
@@ -2712,7 +2712,7 @@
}
}
}
- if (appView.options().debug || code.context().isReachabilitySensitive()) {
+ if (appView.options().debug || code.context().getOrComputeReachabilitySensitive(appView)) {
// In debug mode, or if the method is reachability sensitive, extend the live range
// to cover the full scope of a local variable (encoded as debug values).
int number = instruction.getNumber();
diff --git a/src/main/java/com/android/tools/r8/shaking/EnqueuerDeferredTracingImpl.java b/src/main/java/com/android/tools/r8/shaking/EnqueuerDeferredTracingImpl.java
index af43714..8eac490 100644
--- a/src/main/java/com/android/tools/r8/shaking/EnqueuerDeferredTracingImpl.java
+++ b/src/main/java/com/android/tools/r8/shaking/EnqueuerDeferredTracingImpl.java
@@ -97,7 +97,7 @@
}
// If the access is from a reachability sensitive method, then bail out.
- if (context.getHolder().isReachabilitySensitive()) {
+ if (context.getHolder().getOrComputeReachabilitySensitive(appView)) {
return enqueueDeferredEnqueuerActions(field);
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index 44324b7..068a1a7 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -220,9 +220,6 @@
}
clazz.setDirectMethods(directMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
clazz.setVirtualMethods(virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
- if (clazz.isProgramClass()) {
- clazz.asProgramClass().setReachabilitySensitive(false);
- }
return clazz;
}
}
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 1a92b00..7a109a2 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -917,12 +917,12 @@
public boolean debug = false;
- public boolean shouldCompileMethodInDebugMode(ProgramMethod method) {
- return debug || method.isReachabilitySensitive();
+ public boolean shouldCompileMethodInDebugMode(AppView<?> appView, ProgramMethod method) {
+ return debug || method.getOrComputeReachabilitySensitive(appView);
}
public boolean shouldCompileMethodInReleaseMode(AppView<?> appView, ProgramMethod method) {
- return !shouldCompileMethodInDebugMode(method);
+ return !shouldCompileMethodInDebugMode(appView, method);
}
private final AccessModifierOptions accessModifierOptions = new AccessModifierOptions(this);