Cache stack map verification from open/closed interfaces analysis
Change-Id: I482279b3c84ca25d7bc1b73dce0c428c54730a21
diff --git a/src/main/java/com/android/tools/r8/cf/CfVerifierTool.java b/src/main/java/com/android/tools/r8/cf/CfVerifierTool.java
index bd4a06f..5b1d74f 100644
--- a/src/main/java/com/android/tools/r8/cf/CfVerifierTool.java
+++ b/src/main/java/com/android/tools/r8/cf/CfVerifierTool.java
@@ -36,7 +36,12 @@
appView.setAppServices(AppServices.builder(appView).build());
for (DexProgramClass clazz : appView.appInfo().classes()) {
clazz.forEachProgramMethod(
- method -> method.getDefinition().getCode().asCfCode().verifyFrames(method, appView));
+ method ->
+ method
+ .getDefinition()
+ .getCode()
+ .asCfCode()
+ .getOrComputeStackMapStatus(method, appView));
}
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java b/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java
index 7866b2d..bdd6512 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfFrameVerifier.java
@@ -378,6 +378,10 @@
return this == NOT_PRESENT;
}
+ public boolean isNotVerified() {
+ return this == NOT_VERIFIED;
+ }
+
public boolean isValid() {
return this == VALID;
}
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 0d4f9c9..68deb8e 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -248,6 +248,10 @@
return stackMapStatus;
}
+ public void setStackMapStatus(StackMapStatus stackMapStatus) {
+ this.stackMapStatus = stackMapStatus;
+ }
+
public com.android.tools.r8.position.Position getDiagnosticPosition() {
return diagnosticPosition;
}
@@ -407,7 +411,7 @@
LensCodeRewriterUtils rewriter,
MethodVisitor visitor) {
GraphLens graphLens = appView.graphLens();
- assert verifyFrames(method, appView).isValidOrNotPresent()
+ assert getOrComputeStackMapStatus(method, appView).isValidOrNotPresent()
: "Could not validate stack map frames";
DexItemFactory dexItemFactory = appView.dexItemFactory();
InitClassLens initClassLens = appView.initClassLens();
@@ -545,7 +549,7 @@
}
private void verifyFramesOrRemove(ProgramMethod method, AppView<?> appView, GraphLens codeLens) {
- stackMapStatus = verifyFrames(method, appView, codeLens);
+ stackMapStatus = getOrComputeStackMapStatus(method, appView, codeLens);
if (!stackMapStatus.isValidOrNotPresent()) {
ArrayList<CfInstruction> copy = new ArrayList<>(instructions);
copy.removeIf(CfInstruction::isFrame);
@@ -884,11 +888,20 @@
originalHolder, maxStack, maxLocals, newInstructions, tryCatchRanges, localVariables);
}
- public StackMapStatus verifyFrames(ProgramMethod method, AppView<?> appView) {
- return verifyFrames(method, appView, getCodeLens(appView));
+ public StackMapStatus getOrComputeStackMapStatus(ProgramMethod method, AppView<?> appView) {
+ return getOrComputeStackMapStatus(method, appView, getCodeLens(appView));
}
- public StackMapStatus verifyFrames(ProgramMethod method, AppView<?> appView, GraphLens codeLens) {
+ public StackMapStatus getOrComputeStackMapStatus(
+ ProgramMethod method, AppView<?> appView, GraphLens codeLens) {
+ if (stackMapStatus.isNotVerified()) {
+ setStackMapStatus(computeStackMapStatus(method, appView, codeLens));
+ }
+ return stackMapStatus;
+ }
+
+ private StackMapStatus computeStackMapStatus(
+ ProgramMethod method, AppView<?> appView, GraphLens codeLens) {
CfFrameVerifierEventConsumer eventConsumer =
new CfFrameVerifierEventConsumer() {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index cb3bf73..a62fd2f 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -193,7 +193,8 @@
DexBuilder.removeRedundantDebugPositions(code);
CfCode code = buildCfCode();
assert verifyInvokeInterface(code, appView);
- assert code.verifyFrames(method, appView, appView.graphLens()).isValidOrNotPresent();
+ assert code.getOrComputeStackMapStatus(method, appView, appView.graphLens())
+ .isValidOrNotPresent();
return code;
}
diff --git a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfOpenClosedInterfacesAnalysis.java b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfOpenClosedInterfacesAnalysis.java
index bc44d01..7d65c1e 100644
--- a/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfOpenClosedInterfacesAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/interfaces/analysis/CfOpenClosedInterfacesAnalysis.java
@@ -91,8 +91,12 @@
CfAnalysisConfig config = createConfig(method, cfCode);
CfOpenClosedInterfacesAnalysisHelper helper =
new CfOpenClosedInterfacesAnalysisHelper(appView, method, unverifiableCodeDiagnostics);
- if (runLinearScan(method, cfCode, config, helper).isNotPresent()) {
+ StackMapStatus stackMapStatus = runLinearScan(method, cfCode, config, helper);
+ if (stackMapStatus.isNotPresent()) {
runFixpoint(method, cfCode, config, helper);
+ cfCode.setStackMapStatus(stackMapStatus);
+ } else if (stackMapStatus.isValid()) {
+ cfCode.setStackMapStatus(stackMapStatus);
}
return helper.getOpenInterfaces();
}