Revert "Reland "Maintain mapped range state when computing equal delta ranges""
This reverts commit 347139251b70f57e88f44b4a85e69795d4aff2bb.
Reason for revert: Failing the bots
Change-Id: Ia1ae3cf6a914f1aaec552029563b109ae8ed4461
diff --git a/src/main/java/com/android/tools/r8/utils/BoxBase.java b/src/main/java/com/android/tools/r8/utils/BoxBase.java
index 93f70da..d38d92b 100644
--- a/src/main/java/com/android/tools/r8/utils/BoxBase.java
+++ b/src/main/java/com/android/tools/r8/utils/BoxBase.java
@@ -6,7 +6,6 @@
import java.util.Comparator;
import java.util.Objects;
-import java.util.function.Function;
import java.util.function.Supplier;
public abstract class BoxBase<T> {
@@ -40,12 +39,6 @@
return oldValue;
}
- public T getAndCompute(Function<T, T> newValue) {
- T t = get();
- set(newValue.apply(t));
- return t;
- }
-
void set(T value) {
this.value = value;
}
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 c24826c..4da52b8 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -123,8 +123,7 @@
// Set to true to run compilation in a single thread and without randomly shuffling the input.
// This makes life easier when running R8 in a debugger.
- public static final boolean DETERMINISTIC_DEBUGGING =
- System.getProperty("com.android.tools.r8.deterministicdebugging") != null;
+ public static final boolean DETERMINISTIC_DEBUGGING = false;
// Use a MethodCollection where most interleavings between reading and mutating is caught.
public static final boolean USE_METHOD_COLLECTION_CONCURRENCY_CHECKED = false;
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index ffbe243..90d26b4 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -689,16 +689,26 @@
MappedPosition firstPosition = mappedPositions.get(i);
int j = i + 1;
MappedPosition lastPosition = firstPosition;
- MappedPositionRange mappedPositionRange = MappedPositionRange.SINGLE_LINE;
for (; j < mappedPositions.size(); j++) {
// Break if this position cannot be merged with lastPosition.
MappedPosition currentPosition = mappedPositions.get(j);
- mappedPositionRange =
- mappedPositionRange.canAddNextMappingToRange(lastPosition, currentPosition);
+ // We allow for ranges being mapped to the same line but not to other ranges:
+ // 1:10:void foo():42:42 -> a
+ // is OK since retrace(a(:7)) = 42, however, the following is not OK:
+ // 1:10:void foo():42:43 -> a
+ // since retrace(a(:7)) = 49, which is not correct.
+ boolean isSingleLine = currentPosition.originalLine == firstPosition.originalLine;
+ boolean differentDelta =
+ currentPosition.originalLine - lastPosition.originalLine
+ != currentPosition.obfuscatedLine - lastPosition.obfuscatedLine;
+ boolean isMappingRangeToSingleLine =
+ firstPosition.obfuscatedLine != lastPosition.obfuscatedLine
+ && firstPosition.originalLine == lastPosition.originalLine;
// Note that currentPosition.caller and lastPosition.class must be deep-compared since
// multiple inlining passes lose the canonical property of the positions.
if (currentPosition.method != lastPosition.method
- || mappedPositionRange.isOutOfRange()
+ || (!isSingleLine && differentDelta)
+ || (!isSingleLine && isMappingRangeToSingleLine)
|| !Objects.equals(currentPosition.caller, lastPosition.caller)
// Break when we see a mapped outline
|| currentPosition.outlineCallee != null
@@ -1404,60 +1414,6 @@
}
}
- private enum MappedPositionRange {
- // Single line represent a mapping on the form X:X:<method>:Y:Y.
- SINGLE_LINE,
- // Range to single line allows for a range on the left hand side, X:X':<method>:Y:Y
- RANGE_TO_SINGLE,
- // Same delta is when we have a range on both sides and the delta (line mapping between them)
- // is the same: X:X':<method>:Y:Y' and delta(X,X') = delta(Y,Y')
- SAME_DELTA,
- // Out of range encodes a mapping range that cannot be encoded.
- OUT_OF_RANGE;
-
- private boolean isSingleLine() {
- return this == SINGLE_LINE;
- }
-
- private boolean isRangeToSingle() {
- return this == RANGE_TO_SINGLE;
- }
-
- private boolean isOutOfRange() {
- return this == OUT_OF_RANGE;
- }
-
- public MappedPositionRange canAddNextMappingToRange(
- MappedPosition lastPosition, MappedPosition currentPosition) {
- if (isOutOfRange()) {
- return this;
- }
- // We allow for ranges being mapped to the same line but not to other ranges:
- // 1:10:void foo():42:42 -> a
- // is OK since retrace(a(:7)) = 42, however, the following is not OK:
- // 1:10:void foo():42:43 -> a
- // since retrace(a(:7)) = 49, which is not correct.
- boolean hasSameRightHandSide = lastPosition.originalLine == currentPosition.originalLine;
- if (hasSameRightHandSide) {
- switch (this) {
- case SINGLE_LINE:
- case RANGE_TO_SINGLE:
- return this;
- default:
- return OUT_OF_RANGE;
- }
- }
- if (isRangeToSingle()) {
- // We cannot recover a delta encoding if we have had range to single encoding.
- return OUT_OF_RANGE;
- }
- boolean sameDelta =
- currentPosition.originalLine - lastPosition.originalLine
- == currentPosition.obfuscatedLine - lastPosition.obfuscatedLine;
- return sameDelta ? SAME_DELTA : OUT_OF_RANGE;
- }
- }
-
private static class OutlineFixupBuilder {
private static final int MINIFIED_POSITION_REMOVED = -1;
diff --git a/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java b/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java
deleted file mode 100644
index 34e9db8..0000000
--- a/src/main/java/com/android/tools/r8/utils/StackTraceUtils.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.utils;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.nio.charset.StandardCharsets;
-
-public class StackTraceUtils {
-
- private static final String pathToWriteStacktrace =
- System.getProperty("com.android.tools.r8.internalPathToStacktraces");
-
- private static final String SEPARATOR = "@@@@";
-
- private static final PrintStream printStream = getStacktracePrintStream();
-
- private static final int samplingInterval = getSamplingInterval();
-
- private static int getSamplingInterval() {
- String setSamplingInterval =
- System.getProperty("com.android.tools.r8.internalStackTraceSamplingInterval");
- if (setSamplingInterval == null) {
- return 1000;
- }
- return Integer.parseInt(setSamplingInterval);
- }
-
- private static int counter = 0;
-
- private static PrintStream getStacktracePrintStream() {
- if (pathToWriteStacktrace == null) {
- throw new RuntimeException("pathToWriteStacktrace is null");
- }
- try {
- return new PrintStream(pathToWriteStacktrace, StandardCharsets.UTF_8.name());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Utility function with the only purpose of being able to print stack traces from various
- * inserted points in R8. See RetraceStackTraceFunctionalCompositionTest.
- */
- public static void printCurrentStack(long identifier) {
- if (counter++ < samplingInterval) {
- new RuntimeException("------(" + identifier + "," + counter + ")------")
- .printStackTrace(printStream);
- printStream.println(SEPARATOR);
- }
- }
-}
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceStackTraceFunctionalCompositionTest.java b/src/test/java/com/android/tools/r8/retrace/RetraceStackTraceFunctionalCompositionTest.java
deleted file mode 100644
index 09a05ed..0000000
--- a/src/test/java/com/android/tools/r8/retrace/RetraceStackTraceFunctionalCompositionTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.android.tools.r8.retrace;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-import static org.objectweb.asm.Opcodes.INVOKESTATIC;
-
-import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.transformers.ClassTransformer;
-import com.android.tools.r8.transformers.MethodTransformer;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.Box;
-import com.android.tools.r8.utils.FileUtils;
-import com.android.tools.r8.utils.Pair;
-import com.android.tools.r8.utils.StackTraceUtils;
-import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.ZipUtils;
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.function.Supplier;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-import org.objectweb.asm.MethodVisitor;
-
-@RunWith(Parameterized.class)
-public class RetraceStackTraceFunctionalCompositionTest extends TestBase {
-
- @Parameter() public TestParameters parameters;
-
- private Path rewrittenR8Jar;
- private static final int SAMPLING_SIZE = 50000;
-
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- assumeTrue(ToolHelper.isLinux());
- return getTestParameters().withDefaultCfRuntime().build();
- }
-
- private void insertPrintingOfStacktraces(Path path, Path outputPath) throws Exception {
- String entryNameForClass = ZipUtils.zipEntryNameForClass(StackTraceUtils.class);
- Box<Long> idBox = new Box<>(0L);
- ZipUtils.map(
- path,
- outputPath,
- (zipEntry, bytes) -> {
- String entryName = zipEntry.getName();
- // Only insert into the R8 namespace, this will provide a better sampling than inserting
- // into all calls due to more inlining/outlining could have happened.
- if (ZipUtils.isClassFile(entryName)
- && !entryNameForClass.equals(entryName)
- && entryName.contains("com/android/tools/r8/")) {
- return transformer(bytes, null)
- .addClassTransformer(
- new ClassTransformer() {
- @Override
- public MethodVisitor visitMethod(
- int access,
- String name,
- String descriptor,
- String signature,
- String[] exceptions) {
- MethodVisitor sub =
- super.visitMethod(access, name, descriptor, signature, exceptions);
- if (name.equals("<clinit>")) {
- return sub;
- } else {
- return new InsertStackTraceCallTransformer(
- sub, () -> idBox.getAndCompute(x -> x + 1));
- }
- }
- ;
- })
- .transform();
- }
- return bytes;
- });
- }
-
- private static class InsertStackTraceCallTransformer extends MethodTransformer {
-
- private boolean insertedStackTraceCall = false;
- private final Supplier<Long> idGenerator;
-
- private InsertStackTraceCallTransformer(MethodVisitor visitor, Supplier<Long> idGenerator) {
- this.mv = visitor;
- this.idGenerator = idGenerator;
- }
-
- @Override
- public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
- insertPrintIfFirstInstruction();
- super.visitFieldInsn(opcode, owner, name, descriptor);
- }
-
- @Override
- public void visitInsn(int opcode) {
- insertPrintIfFirstInstruction();
- super.visitInsn(opcode);
- }
-
- @Override
- public void visitLdcInsn(Object value) {
- insertPrintIfFirstInstruction();
- super.visitLdcInsn(value);
- }
-
- @Override
- public void visitMethodInsn(
- int opcode, String owner, String name, String descriptor, boolean isInterface) {
- insertPrintIfFirstInstruction();
- super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
- }
-
- private void insertPrintIfFirstInstruction() {
- if (!insertedStackTraceCall) {
- super.visitLdcInsn(idGenerator.get());
- super.visitMethodInsn(
- INVOKESTATIC, binaryName(StackTraceUtils.class), "printCurrentStack", "(J)V", false);
- insertedStackTraceCall = true;
- }
- }
-
- @Override
- public void visitMaxs(int maxStack, int maxLocals) {
- super.visitMaxs(maxStack + 2, maxLocals);
- }
- }
-
- private Path getRewrittenR8Jar() throws Exception {
- if (rewrittenR8Jar != null) {
- return rewrittenR8Jar;
- }
- rewrittenR8Jar = temp.newFolder().toPath().resolve("r8_with_deps_with_prints.jar");
- insertPrintingOfStacktraces(ToolHelper.R8_WITH_DEPS_JAR, rewrittenR8Jar);
- return rewrittenR8Jar;
- }
-
- @Test
- public void testR8RetraceAndComposition() throws Exception {
- Path rewrittenR8Jar = getRewrittenR8Jar();
- List<String> originalStackTraces = generateStackTraces(rewrittenR8Jar);
- Map<String, List<String>> originalPartitions = partitionStacktraces(originalStackTraces);
-
- List<String> originalStackTracesDeterministicCheck = generateStackTraces(rewrittenR8Jar);
- Map<String, List<String>> deterministicPartitions =
- partitionStacktraces(originalStackTracesDeterministicCheck);
- comparePartitionedStackTraces(originalPartitions, deterministicPartitions);
-
- // Compile rewritten R8 with R8 to obtain first level
- Pair<Path, Path> r8OfR8 = compileR8WithR8(rewrittenR8Jar);
- List<String> firstLevelStackTraces = generateStackTraces(r8OfR8.getFirst());
-
- // If we retrace the entire file we should get the same result as the original.
- List<String> retracedFirstLevelStackTraces = new ArrayList<>();
- Retrace.run(
- RetraceCommand.builder()
- .setRetracedStackTraceConsumer(retracedFirstLevelStackTraces::addAll)
- .setStackTrace(firstLevelStackTraces)
- .setMappingSupplier(
- ProguardMappingSupplier.builder()
- .setProguardMapProducer(ProguardMapProducer.fromPath(r8OfR8.getSecond()))
- .build())
- .build());
- Map<String, List<String>> firstRoundPartitions =
- partitionStacktraces(retracedFirstLevelStackTraces);
- comparePartitionedStackTraces(originalPartitions, firstRoundPartitions);
- }
-
- private void comparePartitionedStackTraces(
- Map<String, List<String>> one, Map<String, List<String>> other) {
- for (Entry<String, List<String>> keyStackTraceEntry : one.entrySet()) {
- String oneAsString = StringUtils.lines(keyStackTraceEntry.getValue());
- String otherAsString = StringUtils.lines(other.get(keyStackTraceEntry.getKey()));
- assertEquals(oneAsString, otherAsString);
- }
- assertEquals(one.keySet(), other.keySet());
- }
-
- private Map<String, List<String>> partitionStacktraces(List<String> allStacktraces) {
- Map<String, List<String>> partitions = new LinkedHashMap<>();
- int lastIndex = 0;
- for (int i = 0; i < allStacktraces.size(); i++) {
- if (allStacktraces.get(i).contains("@@@@")) {
- List<String> stackTrace = allStacktraces.subList(lastIndex, i);
- String keyForStackTrace = getKeyForStackTrace(stackTrace);
- List<String> existing = partitions.put(keyForStackTrace, stackTrace);
- assertNull(existing);
- lastIndex = i + 1;
- i++;
- }
- }
- return partitions;
- }
-
- private String getKeyForStackTrace(List<String> stackTrace) {
- String identifier = "java.lang.RuntimeException: ------(";
- String firstLine = stackTrace.get(0);
- int index = firstLine.indexOf(identifier);
- assertEquals(0, index);
- String endIdentifier = ")------";
- int endIndex = firstLine.indexOf(endIdentifier);
- assertTrue(endIndex > 0);
- return firstLine.substring(index + identifier.length(), endIndex);
- }
-
- private Pair<Path, Path> compileR8WithR8(Path r8Input) throws Exception {
- Path MAIN_KEEP = Paths.get("src/main/keep.txt");
- Path jar = temp.newFolder().toPath().resolve("out.jar");
- Path map = temp.newFolder().toPath().resolve("out.map");
- testForR8(Backend.CF)
- .setMode(CompilationMode.RELEASE)
- .addProgramFiles(r8Input)
- .addKeepRuleFiles(MAIN_KEEP)
- .allowUnusedProguardConfigurationRules()
- .addDontObfuscate()
- .compile()
- .apply(c -> FileUtils.writeTextFile(map, c.getProguardMap()))
- .writeToZip(jar);
- return Pair.create(jar, map);
- }
-
- private List<String> generateStackTraces(Path r8Jar) throws Exception {
- File stacktraceOutput = new File(temp.newFolder(), "stacktraces.txt");
- stacktraceOutput.createNewFile();
- testForExternalR8(Backend.DEX, parameters.getRuntime())
- .useProvidedR8(r8Jar)
- .addProgramClasses(HelloWorld.class)
- .addKeepMainRule(HelloWorld.class)
- .setMinApi(AndroidApiLevel.B)
- .addJvmFlag("-Dcom.android.tools.r8.deterministicdebugging=true")
- .addJvmFlag("-Dcom.android.tools.r8.internalStackTraceSamplingInterval=" + SAMPLING_SIZE)
- .addJvmFlag("-Dcom.android.tools.r8.internalPathToStacktraces=" + stacktraceOutput.toPath())
- .compile();
- return Files.readAllLines(stacktraceOutput.toPath(), StandardCharsets.UTF_8);
- }
-
- public static class HelloWorld {
-
- public static void main(String[] args) {
- System.out.println("Hello World");
- }
- }
-}