Maintain native pc encoded debug info for reoptimize dex.
Re-storing the native encoding is followup work (marked todo).
Bug: b/498336713
Change-Id: Id6139f19035bd84dfb435688bd968a5e23b1d2d6
diff --git a/src/main/java/com/android/tools/r8/D8.java b/src/main/java/com/android/tools/r8/D8.java
index 4806dea..e3055dd 100644
--- a/src/main/java/com/android/tools/r8/D8.java
+++ b/src/main/java/com/android/tools/r8/D8.java
@@ -8,13 +8,18 @@
import com.android.tools.r8.androidapi.ApiReferenceStubber;
import com.android.tools.r8.assistant.AssistantInstrumentation;
+import com.android.tools.r8.debuginfo.DebugRepresentation;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.dex.code.DexInstruction;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.graph.DexDebugInfo.PcBasedDebugInfo;
+import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.LazyLoadedDexApplication;
@@ -56,6 +61,8 @@
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
@@ -216,6 +223,7 @@
timing.begin("Read input app");
AppView<AppInfo> appView = readApp(inputApp, options, executor, timing);
timing.end();
+ materializeMissingDebugInfo(appView, executor, timing);
timing.begin("Initialize assume info collection");
initializeAssumeInfoCollection(appView);
timing.end();
@@ -352,6 +360,46 @@
consumer.finished();
}
+ private static void materializeMissingDebugInfo(
+ AppView<AppInfo> appView, ExecutorService executor, Timing timing) throws ExecutionException {
+ if (!appView.options().enableDexToDexCodeOptimizations) {
+ return;
+ }
+ timing.time(
+ "Materialize missing debug info",
+ () -> {
+ ConcurrentHashMap<PcBasedDebugInfo, PcBasedDebugInfo> cache = new ConcurrentHashMap<>();
+ // Methods without debug info is assumed to be native pc encoded debug info.
+ // Rematerialize into PcEncodedDebugInfo.
+ ThreadUtils.processItems(
+ appView.appInfo().classes(),
+ clazz -> materializeMissingDebugInfo(clazz, cache),
+ appView.options().getThreadingModule(),
+ executor);
+ });
+ }
+
+ private static void materializeMissingDebugInfo(
+ DexProgramClass clazz, ConcurrentMap<PcBasedDebugInfo, PcBasedDebugInfo> cache) {
+ for (DexEncodedMethod method : clazz.methods()) {
+ if (!method.hasCode() || !method.getCode().isDexCode()) {
+ continue;
+ }
+ DexCode code = method.getCode().asDexCode();
+ if (code.getDebugInfo() != null) {
+ continue;
+ }
+ DexInstruction lastInstruction = DebugRepresentation.getLastExecutableInstruction(code);
+ if (lastInstruction == null) {
+ continue;
+ }
+ int maxPc = lastInstruction.getOffset();
+ int parameterCount = method.getParameters().size();
+ PcBasedDebugInfo debugInfo = new PcBasedDebugInfo(parameterCount, maxPc);
+ code.setDebugInfo(cache.computeIfAbsent(debugInfo, k -> k));
+ }
+ }
+
private static void writeApplication(
AppView<AppInfo> appView,
AndroidApp inputApp,
diff --git a/src/test/java/com/android/tools/r8/redex/NativeDebugPreservationTest.java b/src/test/java/com/android/tools/r8/redex/NativeDebugPreservationTest.java
index 7200e59..8ef65cd 100644
--- a/src/test/java/com/android/tools/r8/redex/NativeDebugPreservationTest.java
+++ b/src/test/java/com/android/tools/r8/redex/NativeDebugPreservationTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.redex;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.TestBase;
@@ -61,7 +62,8 @@
inspector -> {
ClassSubject clazz = inspector.clazz(TestClass.class);
MethodSubject method = clazz.uniqueMethodWithOriginalName("main");
- assertFalse("Expected no debug info", method.hasLineNumberTable());
+ // TODO(b/498336713): re-encode the pc debug info.
+ assertTrue("Expected no debug info", method.hasLineNumberTable());
});
}
diff --git a/src/test/java/com/android/tools/r8/redex/StacktracePreservationTest.java b/src/test/java/com/android/tools/r8/redex/StacktracePreservationTest.java
index 1cb4d1f..625f676 100644
--- a/src/test/java/com/android/tools/r8/redex/StacktracePreservationTest.java
+++ b/src/test/java/com/android/tools/r8/redex/StacktracePreservationTest.java
@@ -134,14 +134,7 @@
stacktrace -> {
assertThat(stacktrace, not(StackTrace.isSame(getExpectedStackTrace())));
StackTrace retracedStackTrace = stacktrace.retrace(r8Mapping);
- if (compilationApiLevel == AndroidApiLevel.CINNAMON_BUN
- && redexApiLevel == AndroidApiLevel.CINNAMON_BUN) {
- // TODO(b/498336713): Fix trace preservation for native pc encoding, removing this
- // special case.
- assertThat(retracedStackTrace, not(StackTrace.isSame(getExpectedStackTrace())));
- } else {
- assertThat(retracedStackTrace, StackTrace.isSame(getExpectedStackTrace()));
- }
+ assertThat(retracedStackTrace, StackTrace.isSame(getExpectedStackTrace()));
});
}