Version 2.0.43
Cherry pick: Don't emit line numbers when keepparameternames is set
CL: https://r8-review.googlesource.com/c/r8/+/49268
Bug: 150400371
Change-Id: Ia60a3c11bb4cb07cb4604b35fc3d3da705130951
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 3a0340e..993d66a 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
// This field is accessed from release scripts using simple pattern matching.
// Therefore, changing this field could break our release scripts.
- public static final String LABEL = "2.0.42";
+ public static final String LABEL = "2.0.43";
private Version() {
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexCode.java b/src/main/java/com/android/tools/r8/graph/DexCode.java
index d32abdf..a683332 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -290,9 +290,13 @@
debugInfo = debugInfoIterator.hasNext() ? debugInfoIterator.next() : null;
}
int instructionNumber = 0;
+ Map<Integer, DebugLocalInfo> locals = Collections.emptyMap();
for (Instruction insn : instructions) {
while (debugInfo != null && debugInfo.address == insn.getOffset()) {
- builder.append(" ").append(debugInfo.toString(false)).append("\n");
+ if (debugInfo.lineEntry || !locals.equals(debugInfo.locals)) {
+ builder.append(" ").append(debugInfo.toString(false)).append("\n");
+ }
+ locals = debugInfo.locals;
debugInfo = debugInfoIterator.hasNext() ? debugInfoIterator.next() : null;
}
StringUtils.appendLeftPadded(builder, Integer.toString(instructionNumber++), 5);
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 d012556..09b40ee 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -147,11 +147,25 @@
return code;
}
+ public static class DebugParsingOptions {
+ public final boolean lineInfo;
+ public final boolean localInfo;
+ public final int asmReaderOptions;
+
+ public DebugParsingOptions(boolean lineInfo, boolean localInfo, int asmReaderOptions) {
+ this.lineInfo = lineInfo;
+ this.localInfo = localInfo;
+ this.asmReaderOptions = asmReaderOptions;
+ }
+ }
+
public void parseCode(ReparseContext context, boolean useJsrInliner) {
- int parsingOptions = getParsingOptions(application, reachabilitySensitive);
+ DebugParsingOptions parsingOptions = getParsingOptions(application, reachabilitySensitive);
+
ClassCodeVisitor classVisitor =
- new ClassCodeVisitor(context.owner, createCodeLocator(context), application, useJsrInliner);
- new ClassReader(context.classCache).accept(classVisitor, parsingOptions);
+ new ClassCodeVisitor(
+ context.owner, createCodeLocator(context), application, useJsrInliner, parsingOptions);
+ new ClassReader(context.classCache).accept(classVisitor, parsingOptions.asmReaderOptions);
}
private void setCode(CfCode code) {
@@ -251,17 +265,20 @@
private final BiFunction<String, String, LazyCfCode> codeLocator;
private final JarApplicationReader application;
private boolean usrJsrInliner;
+ private final DebugParsingOptions debugParsingOptions;
ClassCodeVisitor(
DexClass clazz,
BiFunction<String, String, LazyCfCode> codeLocator,
JarApplicationReader application,
- boolean useJsrInliner) {
+ boolean useJsrInliner,
+ DebugParsingOptions debugParsingOptions) {
super(InternalOptions.ASM_VERSION);
this.clazz = clazz;
this.codeLocator = codeLocator;
this.application = application;
this.usrJsrInliner = useJsrInliner;
+ this.debugParsingOptions = debugParsingOptions;
}
@Override
@@ -272,7 +289,8 @@
LazyCfCode code = codeLocator.apply(name, desc);
if (code != null) {
DexMethod method = application.getMethod(clazz.type, name, desc);
- MethodCodeVisitor methodVisitor = new MethodCodeVisitor(application, method, code);
+ MethodCodeVisitor methodVisitor =
+ new MethodCodeVisitor(application, method, code, debugParsingOptions);
if (!usrJsrInliner) {
return methodVisitor;
}
@@ -286,6 +304,7 @@
private static class MethodCodeVisitor extends MethodVisitor {
private final JarApplicationReader application;
private final DexItemFactory factory;
+ private final DebugParsingOptions debugParsingOptions;
private int maxStack;
private int maxLocals;
private List<CfInstruction> instructions;
@@ -296,8 +315,13 @@
private final LazyCfCode code;
private final DexMethod method;
- MethodCodeVisitor(JarApplicationReader application, DexMethod method, LazyCfCode code) {
+ MethodCodeVisitor(
+ JarApplicationReader application,
+ DexMethod method,
+ LazyCfCode code,
+ DebugParsingOptions debugParsingOptions) {
super(InternalOptions.ASM_VERSION);
+ this.debugParsingOptions = debugParsingOptions;
assert code != null;
this.application = application;
this.factory = application.getFactory();
@@ -895,14 +919,16 @@
@Override
public void visitLocalVariable(
String name, String desc, String signature, Label start, Label end, int index) {
- DebugLocalInfo debugLocalInfo =
- canonicalize(
- new DebugLocalInfo(
- factory.createString(name),
- factory.createType(desc),
- signature == null ? null : factory.createString(signature)));
- localVariables.add(
- new LocalVariableInfo(index, debugLocalInfo, getLabel(start), getLabel(end)));
+ if (debugParsingOptions.localInfo) {
+ DebugLocalInfo debugLocalInfo =
+ canonicalize(
+ new DebugLocalInfo(
+ factory.createString(name),
+ factory.createType(desc),
+ signature == null ? null : factory.createString(signature)));
+ localVariables.add(
+ new LocalVariableInfo(index, debugLocalInfo, getLabel(start), getLabel(end)));
+ }
}
private DebugLocalInfo canonicalize(DebugLocalInfo debugLocalInfo) {
@@ -911,7 +937,9 @@
@Override
public void visitLineNumber(int line, Label start) {
- instructions.add(new CfPosition(getLabel(start), new Position(line, null, method, null)));
+ if (debugParsingOptions.lineInfo) {
+ instructions.add(new CfPosition(getLabel(start), new Position(line, null, method, null)));
+ }
}
@Override
@@ -923,7 +951,7 @@
}
}
- private static int getParsingOptions(
+ private static DebugParsingOptions getParsingOptions(
JarApplicationReader application, boolean reachabilitySensitive) {
int parsingOptions =
application.options.testing.readInputStackMaps
@@ -931,18 +959,24 @@
: ClassReader.SKIP_FRAMES;
ProguardConfiguration configuration = application.options.getProguardConfiguration();
- if (configuration != null && !configuration.isKeepParameterNames()) {
- ProguardKeepAttributes keep =
- application.options.getProguardConfiguration().getKeepAttributes();
- if (!application.options.getProguardConfiguration().isKeepParameterNames()
- && !keep.localVariableTable
- && !keep.localVariableTypeTable
- && !keep.lineNumberTable
- && !reachabilitySensitive) {
- parsingOptions |= ClassReader.SKIP_DEBUG;
- }
+ if (configuration == null) {
+ return new DebugParsingOptions(true, true, parsingOptions);
}
- return parsingOptions;
+ ProguardKeepAttributes keep =
+ application.options.getProguardConfiguration().getKeepAttributes();
+
+ boolean localsInfo =
+ configuration.isKeepParameterNames()
+ || keep.localVariableTable
+ || keep.localVariableTypeTable
+ || reachabilitySensitive;
+ boolean lineInfo = keep.lineNumberTable;
+
+ if (!localsInfo && !lineInfo) {
+ parsingOptions |= ClassReader.SKIP_DEBUG;
+ }
+
+ return new DebugParsingOptions(lineInfo, localsInfo, parsingOptions);
}
@Override
diff --git a/src/test/java/com/android/tools/r8/regress/b150400371/DebuginfoForInlineFrameRegressionTest.java b/src/test/java/com/android/tools/r8/regress/b150400371/DebuginfoForInlineFrameRegressionTest.java
new file mode 100644
index 0000000..68c1d36
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/regress/b150400371/DebuginfoForInlineFrameRegressionTest.java
@@ -0,0 +1,77 @@
+// Copyright (c) 2020, 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.regress.b150400371;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import it.unimi.dsi.fastutil.ints.IntArraySet;
+import it.unimi.dsi.fastutil.ints.IntSet;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class DebuginfoForInlineFrameRegressionTest extends TestBase {
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withDexRuntime(Version.DEFAULT).withAllApiLevels().build();
+ }
+
+ public DebuginfoForInlineFrameRegressionTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test
+ public void testNoLinesForNonInline() throws Exception {
+ testForR8(parameters.getBackend())
+ .addInnerClasses(DebuginfoForInlineFrameRegressionTest.class)
+ .addKeepMainRule(InlineInto.class)
+ .addKeepRules("-keepparameternames")
+ .setMinApi(parameters.getApiLevel())
+ .run(parameters.getRuntime(), InlineInto.class)
+ .assertSuccessWithOutputLines("42foo")
+ .inspect(
+ (inspector) -> {
+ MethodSubject main =
+ inspector.method(InlineInto.class.getDeclaredMethod("main", String[].class));
+ IntSet lines = new IntArraySet(main.getLineNumberTable().getLines());
+ assertEquals(2, lines.size());
+ });
+ }
+
+ public static class InlineInto {
+ public static void main(String[] args) {
+ boolean late = System.currentTimeMillis() > 2;
+ String a = late ? "42" : "43";
+ String b = late ? "foo" : "bar";
+ String foo = InlineFrom.foo();
+ String result;
+ if (System.currentTimeMillis() < 2) {
+ result = a + b + foo + " that will never happen";
+ } else {
+ result = a + b;
+ }
+ System.out.println(late ? result : "never");
+ if (!late) {
+ System.out.println(late ? result : "never");
+ System.out.println(late ? result : "never");
+ }
+ }
+ }
+
+ public static class InlineFrom {
+ public static String foo() {
+ return "bar" + System.currentTimeMillis();
+ }
+ }
+}