Revert "Represent all original method information in positions"
This reverts commit bfdcaaa146ab54e8e33fabc4e1dcdae7d75fee5d.
Reason for revert: fails to build r8lib
Bug: b/261971803
Change-Id: I7db75031616c0009707ac939b8ca439fd2ffc799
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index 9964d6e..79623e1 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -17,8 +17,10 @@
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppServices;
import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
@@ -26,6 +28,7 @@
import com.android.tools.r8.graph.GenericSignatureContextBuilder;
import com.android.tools.r8.graph.GenericSignatureCorrectnessHelper;
import com.android.tools.r8.graph.ProgramDefinition;
+import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.PrunedItems;
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.graph.analysis.ClassInitializerAssertionEnablingAnalysis;
@@ -777,6 +780,8 @@
}
appView.appInfo().notifyMinifierFinished();
+ assert verifyMovedMethodsHaveOriginalMethodPosition(appView, getDirectApp(appView));
+
// If a method filter is present don't produce output since the application is likely partial.
if (options.hasMethodsFilter()) {
System.out.println("Finished compilation with method filter: ");
@@ -836,8 +841,6 @@
options.androidResourceProvider, options.androidResourceConsumer, appView.reporter());
}
- assert appView.verifyMovedMethodsHaveOriginalMethodPosition();
-
// Generate the resulting application resources.
writeApplication(appView, inputApp, executorService);
@@ -943,6 +946,57 @@
executorService);
}
+ @SuppressWarnings("ReferenceEquality")
+ private static boolean verifyMovedMethodsHaveOriginalMethodPosition(
+ AppView<?> appView, DirectMappedDexApplication application) {
+ application
+ .classesWithDeterministicOrder()
+ .forEach(
+ clazz ->
+ clazz.forEachProgramMethod(
+ method -> {
+ DexMethod originalMethod =
+ appView.graphLens().getOriginalMethodSignature(method.getReference());
+ if (originalMethod != method.getReference()) {
+ DexEncodedMethod definition = method.getDefinition();
+ Code code = definition.getCode();
+ if (code == null) {
+ return;
+ }
+ if (code.isCfCode() || code.isDexCode()) {
+ assert verifyOriginalMethodInPosition(code, originalMethod, method);
+ } else {
+ assert code.isDefaultInstanceInitializerCode() || code.isThrowNullCode();
+ }
+ }
+ }));
+ return true;
+ }
+
+ @SuppressWarnings({"ComplexBooleanConstant", "ReferenceEquality"})
+ private static boolean verifyOriginalMethodInPosition(
+ Code code, DexMethod originalMethod, ProgramMethod context) {
+ code.forEachPosition(
+ originalMethod,
+ position -> {
+ if (position.isOutlineCaller()) {
+ // Check the outlined positions for the original method
+ position
+ .getOutlinePositions()
+ .forEach(
+ (ignored, outlinePosition) -> {
+ assert outlinePosition.hasMethodInChain(originalMethod);
+ });
+ } else if (context.getDefinition().isD8R8Synthesized()) {
+ // TODO(b/261971803): Enable assert.
+ assert true || position.hasMethodInChain(originalMethod);
+ } else {
+ assert position.getOutermostCaller().getMethod() == originalMethod;
+ }
+ });
+ return true;
+ }
+
private AppView<AppInfoWithLiveness> runEnqueuer(
AnnotationRemover.Builder annotationRemoverBuilder,
ExecutorService executorService,
diff --git a/src/main/java/com/android/tools/r8/graph/AppView.java b/src/main/java/com/android/tools/r8/graph/AppView.java
index 7c724df..a5fe760 100644
--- a/src/main/java/com/android/tools/r8/graph/AppView.java
+++ b/src/main/java/com/android/tools/r8/graph/AppView.java
@@ -975,7 +975,6 @@
throws ExecutionException {
rewriteWithLensAndApplication(
lens, application, executorService, timing, withClassHierarchy(), lens.getPrevious());
- assert verifyMovedMethodsHaveOriginalMethodPosition();
}
private static void rewriteWithLensAndApplication(
@@ -1284,38 +1283,4 @@
public String getPrunedClassSourceFileInfo(DexType dexType) {
return sourceFileForPrunedTypes.get(dexType);
}
-
- public boolean verifyMovedMethodsHaveOriginalMethodPosition() {
- DirectMappedDexApplication application = app().asDirect();
- application
- .classesWithDeterministicOrder()
- .forEach(
- clazz ->
- clazz.forEachProgramMethod(
- method -> {
- DexEncodedMethod definition = method.getDefinition();
- Code code = definition.getCode();
- if (code == null) {
- return;
- }
- if (code.isCfCode() || code.isDexCode() || code.isLirCode()) {
- assert verifyOriginalMethodInPosition(code, method);
- } else {
- assert code.isDefaultInstanceInitializerCode() || code.isThrowNullCode();
- }
- }));
- return true;
- }
-
- private static boolean verifyOriginalMethodInPosition(Code code, ProgramMethod context) {
- DexMethod thisMethod = context.getReference();
- code.forEachPosition(
- context.getReference(),
- context.getDefinition().isD8R8Synthesized(),
- position -> {
- DexMethod outerCaller = position.getOutermostCaller().getMethod();
- assert thisMethod.isIdenticalTo(outerCaller);
- });
- return true;
- }
}
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 bc71dd6..b636a5c 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -684,6 +684,7 @@
this,
localVariables,
method,
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
callerPosition,
origin,
appView);
@@ -892,17 +893,8 @@
@Override
public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- Position callerPosition =
- SyntheticPosition.builder()
- .setLine(0)
- .setMethod(caller)
- .setIsD8R8Synthesized(isCallerD8R8Synthesized)
- .build();
+ DexMethod caller, DexMethod callee, DexItemFactory factory, boolean isCalleeD8R8Synthesized) {
+ Position callerPosition = SyntheticPosition.builder().setLine(0).setMethod(caller).build();
List<CfInstruction> newInstructions = new ArrayList<>(instructions.size() + 2);
CfLabel firstLabel;
if (instructions.get(0).isLabel()) {
@@ -976,8 +968,7 @@
}
@Override
- public void forEachPosition(
- DexMethod method, boolean isD8R8Synthesized, Consumer<Position> positionConsumer) {
+ public void forEachPosition(DexMethod method, Consumer<Position> positionConsumer) {
for (CfInstruction instruction : getInstructions()) {
if (instruction.isPosition()) {
positionConsumer.accept(instruction.asPosition().getPosition());
diff --git a/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java b/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
index 0670aeb..59788bc 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCodeStackMapValidatingException.java
@@ -16,7 +16,10 @@
if (appView.enableWholeProgramOptimizations()) {
sb.append(" In later version of R8, the method may be assumed not reachable.");
}
- return new CfCodeDiagnostics(method.getOrigin(), method.getReference(), sb.toString());
+ return new CfCodeDiagnostics(
+ method.getOrigin(),
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
+ sb.toString());
}
public static CfCodeDiagnostics multipleFramesForLabel(ProgramMethod method, AppView<?> appView) {
@@ -24,7 +27,10 @@
if (appView.enableWholeProgramOptimizations()) {
sb.append(" In later version of R8, the method may be assumed not reachable.");
}
- return new CfCodeDiagnostics(method.getOrigin(), method.getReference(), sb.toString());
+ return new CfCodeDiagnostics(
+ method.getOrigin(),
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
+ sb.toString());
}
public static CfCodeDiagnostics noFramesForMethodWithJumps(
@@ -34,7 +40,10 @@
if (appView.enableWholeProgramOptimizations()) {
sb.append(" In later version of R8, the method may be assumed not reachable.");
}
- return new CfCodeDiagnostics(method.getOrigin(), method.getReference(), sb.toString());
+ return new CfCodeDiagnostics(
+ method.getOrigin(),
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
+ sb.toString());
}
public static CfCodeDiagnostics invalidTryCatchRange(
@@ -48,7 +57,10 @@
if (appView.enableWholeProgramOptimizations()) {
sb.append(" In later version of R8, the method may be assumed not reachable.");
}
- return new CfCodeDiagnostics(method.getOrigin(), method.getReference(), sb.toString());
+ return new CfCodeDiagnostics(
+ method.getOrigin(),
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
+ sb.toString());
}
public static CfCodeDiagnostics invalidStackMapForInstruction(
@@ -68,6 +80,9 @@
if (appView.enableWholeProgramOptimizations()) {
sb.append(" In later version of R8, the method may be assumed not reachable.");
}
- return new CfCodeDiagnostics(method.getOrigin(), method.getReference(), sb.toString());
+ return new CfCodeDiagnostics(
+ method.getOrigin(),
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
+ sb.toString());
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/Code.java b/src/main/java/com/android/tools/r8/graph/Code.java
index 36d8464..566f79e 100644
--- a/src/main/java/com/android/tools/r8/graph/Code.java
+++ b/src/main/java/com/android/tools/r8/graph/Code.java
@@ -191,53 +191,55 @@
return true;
}
+ public Code getCodeAsInlining(DexMethod caller, DexEncodedMethod callee, DexItemFactory factory) {
+ return getCodeAsInlining(caller, callee.getReference(), factory, callee.isD8R8Synthesized());
+ }
+
public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
+ DexMethod caller, DexMethod callee, DexItemFactory factory, boolean isCalleeD8R8Synthesized) {
throw new Unreachable();
}
public static Position newInlineePosition(
- Position callerPosition, Position calleePosition, boolean isCalleeD8R8Synthesized) {
- Position outermostCallee = calleePosition.getOutermostCaller();
- // If the callee is not synthetic, then just append the frame.
- assert outermostCallee.isD8R8Synthesized() == isCalleeD8R8Synthesized;
+ Position callerPosition, Position oldPosition, boolean isCalleeD8R8Synthesized) {
+ Position outermostCaller = oldPosition.getOutermostCaller();
if (!isCalleeD8R8Synthesized) {
- assert !outermostCallee.isOutline();
- return calleePosition.withOutermostCallerPosition(callerPosition);
+ return removeSameMethodAndLineZero(oldPosition, callerPosition);
}
// We can replace the position since the callee was synthesized by the compiler, however, if
// the position carries special information we need to copy it.
- if (!outermostCallee.isOutline() && !outermostCallee.isRemoveInnerFramesIfThrowingNpe()) {
- return calleePosition.replacePosition(outermostCallee, callerPosition);
+ if (!outermostCaller.isOutline() && !outermostCaller.isRemoveInnerFramesIfThrowingNpe()) {
+ return oldPosition.replacePosition(outermostCaller, callerPosition);
}
-
assert !callerPosition.isOutline();
- assert !callerPosition.hasCallerPosition();
- // Copy the callee frame to ensure transfer of the outline key if present.
- PositionBuilder<?, ?> newCallerBuilder =
- outermostCallee.builderWithCopy().setMethod(callerPosition.getMethod());
- // If the callee is an outline, the line must be that of the outline to maintain the positions.
- if (outermostCallee.isOutline()) {
- // This does not implement inlining an outline. The cases this hits should always be a full
- // "move as inlining" to be correct.
- assert callerPosition.isD8R8Synthesized();
- assert callerPosition.getLine() == 0;
- } else {
- newCallerBuilder.setLine(outermostCallee.getLine());
- }
- // Transfer other info from the caller.
+ PositionBuilder<?, ?> positionBuilder =
+ outermostCaller
+ .builderWithCopy()
+ .setMethod(callerPosition.getMethod())
+ .setLine(callerPosition.getLine());
if (callerPosition.isRemoveInnerFramesIfThrowingNpe()) {
- newCallerBuilder.setRemoveInnerFramesIfThrowingNpe(true);
+ positionBuilder.setRemoveInnerFramesIfThrowingNpe(true);
}
- return calleePosition.replacePosition(outermostCallee, newCallerBuilder.build());
+ return oldPosition.replacePosition(outermostCaller, positionBuilder.build());
}
- public void forEachPosition(
- DexMethod method, boolean isD8R8Synthesized, Consumer<Position> positionConsumer) {
+ @Deprecated()
+ @SuppressWarnings("ReferenceEquality")
+ // TODO(b/261971803): When having complete control over the positions we should not need this.
+ private static Position removeSameMethodAndLineZero(
+ Position calleePosition, Position callerPosition) {
+ Position outermostCaller = calleePosition.getOutermostCaller();
+ if (outermostCaller.getLine() == 0) {
+ while (callerPosition != null
+ && outermostCaller.getMethod() == callerPosition.getMethod()
+ && callerPosition.getLine() == 0) {
+ callerPosition = callerPosition.getCallerPosition();
+ }
+ }
+ return calleePosition.withOutermostCallerPosition(callerPosition);
+ }
+
+ public void forEachPosition(DexMethod method, Consumer<Position> positionConsumer) {
// Intentionally empty. Override where we have fully build CF or DEX code.
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java b/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java
index 906a0be..b70ff11 100644
--- a/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DefaultInstanceInitializerCode.java
@@ -20,7 +20,6 @@
import com.android.tools.r8.graph.lens.MethodLookupResult;
import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.InvokeDirect;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SyntheticPosition;
@@ -88,19 +87,6 @@
method.setCode(get().toCfCode(method, appView.dexItemFactory(), superType), appView);
}
- @Override
- public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- // TODO(b/261971803): It is odd this code does not have an original position for the <init>.
- // See OverrideParentCollisionTest for a case hitting this inlining where callee is a
- // non-synthetic non-default <init> (it has argument String).
- return this;
- }
-
@SuppressWarnings("ReferenceEquality")
private static boolean hasDefaultInstanceInitializerCode(
ProgramMethod method, AppView<?> appView) {
@@ -158,9 +144,10 @@
AppView<?> appView,
Origin origin,
MutableMethodConversionOptions conversionOptions) {
+ DexMethod originalMethod =
+ appView.graphLens().getOriginalMethodSignature(method.getReference());
DefaultInstanceInitializerSourceCode source =
- new DefaultInstanceInitializerSourceCode(
- method.getReference(), method.getDefinition().isD8R8Synthesized());
+ new DefaultInstanceInitializerSourceCode(originalMethod);
return IRBuilder.create(method, appView, source, origin).build(method, conversionOptions);
}
@@ -174,9 +161,10 @@
Position callerPosition,
Origin origin,
RewrittenPrototypeDescription protoChanges) {
+ DexMethod originalMethod =
+ appView.graphLens().getOriginalMethodSignature(method.getReference());
DefaultInstanceInitializerSourceCode source =
- new DefaultInstanceInitializerSourceCode(
- method.getReference(), method.getDefinition().isD8R8Synthesized(), callerPosition);
+ new DefaultInstanceInitializerSourceCode(originalMethod, callerPosition);
return IRBuilder.createForInlining(
method, appView, codeLens, source, origin, valueNumberGenerator, protoChanges)
.build(context, MethodConversionOptions.nonConverting());
@@ -422,33 +410,25 @@
static class DefaultInstanceInitializerSourceCode extends SyntheticStraightLineSourceCode {
- DefaultInstanceInitializerSourceCode(DexMethod method, boolean isD8R8Synthesized) {
- this(method, isD8R8Synthesized, null);
+ DefaultInstanceInitializerSourceCode(DexMethod method) {
+ this(method, null);
}
- DefaultInstanceInitializerSourceCode(
- DexMethod method, boolean isD8R8Synthesized, Position callerPosition) {
- super(getInstructionBuilders(), getPosition(method, isD8R8Synthesized, callerPosition));
- }
-
- private static Position getPosition(
- DexMethod method, boolean isD8R8Synthesized, Position callerPosition) {
- SyntheticPosition calleePosition =
+ DefaultInstanceInitializerSourceCode(DexMethod method, Position callerPosition) {
+ super(
+ getInstructionBuilders(),
SyntheticPosition.builder()
.setLine(0)
.setMethod(method)
- .setIsD8R8Synthesized(isD8R8Synthesized)
- .build();
- return callerPosition == null
- ? calleePosition
- : Code.newInlineePosition(callerPosition, calleePosition, isD8R8Synthesized);
+ .setCallerPosition(callerPosition)
+ .build());
}
private static List<Consumer<IRBuilder>> getInstructionBuilders() {
return ImmutableList.of(
builder ->
builder.add(
- InvokeDirect.builder()
+ com.android.tools.r8.ir.code.InvokeDirect.builder()
.setMethod(
getParentConstructor(
builder.getProgramMethod(), builder.dexItemFactory()))
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 e800b21..f3fd961 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -351,11 +351,7 @@
@Override
public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
+ DexMethod caller, DexMethod callee, DexItemFactory factory, boolean isCalleeD8R8Synthesized) {
return new DexCode(
registerSize,
incomingRegisterSize,
@@ -400,8 +396,7 @@
// => Insert a default event and potentially advance line.
// 4) There is no SET_POSITION_FRAME and no default event setting a position for PC 0..
// => Insert a SET_POSITION_FRAME and a default event and potentially advance line.
- PositionInfo positionInfo =
- computePreamblePosition(callee, isCalleeD8R8Synthesized, eventBasedInfo);
+ PositionInfo positionInfo = computePreamblePosition(callee, eventBasedInfo);
DexDebugEvent[] oldEvents = eventBasedInfo.events;
boolean adjustStartPosition =
!positionInfo.hasLinePositionAtPcZero() && debugInfo.getStartLine() > 0;
@@ -542,6 +537,7 @@
new DexSourceCode(
this,
method,
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
null,
appView.dexItemFactory());
return IRBuilder.create(method, appView, source, origin).build(method, conversionOptions);
@@ -562,6 +558,7 @@
new DexSourceCode(
this,
method,
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
callerPosition,
appView.dexItemFactory());
return IRBuilder.createForInlining(
@@ -878,8 +875,7 @@
}
@Override
- public void forEachPosition(
- DexMethod method, boolean isD8R8Synthesized, Consumer<Position> positionConsumer) {
+ public void forEachPosition(DexMethod method, Consumer<Position> positionConsumer) {
if (getDebugInfo() == null || getDebugInfo().isPcBasedInfo()) {
return;
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java b/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java
index e5ca60d..e323ab8 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java
@@ -57,9 +57,9 @@
private List<DexDebugEntry> entries = new ArrayList<>();
private final DexDebugPositionState positionState;
- public DexDebugEntryBuilder(DexMethod method, boolean isD8R8Synthesized, int startLine) {
+ public DexDebugEntryBuilder(int startLine, DexMethod method) {
assert method != null;
- positionState = new DexDebugPositionState(startLine, method, isD8R8Synthesized);
+ positionState = new DexDebugPositionState(startLine, method);
}
public DexDebugEntryBuilder(DexEncodedMethod method, DexItemFactory factory) {
@@ -68,9 +68,7 @@
EventBasedDebugInfo info = code.getDebugInfo().asEventBasedInfo();
// Only event based debug info supports conversion to entries.
assert info != null;
- positionState =
- new DexDebugPositionState(
- info.startLine, method.getReference(), method.isD8R8Synthesized());
+ positionState = new DexDebugPositionState(info.startLine, method.getReference());
int argumentRegister = code.registerSize - code.incomingRegisterSize;
if (!method.accessFlags.isStatic()) {
DexString name = factory.thisName;
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java b/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
index 557bb44..b77b311 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
@@ -202,12 +202,10 @@
return;
}
startLine = position.getLine();
- Position outermostCaller = position.getOutermostCaller();
emittedPosition =
SourcePosition.builder()
.setLine(position.getLine())
- .setMethod(outermostCaller.getMethod())
- .setIsD8R8Synthesized(outermostCaller.isD8R8Synthesized())
+ .setMethod(position.getOutermostCaller().getMethod())
.build();
}
assert emittedPc != pc;
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java b/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java
index 3707fdf..1a0023a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugInfo.java
@@ -239,8 +239,8 @@
return parameters.length;
}
- public List<DexDebugEntry> computeEntries(DexMethod method, boolean isD8R8Synthesized) {
- DexDebugEntryBuilder builder = new DexDebugEntryBuilder(method, isD8R8Synthesized, startLine);
+ public List<DexDebugEntry> computeEntries(DexMethod method) {
+ DexDebugEntryBuilder builder = new DexDebugEntryBuilder(startLine, method);
for (DexDebugEvent event : events) {
event.accept(builder);
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java b/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java
index 26f1577..96eb206 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java
@@ -27,13 +27,11 @@
private int currentPc = 0;
private int currentLine;
protected DexMethod currentMethod;
- protected boolean isCurrentMethodD8R8Synthesized;
protected Position currentPosition;
- public DexDebugPositionState(int startLine, DexMethod method, boolean isD8R8Synthesized) {
+ public DexDebugPositionState(int startLine, DexMethod method) {
currentLine = startLine;
currentMethod = method;
- isCurrentMethodD8R8Synthesized = isD8R8Synthesized;
}
@Override
@@ -52,7 +50,6 @@
assert setPositionFrame.getPosition() != null;
Position position = setPositionFrame.getPosition();
currentMethod = position.getMethod();
- isCurrentMethodD8R8Synthesized = position.isD8R8Synthesized();
currentPosition = position;
}
@@ -106,7 +103,6 @@
return (getCurrentLine() > 0 ? SourcePosition.builder() : SyntheticPosition.builder())
.setLine(getCurrentLine())
.setMethod(currentMethod)
- .setIsD8R8Synthesized(isCurrentMethodD8R8Synthesized)
.build();
} else {
return currentPosition.builderWithCopy().setLine(getCurrentLine()).build();
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index c1f8ac7..87740a8 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -213,12 +213,11 @@
/**
* Flags this method as no longer being obsolete.
*
- * <p>Example use case: The vertical class merger optimistically merges two classes before it is
+ * Example use case: The vertical class merger optimistically merges two classes before it is
* guaranteed that the two classes can be merged. In this process, methods are moved from the
- * source class to the target class using {@link #toTypeSubstitutedMethodAsInlining(DexMethod,
- * DexItemFactory)}, which causes the original methods of the source class to become obsolete. If
- * vertical class merging is aborted, the original methods of the source class needs to be marked
- * as not being obsolete.
+ * source class to the target class using {@link #toTypeSubstitutedMethod(DexMethod)}, which
+ * causes the original methods of the source class to become obsolete. If vertical class merging
+ * is aborted, the original methods of the source class needs to be marked as not being obsolete.
*/
public void unsetObsolete() {
obsolete = false;
@@ -1125,6 +1124,16 @@
return new CfCode(getReference().holder, 3, locals, instructionBuilder.build());
}
+ public DexEncodedMethod toTypeSubstitutedMethod(DexMethod method) {
+ checkIfObsolete();
+ return toTypeSubstitutedMethodHelper(method, isD8R8Synthesized(), null);
+ }
+
+ public DexEncodedMethod toTypeSubstitutedMethod(DexMethod method, Consumer<Builder> consumer) {
+ checkIfObsolete();
+ return toTypeSubstitutedMethodHelper(method, isD8R8Synthesized(), consumer);
+ }
+
public DexEncodedMethod toTypeSubstitutedMethodAsInlining(
DexMethod method, DexItemFactory factory) {
checkIfObsolete();
@@ -1133,20 +1142,12 @@
public DexEncodedMethod toTypeSubstitutedMethodAsInlining(
DexMethod method, DexItemFactory factory, Consumer<Builder> consumer) {
- boolean isCallerD8R8Synthesized = true;
return toTypeSubstitutedMethodHelper(
method,
- isCallerD8R8Synthesized,
+ true,
builder -> {
if (code != null) {
- builder.setCode(
- getCode()
- .getCodeAsInlining(
- method,
- isCallerD8R8Synthesized,
- getReference(),
- isD8R8Synthesized(),
- factory));
+ builder.setCode(getCode().getCodeAsInlining(method, this, factory));
}
if (consumer != null) {
consumer.accept(builder);
@@ -1180,26 +1181,24 @@
return builder.build();
}
- public ProgramMethod toPrivateSyntheticMethod(
- DexProgramClass holder, DexMethod method, DexItemFactory factory) {
+ @SuppressWarnings("ReferenceEquality")
+ public ProgramMethod toPrivateSyntheticMethod(DexProgramClass holder, DexMethod method) {
assert !isStatic();
assert !isPrivate();
- assert getHolderType().isIdenticalTo(method.getHolderType());
+ assert getHolderType() == method.getHolderType();
checkIfObsolete();
- DexEncodedMethod newMethod =
- toTypeSubstitutedMethodAsInlining(
- method,
- factory,
- builder -> {
- builder.modifyAccessFlags(
- accessFlags -> {
- accessFlags.setSynthetic();
- accessFlags.unsetProtected();
- accessFlags.unsetPublic();
- accessFlags.setPrivate();
- });
- });
- return new ProgramMethod(holder, newMethod);
+ return new ProgramMethod(
+ holder,
+ syntheticBuilder(this)
+ .setMethod(method)
+ .modifyAccessFlags(
+ accessFlags -> {
+ accessFlags.setSynthetic();
+ accessFlags.unsetProtected();
+ accessFlags.unsetPublic();
+ accessFlags.setPrivate();
+ })
+ .build());
}
public DexEncodedMethod toForwardingMethod(DexClass newHolder, AppView<?> definitions) {
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 c7fe5c9..5676a96 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -181,15 +181,8 @@
}
@Override
- public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- return asCfCode()
- .getCodeAsInlining(
- caller, isCallerD8R8Synthesized, callee, isCalleeD8R8Synthesized, factory);
+ public Code getCodeAsInlining(DexMethod caller, DexEncodedMethod callee, DexItemFactory factory) {
+ return asCfCode().getCodeAsInlining(caller, callee, factory);
}
public static class DebugParsingOptions {
diff --git a/src/main/java/com/android/tools/r8/graph/ThrowNullCode.java b/src/main/java/com/android/tools/r8/graph/ThrowNullCode.java
index a58f744..735be28 100644
--- a/src/main/java/com/android/tools/r8/graph/ThrowNullCode.java
+++ b/src/main/java/com/android/tools/r8/graph/ThrowNullCode.java
@@ -55,18 +55,6 @@
}
@Override
- public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- // We don't maintain a position on the throwing stub. We may want to reconsider this as it
- // would allow retracing to recover inlinings of this stub.
- return this;
- }
-
- @Override
public IRCode buildIR(
ProgramMethod method,
AppView<?> appView,
@@ -143,7 +131,7 @@
@Override
public TryHandler[] getHandlers() {
- return TryHandler.EMPTY_ARRAY;
+ return new TryHandler[0];
}
@Override
@@ -176,7 +164,7 @@
@Override
public Try[] getTries() {
- return Try.EMPTY_ARRAY;
+ return new Try[0];
}
@Override
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 4810b23..908749c 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
@@ -258,12 +258,12 @@
}
/** Fixup a method definition. */
+ @SuppressWarnings("ReferenceEquality")
public DexEncodedMethod fixupMethod(DexEncodedMethod method) {
DexMethod methodReference = method.getReference();
DexMethod newMethodReference = fixupMethodReference(methodReference);
- if (!methodReference.isIdenticalTo(newMethodReference)) {
- return recordMethodChange(
- method, method.toTypeSubstitutedMethodAsInlining(newMethodReference, dexItemFactory));
+ if (newMethodReference != methodReference) {
+ return recordMethodChange(method, method.toTypeSubstitutedMethod(newMethodReference));
}
return method;
}
diff --git a/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java b/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
index ef55a1f..4d339e8 100644
--- a/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
+++ b/src/main/java/com/android/tools/r8/graph/lens/GraphLens.java
@@ -678,8 +678,16 @@
+ "` back to original program";
}
for (DexEncodedMethod method : clazz.methods()) {
- // Methods synthesized by D8/R8 are not mapped, but all non-synthesized must be originals.
- assert method.isD8R8Synthesized() || originalMethods.contains(method.getReference());
+ if (method.isD8R8Synthesized()) {
+ // Methods synthesized by D8/R8 may not be mapped.
+ continue;
+ }
+ DexMethod originalMethod = getOriginalMethodSignature(method.getReference());
+ assert originalMethods.contains(originalMethod)
+ : "Method could not be mapped back: "
+ + method.toSourceString()
+ + ", originalMethod: "
+ + originalMethod.toSourceString();
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
index d6b92e0..06117ec 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
@@ -142,7 +142,7 @@
DexEncodedMethod.syntheticBuilder()
.setMethod(newMethodReference)
.setAccessFlags(MethodAccessFlags.createForClassInitializer())
- .setCode(classInitializerMerger.getCode(newMethodReference))
+ .setCode(classInitializerMerger.getCode(syntheticMethodReference))
.setClassFileVersion(classInitializerMerger.getCfVersion())
.setApiLevelForDefinition(apiReferenceLevel)
.setApiLevelForCode(apiReferenceLevel)
@@ -176,7 +176,7 @@
}
classMethodsBuilder.addDirectMethod(
newMethod != method.getReference()
- ? definition.toTypeSubstitutedMethodAsInlining(newMethod, dexItemFactory)
+ ? definition.toTypeSubstitutedMethod(newMethod)
: method.getDefinition());
if (definition.getReference() != newMethod) {
lensBuilder.moveMethod(definition.getReference(), newMethod);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorEntryPoint.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorEntryPoint.java
index 76c4d8a..d4cb598 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorEntryPoint.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorEntryPoint.java
@@ -41,8 +41,9 @@
Int2ReferenceSortedMap<DexMethod> typeConstructors,
DexMethod newConstructor,
DexField classIdField,
- Position callerPosition) {
- super(newConstructor.holder, newConstructor, callerPosition);
+ Position callerPosition,
+ DexMethod originalMethod) {
+ super(newConstructor.holder, newConstructor, callerPosition, originalMethod);
this.typeConstructors = typeConstructors;
this.classIdField = classIdField;
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteHorizontalClassMergerCode.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteHorizontalClassMergerCode.java
index 7e37921..abb1fbf 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteHorizontalClassMergerCode.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteHorizontalClassMergerCode.java
@@ -11,8 +11,6 @@
import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.code.IRCode;
@@ -37,18 +35,6 @@
ProgramMethod method,
HorizontalClassMergerGraphLens lens);
- @Override
- public final Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- // This code object is synthesized so "inlining" just "strips" the callee position.
- assert isCalleeD8R8Synthesized;
- return this;
- }
-
// Implement Code.
@Override
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java
index 837157e..a77873f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/IncompleteMergedInstanceInitializerCode.java
@@ -48,6 +48,7 @@
private final DexField classIdField;
private final int extraNulls;
private final DexMethod originalMethodReference;
+ private final DexMethod syntheticMethodReference;
private final Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPre;
private final Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPost;
@@ -59,6 +60,7 @@
DexField classIdField,
int extraNulls,
DexMethod originalMethodReference,
+ DexMethod syntheticMethodReference,
Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPre,
Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPost,
DexMethod parentConstructor,
@@ -66,6 +68,7 @@
this.classIdField = classIdField;
this.extraNulls = extraNulls;
this.originalMethodReference = originalMethodReference;
+ this.syntheticMethodReference = syntheticMethodReference;
this.instanceFieldAssignmentsPre = instanceFieldAssignmentsPre;
this.instanceFieldAssignmentsPost = instanceFieldAssignmentsPost;
this.parentConstructor = parentConstructor;
@@ -87,13 +90,16 @@
IntBox maxStack = new IntBox();
ImmutableList.Builder<CfInstruction> instructionBuilder = ImmutableList.builder();
- Position preamblePosition =
+ // Set position.
+ Position callerPosition =
+ SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
+ Position calleePosition =
SyntheticPosition.builder()
.setLine(0)
- .setMethod(method.getReference())
- .setIsD8R8Synthesized(method.getDefinition().isD8R8Synthesized())
+ .setMethod(originalMethodReference)
+ .setCallerPosition(callerPosition)
.build();
- CfPosition position = new CfPosition(new CfLabel(), preamblePosition);
+ CfPosition position = new CfPosition(new CfLabel(), calleePosition);
instructionBuilder.add(position);
instructionBuilder.add(position.getLabel());
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java
index 2360c36..b2421bb 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java
@@ -71,9 +71,12 @@
* Transform this description into actual CF code.
*
* @param originalMethodReference the original reference of the representative method
+ * @param syntheticMethodReference the original, synthetic reference of the new method reference
+ * ($r8$init$synthetic)
*/
public IncompleteMergedInstanceInitializerCode createCfCode(
DexMethod originalMethodReference,
+ DexMethod syntheticMethodReference,
MergeGroup group,
boolean hasClassId,
int extraNulls) {
@@ -81,6 +84,7 @@
hasClassId ? group.getClassIdField() : null,
extraNulls,
originalMethodReference,
+ syntheticMethodReference,
instanceFieldAssignmentsPre,
instanceFieldAssignmentsPost,
parentConstructor,
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
index 22099a3..91bfef0 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerMerger.java
@@ -253,9 +253,7 @@
classMethodsBuilder::isFresh);
DexEncodedMethod encodedMethod =
- instanceInitializer
- .getDefinition()
- .toTypeSubstitutedMethodAsInlining(method, dexItemFactory);
+ instanceInitializer.getDefinition().toTypeSubstitutedMethod(method);
encodedMethod.getMutableOptimizationInfo().markForceInline();
encodedMethod.getAccessFlags().unsetConstructor();
encodedMethod.getAccessFlags().unsetPublic();
@@ -272,19 +270,26 @@
}
private Code getNewCode(
+ DexMethod newMethodReference,
+ DexMethod syntheticMethodReference,
boolean needsClassId,
int extraNulls) {
if (hasInstanceInitializerDescription()) {
return instanceInitializerDescription.createCfCode(
getOriginalMethodReference(),
+ syntheticMethodReference,
group,
needsClassId,
extraNulls);
}
- assert useSyntheticMethod();
+ if (!useSyntheticMethod()) {
+ return getRepresentative().getDefinition().getCode();
+ }
return new ConstructorEntryPointSynthesizedCode(
createClassIdToInstanceInitializerMap(),
- group.hasClassIdField() ? group.getClassIdField() : null);
+ newMethodReference,
+ group.hasClassIdField() ? group.getClassIdField() : null,
+ syntheticMethodReference);
}
private boolean isSingleton() {
@@ -376,23 +381,24 @@
}
DexEncodedMethod representativeMethod = representative.getDefinition();
-
- DexEncodedMethod newInstanceInitializer;
- if (!hasInstanceInitializerDescription() && !useSyntheticMethod()) {
- newInstanceInitializer =
- representativeMethod.toTypeSubstitutedMethodAsInlining(
- newMethodReference, dexItemFactory);
- } else {
- newInstanceInitializer =
- DexEncodedMethod.syntheticBuilder()
- .setMethod(newMethodReference)
- .setAccessFlags(getNewAccessFlags())
- .setCode(getNewCode(needsClassId, extraUnusedNullParameters.size()))
- .setClassFileVersion(getNewClassFileVersion())
- .setApiLevelForDefinition(representativeMethod.getApiLevelForDefinition())
- .setApiLevelForCode(representativeMethod.getApiLevelForCode())
- .build();
- }
+ boolean useSynthethicBuilder = useSyntheticMethod() || representativeMethod.isD8R8Synthesized();
+ DexEncodedMethod newInstanceInitializer =
+ (useSynthethicBuilder ? DexEncodedMethod.syntheticBuilder() : DexEncodedMethod.builder())
+ .setMethod(newMethodReference)
+ .setAccessFlags(
+ useSynthethicBuilder
+ ? getNewAccessFlags()
+ : representative.getAccessFlags().withPublic())
+ .setCode(
+ getNewCode(
+ newMethodReference,
+ syntheticMethodReference,
+ needsClassId,
+ extraUnusedNullParameters.size()))
+ .setClassFileVersion(getNewClassFileVersion())
+ .setApiLevelForDefinition(representativeMethod.getApiLevelForDefinition())
+ .setApiLevelForCode(representativeMethod.getApiLevelForCode())
+ .build();
classMethodsBuilder.addDirectMethod(newInstanceInitializer);
if (mode.isFinal()) {
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
index 538c0d3..8cca85f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/TreeFixer.java
@@ -237,7 +237,7 @@
newMethodSignature.withHolder(originalMethodReference, dexItemFactory);
lensBuilder.fixupMethod(originalMethodReference, newMethodReference);
return newMethodReference != originalMethodReference
- ? method.toTypeSubstitutedMethodAsInlining(newMethodReference, dexItemFactory)
+ ? method.toTypeSubstitutedMethod(newMethodReference)
: method;
}
@@ -278,8 +278,7 @@
lensBuilder.fixupMethod(originalMethodReference, newMethodReference);
- DexEncodedMethod newMethod =
- method.toTypeSubstitutedMethodAsInlining(newMethodReference, dexItemFactory);
+ DexEncodedMethod newMethod = method.toTypeSubstitutedMethod(newMethodReference);
if (newMethod.isNonPrivateVirtualMethod()) {
// Since we changed the return type or one of the parameters, this method cannot be a
// classpath or library method override, since we only class merge program classes.
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
index 5b1ee78..eca0a6f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
@@ -124,8 +124,7 @@
group.getTarget().getType(),
classMethodsBuilder::isFresh);
- DexEncodedMethod encodedMethod =
- oldMethod.getDefinition().toTypeSubstitutedMethodAsInlining(method, dexItemFactory);
+ DexEncodedMethod encodedMethod = oldMethod.getDefinition().toTypeSubstitutedMethod(method);
MethodAccessFlags flags = encodedMethod.getAccessFlags();
flags.unsetProtected();
flags.unsetPublic();
@@ -236,9 +235,8 @@
newMethod =
representative
.getDefinition()
- .toTypeSubstitutedMethodAsInlining(
+ .toTypeSubstitutedMethod(
newMethodReference,
- dexItemFactory,
builder -> builder.setIsLibraryMethodOverrideIfKnown(isLibraryMethodOverride));
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
index a0b8b9b..b4d26cd 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
@@ -82,7 +82,7 @@
classInitializer -> classInitializer.getDefinition().getCode().isCfCode());
return new CfCodeBuilder().build(syntheticMethodReference);
}
- return new IRProvider(classInitializers);
+ return new IRProvider(classInitializers, syntheticMethodReference);
}
public CfVersion getCfVersion() {
@@ -141,11 +141,7 @@
// Building the instructions will adjust maxStack and maxLocals. Build it here before invoking
// the CfCode constructor to ensure that the value passed in is the updated values.
Position callerPosition =
- SyntheticPosition.builder()
- .setLine(0)
- .setMethod(syntheticMethodReference)
- .setIsD8R8Synthesized(true)
- .build();
+ SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
List<CfInstruction> instructions = buildInstructions(callerPosition);
return new CfCode(
syntheticMethodReference.getHolderType(), maxStack, maxLocals, instructions);
@@ -167,15 +163,13 @@
CfLabel endLabel = new CfLabel();
boolean requiresLabel = false;
int index = 1;
- boolean calleeD8R8Synthesized = method.getDefinition().isD8R8Synthesized();
for (CfInstruction instruction : code.getInstructions()) {
if (instruction.isPosition()) {
- CfPosition calleePosition = instruction.asPosition();
+ CfPosition cfPosition = instruction.asPosition();
newInstructions.add(
new CfPosition(
- calleePosition.getLabel(),
- Code.newInlineePosition(
- callerPosition, calleePosition.getPosition(), calleeD8R8Synthesized)));
+ cfPosition.getLabel(),
+ cfPosition.getPosition().withOutermostCallerPosition(callerPosition)));
} else if (instruction.isReturn()) {
if (code.getInstructions().size() != index) {
newInstructions.add(new CfGoto(endLabel));
@@ -199,9 +193,12 @@
static class IRProvider extends Code {
private final ImmutableList<ProgramMethod> classInitializers;
+ private final DexMethod syntheticMethodReference;
- private IRProvider(ImmutableList<ProgramMethod> classInitializers) {
+ private IRProvider(
+ ImmutableList<ProgramMethod> classInitializers, DexMethod syntheticMethodReference) {
this.classInitializers = classInitializers;
+ this.syntheticMethodReference = syntheticMethodReference;
}
@Override
@@ -212,13 +209,8 @@
MutableMethodConversionOptions conversionOptions) {
assert !classInitializers.isEmpty();
- Position preamblePosition =
- SyntheticPosition.builder()
- .setLine(0)
- .setMethod(method.getReference())
- .setIsD8R8Synthesized(method.getDefinition().isD8R8Synthesized())
- .build();
-
+ Position callerPosition =
+ SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
IRMetadata metadata = new IRMetadata();
NumberGenerator blockNumberGenerator = new NumberGenerator();
NumberGenerator valueNumberGenerator = new NumberGenerator();
@@ -231,7 +223,7 @@
block.add(
InvokeStatic.builder()
.setMethod(classInitializer.getReference())
- .setPosition(preamblePosition)
+ .setPosition(callerPosition)
.build(),
metadata);
}
@@ -244,7 +236,7 @@
new IRCode(
appView.options(),
method,
- preamblePosition,
+ callerPosition,
ListUtils.newLinkedList(block),
valueNumberGenerator,
blockNumberGenerator,
@@ -274,7 +266,7 @@
appView,
appView.codeLens(),
valueNumberGenerator,
- preamblePosition,
+ callerPosition,
classInitializer.getOrigin(),
RewrittenPrototypeDescription.none());
classInitializer.getDefinition().setObsolete();
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java
index d9e08c8..60903cc 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ConstructorEntryPointSynthesizedCode.java
@@ -14,20 +14,27 @@
import java.util.function.Consumer;
public class ConstructorEntryPointSynthesizedCode extends AbstractSynthesizedCode {
+ private final DexMethod newConstructor;
+ private final DexMethod originalMethod;
private final DexField classIdField;
private final Int2ReferenceSortedMap<DexMethod> typeConstructors;
public ConstructorEntryPointSynthesizedCode(
- Int2ReferenceSortedMap<DexMethod> typeConstructors, DexField classIdField) {
+ Int2ReferenceSortedMap<DexMethod> typeConstructors,
+ DexMethod newConstructor,
+ DexField classIdField,
+ DexMethod originalMethod) {
this.typeConstructors = typeConstructors;
+ this.newConstructor = newConstructor;
this.classIdField = classIdField;
+ this.originalMethod = originalMethod;
}
@Override
public SourceCodeProvider getSourceCodeProvider() {
- return (method, callerPosition) ->
+ return (ignored, callerPosition) ->
new ConstructorEntryPoint(
- typeConstructors, method.getReference(), classIdField, callerPosition);
+ typeConstructors, newConstructor, classIdField, callerPosition, originalMethod);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java b/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java
index 89e7c36..1a07f41 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java
@@ -34,12 +34,7 @@
canonicalPositions =
new HashMap<>(1 + (callerPosition == null ? 0 : 1) + expectedPositionsCount);
if (preamblePosition == null) {
- preamblePosition =
- SyntheticPosition.builder()
- .setLine(0)
- .setMethod(method)
- .setIsD8R8Synthesized(methodIsSynthesized)
- .build();
+ preamblePosition = SyntheticPosition.builder().setLine(0).setMethod(method).build();
}
if (callerPosition != null) {
this.callerPosition = getCanonical(callerPosition);
@@ -67,18 +62,6 @@
return canonical != null ? canonical : position;
}
- public Position canonicalizePositionWithCaller(Position position) {
- if (position.isD8R8Synthesized() && callerPosition != null) {
- assert !position.hasCallerPosition();
- return getCanonical(Code.newInlineePosition(callerPosition, position, true));
- }
- return getCanonical(
- position
- .builderWithCopy()
- .setCallerPosition(canonicalizeCallerPosition(position.getCallerPosition()))
- .build());
- }
-
/**
* Append callerPosition (supplied in constructor) to the end of caller's caller chain and return
* the canonical instance.
diff --git a/src/main/java/com/android/tools/r8/ir/code/Position.java b/src/main/java/com/android/tools/r8/ir/code/Position.java
index 48432c4..187fe6a 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Position.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Position.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.code;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.ProgramMethod;
@@ -40,8 +41,6 @@
Position callerPosition,
boolean removeInnerFramesIfThrowingNpe,
boolean isD8R8Synthesized) {
- assert callerPosition == null || !isD8R8Synthesized
- : "Synthetic positions should always be outermost";
this.line = line;
this.method = method;
this.callerPosition = callerPosition;
@@ -129,20 +128,30 @@
.withBool(Position::isD8R8Synthesized);
}
+ @SuppressWarnings("ReferenceEquality")
public static Position syntheticNone() {
return SyntheticPosition.NO_POSITION_SYNTHETIC;
}
- public static Position getPositionForInlining(InvokeMethod invoke, ProgramMethod context) {
+ @SuppressWarnings("ReferenceEquality")
+ public static Position getPositionForInlining(
+ AppView<?> appView, InvokeMethod invoke, ProgramMethod context) {
Position position = invoke.getPosition();
if (position.method == null) {
assert position.isNone();
position = SourcePosition.builder().setMethod(context.getReference()).build();
}
- // If this assert is hit, then the method has changed/moved and the position info has not been
- // updated. The code changing/moving the method needs to use the "AsInlining" helpers to
- // maintain correct mapping information.
- assert context.getReference().isIdenticalTo(position.getOutermostCaller().getMethod());
+ if (context.getDefinition().isD8R8Synthesized()) {
+ // Some rewritings map a synthetic method back to an original in the program. To ensure we
+ // have correct line information we have to rewrite the positions as inline position
+ // therefore we only check if the original method is present.
+ DexMethod originalMethodSignature =
+ appView.graphLens().getOriginalMethodSignature(context.getReference());
+ assert position.hasMethodInChain(originalMethodSignature);
+ } else {
+ assert position.getOutermostCaller().method
+ == appView.graphLens().getOriginalMethodSignature(context.getReference());
+ }
return position;
}
@@ -189,6 +198,22 @@
return null;
}
+ public boolean hasPositionMatching(Predicate<Position> positionPredicate) {
+ Position lastPosition = this;
+ while (lastPosition != null) {
+ if (positionPredicate.test(lastPosition)) {
+ return true;
+ }
+ lastPosition = lastPosition.getCallerPosition();
+ }
+ return false;
+ }
+
+ @SuppressWarnings("ReferenceEquality")
+ public boolean hasMethodInChain(DexMethod method) {
+ return hasPositionMatching(position -> position.getMethod() == method);
+ }
+
public Position withOutermostCallerPosition(Position newOutermostCallerPosition) {
return builderWithCopy()
.setCallerPosition(
@@ -472,23 +497,13 @@
public static class OutlinePosition extends Position {
- // This is the method that the outline is created at. This needs to stay stable as it is used
- // to identify the mapping table between callers and this outline definition.
- private final DexMethod outlineMethodKey;
-
private OutlinePosition(
int line,
DexMethod method,
Position callerPosition,
boolean removeInnerFramesIfThrowingNpe,
- DexMethod outlineMethodKey) {
- super(line, method, callerPosition, removeInnerFramesIfThrowingNpe, true);
- this.outlineMethodKey = outlineMethodKey;
- assert outlineMethodKey != null;
- }
-
- public DexMethod getOutlineMethodKey() {
- return outlineMethodKey;
+ boolean isD8R8Synthesized) {
+ super(line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
}
@Override
@@ -503,7 +518,7 @@
@Override
public PositionBuilder<?, ?> builderWithCopy() {
- return builder(outlineMethodKey)
+ return builder()
.setLine(line)
.setMethod(method)
.setCallerPosition(callerPosition)
@@ -516,15 +531,13 @@
return Position::specifyBasePosition;
}
- public static OutlinePositionBuilder builder(DexMethod outlineMethodKey) {
- return new OutlinePositionBuilder().setOutlineMethodKey(outlineMethodKey);
+ public static OutlinePositionBuilder builder() {
+ return new OutlinePositionBuilder();
}
public static class OutlinePositionBuilder
extends PositionBuilder<OutlinePosition, OutlinePositionBuilder> {
- private DexMethod outlineMethodKey;
-
private OutlinePositionBuilder() {}
@Override
@@ -532,17 +545,10 @@
return this;
}
- // Intentionally hidden without external setter.
- private OutlinePositionBuilder setOutlineMethodKey(DexMethod outlineMethodKey) {
- this.outlineMethodKey = outlineMethodKey;
- return this;
- }
-
@Override
public OutlinePosition build() {
- assert isD8R8Synthesized;
return new OutlinePosition(
- line, method, callerPosition, removeInnerFramesIfThrowingNpe, outlineMethodKey);
+ line, method, callerPosition, removeInnerFramesIfThrowingNpe, isD8R8Synthesized);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
index de8a584..424108f 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.graph.DebugLocalInfo.PrintLevel;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.CanonicalPositions;
@@ -209,6 +210,7 @@
CfCode code,
List<CfCode.LocalVariableInfo> localVariables,
ProgramMethod method,
+ DexMethod originalMethod,
Position callerPosition,
Origin origin,
AppView<?> appView) {
@@ -232,7 +234,7 @@
new CanonicalPositions(
callerPosition,
cfPositionCount,
- method.getReference(),
+ originalMethod,
method.getDefinition().isD8R8Synthesized(),
code.getPreamblePosition());
internalOutputMode = appView.options().getInternalOutputMode();
@@ -902,6 +904,11 @@
}
public Position getCanonicalPosition(Position position) {
- return canonicalPositions.canonicalizePositionWithCaller(position);
+ return canonicalPositions.getCanonical(
+ position
+ .builderWithCopy()
+ .setCallerPosition(
+ canonicalPositions.canonicalizeCallerPosition(position.getCallerPosition()))
+ .build());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
index b830c14..2edb76d 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
@@ -74,28 +74,29 @@
private final CanonicalPositions canonicalPositions;
private List<DexDebugEntry> debugEntries = null;
+ // In case of inlining the position of the invoke in the caller.
+ private final DexMethod originalMethod;
public DexSourceCode(
DexCode code,
ProgramMethod method,
+ DexMethod originalMethod,
Position callerPosition,
DexItemFactory factory) {
this.code = code;
this.method = method;
- DexMethod reference = method.getReference();
- boolean d8R8Synthesized = method.getDefinition().isD8R8Synthesized();
+ this.originalMethod = originalMethod;
EventBasedDebugInfo info = DexDebugInfo.convertToEventBased(code, factory);
if (info != null) {
- debugEntries = info.computeEntries(reference, d8R8Synthesized);
+ debugEntries = info.computeEntries(originalMethod);
}
canonicalPositions =
new CanonicalPositions(
callerPosition,
debugEntries == null ? 0 : debugEntries.size(),
- reference,
- d8R8Synthesized,
- DexDebugUtils.computePreamblePosition(reference, d8R8Synthesized, info)
- .getFramePosition());
+ originalMethod,
+ method.getDefinition().isD8R8Synthesized(),
+ DexDebugUtils.computePreamblePosition(originalMethod, info).getFramePosition());
}
@Override
@@ -260,7 +261,17 @@
}
private Position getCanonicalPositionAppendCaller(DexDebugEntry entry) {
- return canonicalPositions.canonicalizePositionWithCaller(entry.getPosition());
+ // If this instruction has already been inlined then the original method must be in the caller
+ // chain.
+ Position position = entry.getPosition();
+ // TODO(b/261971803): The original method should probably always be in the chain.
+ assert !position.hasCallerPosition() || position.hasMethodInChain(originalMethod);
+ return canonicalPositions.getCanonical(
+ position
+ .builderWithCopy()
+ .setCallerPosition(
+ canonicalPositions.canonicalizeCallerPosition(position.getCallerPosition()))
+ .build());
}
@Override
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 735df70..0341252 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
@@ -1053,6 +1053,7 @@
appView,
null,
RewrittenPrototypeDescription.none(),
+ appView.graphLens().getOriginalMethodSignature(code.context().getReference()),
(MutableMethodConversionOptions) code.getConversionOptions());
timing.end();
return irCode;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 46988a7..44f9afd 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
@@ -676,8 +675,6 @@
newAccessFlags.unsetPrivate();
// Always make the method public to provide access.
newAccessFlags.setPublic();
- Code code = encodedMethod.getCode();
- DexItemFactory factory = appView.dexItemFactory();
DexEncodedMethod newMethod =
DexEncodedMethod.syntheticBuilder()
.setMethod(callTarget)
@@ -686,12 +683,10 @@
.setAnnotations(encodedMethod.annotations())
.setParameterAnnotations(encodedMethod.parameterAnnotationsList)
.setCode(
- code.getCodeAsInlining(
- callTarget,
- true,
- encodedMethod.getReference(),
- encodedMethod.isD8R8Synthesized(),
- factory))
+ encodedMethod
+ .getCode()
+ .getCodeAsInlining(
+ callTarget, encodedMethod, appView.dexItemFactory()))
.setApiLevelForDefinition(encodedMethod.getApiLevelForDefinition())
.setApiLevelForCode(encodedMethod.getApiLevelForCode())
.build();
@@ -775,8 +770,6 @@
// its accessibility and make it virtual.
MethodAccessFlags newAccessFlags = encodedMethod.accessFlags.copy();
newAccessFlags.unsetPrivate();
- Code code = encodedMethod.getCode();
- DexItemFactory factory = appView.dexItemFactory();
DexEncodedMethod newMethod =
DexEncodedMethod.syntheticBuilder()
.setMethod(callTarget)
@@ -785,12 +778,10 @@
.setAnnotations(encodedMethod.annotations())
.setParameterAnnotations(encodedMethod.parameterAnnotationsList)
.setCode(
- code.getCodeAsInlining(
- callTarget,
- true,
- encodedMethod.getReference(),
- encodedMethod.isD8R8Synthesized(),
- factory))
+ encodedMethod
+ .getCode()
+ .getCodeAsInlining(
+ callTarget, encodedMethod, appView.dexItemFactory()))
.setApiLevelForDefinition(encodedMethod.getApiLevelForDefinition())
.setApiLevelForCode(encodedMethod.getApiLevelForCode())
.build();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
index 0dd9fec..092423e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
@@ -108,7 +108,7 @@
if (clazz.lookupProgramMethod(bridgeReference) == null) {
// Create a new private method holding the code of the virtual method.
ProgramMethod newDirectMethod =
- method.getDefinition().toPrivateSyntheticMethod(clazz, bridgeReference, dexItemFactory);
+ method.getDefinition().toPrivateSyntheticMethod(clazz, bridgeReference);
// Create the new cf code object for the virtual method.
CfCode virtualMethodCode =
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
index 4fff3f5..21771de 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringSyntheticHelper.java
@@ -457,12 +457,10 @@
// Represent a static interface method as a method of companion class.
private DexMethod staticAsMethodOfCompanionClass(DexClassAndMethod method) {
- return staticAsMethodOfCompanionClass(method.getReference(), appView.dexItemFactory());
- }
-
- public static DexMethod staticAsMethodOfCompanionClass(DexMethod method, DexItemFactory factory) {
- DexType companionClassType = getCompanionClassType(method.getHolderType(), factory);
- return method.withHolder(companionClassType, factory);
+ DexItemFactory dexItemFactory = appView.dexItemFactory();
+ DexType companionClassType = getCompanionClassType(method.getHolderType(), dexItemFactory);
+ DexMethod rewritten = method.getReference().withHolder(companionClassType, dexItemFactory);
+ return rewritten;
}
private static DexMethod instanceAsMethodOfCompanionClass(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
index 1e53aa6..7ac6713 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceProcessor.java
@@ -204,11 +204,7 @@
definition
.getCode()
.getCodeAsInlining(
- companion.getReference(),
- companion.getDefinition().isD8R8Synthesized(),
- method.getReference(),
- method.getDefinition().isD8R8Synthesized(),
- appView.dexItemFactory());
+ companion.getReference(), method.getDefinition(), appView.dexItemFactory());
if (!definition.isStatic()) {
DexEncodedMethod.setDebugInfoWithFakeThisParameter(
code, companion.getReference().getArity(), appView);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
index 627d5ba..ac0bc7b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingTreeFixer.java
@@ -916,9 +916,8 @@
method, localUtilityClass, availableMethodSignatures, method.getReference());
return method
.getDefinition()
- .toTypeSubstitutedMethodAsInlining(
+ .toTypeSubstitutedMethod(
newMethod,
- factory,
builder ->
transformMethodForLocalUtility(builder, method)
.setCompilationState(method.getDefinition().getCompilationState()));
@@ -935,9 +934,8 @@
DexEncodedMethod dexEncodedMethod =
method
.getDefinition()
- .toTypeSubstitutedMethodAsInlining(
+ .toTypeSubstitutedMethod(
newMethod,
- factory,
builder ->
transformMethodForLocalUtility(builder, method)
.modifyAccessFlags(MethodAccessFlags::unsetAbstract)
@@ -1018,9 +1016,8 @@
RewrittenPrototypeDescription prototypeChanges =
lensBuilder.moveAndMap(
method.getReference(), newMethod, isStatic, isStatic, extraUnusedNullParameters);
- return method.toTypeSubstitutedMethodAsInlining(
+ return method.toTypeSubstitutedMethod(
newMethod,
- factory,
builder ->
builder
.fixupOptimizationInfo(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/code/CheckNotZeroCode.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/code/CheckNotZeroCode.java
index b17f4b6..4e7801c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/code/CheckNotZeroCode.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/code/CheckNotZeroCode.java
@@ -16,9 +16,6 @@
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
-import com.android.tools.r8.ir.code.NumberGenerator;
-import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
import com.android.tools.r8.ir.optimize.enums.EnumUnboxerImpl;
@@ -51,28 +48,7 @@
Origin origin,
MutableMethodConversionOptions conversionOptions) {
// Build IR from the checkNotNull() method.
- Position callerPosition =
- SyntheticPosition.builder()
- .setMethod(checkNotZeroMethod.getReference())
- .setLine(0)
- .setIsD8R8Synthesized(checkNotZeroMethod.getDefinition().isD8R8Synthesized())
- .build();
- NumberGenerator valueNumberGenerator = new NumberGenerator();
- IRCode code =
- checkNotNullMethod
- .getDefinition()
- .getCode()
- .buildInliningIR(
- checkNotZeroMethod,
- checkNotNullMethod,
- appView,
- appView.graphLens(),
- valueNumberGenerator,
- callerPosition,
- checkNotZeroMethod.getOrigin(),
- appView
- .graphLens()
- .lookupPrototypeChangesForMethodDefinition(checkNotNullMethod.getReference()));
+ IRCode code = checkNotNullMethod.buildIR(appView);
InstructionListIterator instructionIterator = code.instructionListIterator();
// Start iterating at the argument instruction for the checked argument.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/inliner/InliningIRProvider.java b/src/main/java/com/android/tools/r8/ir/optimize/inliner/InliningIRProvider.java
index b1e76f3..958b02d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/inliner/InliningIRProvider.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/inliner/InliningIRProvider.java
@@ -84,7 +84,7 @@
context,
appView,
valueNumberGenerator,
- Position.getPositionForInlining(invoke, context),
+ Position.getPositionForInlining(appView, invoke, context),
origin,
methodProcessor);
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
index 1fe050f..ee3fc44 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/outliner/OutlinerImpl.java
@@ -341,12 +341,14 @@
}
@Override
+ @SuppressWarnings("ReferenceEquality")
public boolean equals(Object other) {
if (!(other instanceof NewInstanceOutlineInstruction)) {
return false;
}
NewInstanceOutlineInstruction o = (NewInstanceOutlineInstruction) other;
- return clazz.isIdenticalTo(o.clazz);
+ boolean result = clazz == o.clazz;
+ return result;
}
@Override
@@ -395,8 +397,9 @@
}
@Override
+ @SuppressWarnings("ReferenceEquality")
public boolean needsLensRewriting(GraphLens currentGraphLens) {
- return !clazz.isIdenticalTo(currentGraphLens.lookupType(clazz));
+ return currentGraphLens.lookupType(clazz) != clazz;
}
}
@@ -446,12 +449,13 @@
}
@Override
+ @SuppressWarnings("ReferenceEquality")
public boolean equals(Object other) {
if (!(other instanceof InvokeOutlineInstruction)) {
return false;
}
InvokeOutlineInstruction o = (InvokeOutlineInstruction) other;
- return method.isIdenticalTo(o.method)
+ return method == o.method
&& invokeType == o.invokeType
&& hasOutValue == o.hasOutValue
&& Objects.equals(proto, o.proto);
@@ -538,8 +542,9 @@
}
@Override
+ @SuppressWarnings("ReferenceEquality")
public boolean needsLensRewriting(GraphLens currentGraphLens) {
- return !method.isIdenticalTo(currentGraphLens.getRenamedMethodSignature(method));
+ return currentGraphLens.getRenamedMethodSignature(method) != method;
}
}
@@ -1250,9 +1255,8 @@
argumentsMapIndex = 0;
OutlineCallerPositionBuilder positionBuilder =
OutlineCallerPosition.builder()
- .setMethod(method.getReference())
+ .setMethod(appView.graphLens().getOriginalMethodSignature(method.getReference()))
.setOutlineCallee(outlineMethod)
- .setIsD8R8Synthesized(method.getDefinition().isD8R8Synthesized())
// We set the line number to 0 here and rely on the LineNumberOptimizer to
// set a new disjoint line.
.setLine(0);
@@ -1735,10 +1739,11 @@
}
@Override
+ @SuppressWarnings("ReferenceEquality")
public void buildInstruction(
IRBuilder builder, int instructionIndex, boolean firstBlockInstruction) {
if (instructionIndex == outline.templateInstructions.size()) {
- if (outline.returnType.isVoidType()) {
+ if (outline.returnType == dexItemFactory.voidType) {
builder.addReturn();
} else {
builder.addReturn(outline.argumentCount());
@@ -1785,11 +1790,7 @@
public Position getCurrentPosition() {
// Always build positions for outlinee - each callsite will only build a position map for
// instructions that are actually throwing.
- return OutlinePosition.builder(method)
- .setLine(position)
- .setMethod(method)
- .setIsD8R8Synthesized(true)
- .build();
+ return OutlinePosition.builder().setLine(position).setMethod(method).build();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java
index a51f68a..f726dda 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/AbstractSynthesizedCode.java
@@ -10,8 +10,6 @@
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.graph.lens.GraphLens;
@@ -53,7 +51,7 @@
}
@Override
- public final IRCode buildInliningIR(
+ public IRCode buildInliningIR(
ProgramMethod context,
ProgramMethod method,
AppView<?> appView,
@@ -74,18 +72,6 @@
}
@Override
- public final Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- // This code object is synthesized so "inlining" just "strips" the callee position.
- assert isCalleeD8R8Synthesized;
- return this;
- }
-
- @Override
public final String toString() {
return toString(null, RetracerForCodePrinting.empty());
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
index e62e6ca..24e8151 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
@@ -28,6 +28,7 @@
private DexType receiver;
private DexMethod method;
+ private DexMethod originalMethod;
private DexType targetReceiver;
private DexMethod target;
private InvokeType invokeType;
@@ -37,6 +38,7 @@
public Builder(DexMethod method) {
this.method = method;
+ this.originalMethod = method;
}
public Builder setReceiver(DexType receiver) {
@@ -49,6 +51,11 @@
return this;
}
+ public Builder setOriginalMethod(DexMethod originalMethod) {
+ this.originalMethod = originalMethod;
+ return this;
+ }
+
public Builder setTargetReceiver(DexType targetReceiver) {
this.targetReceiver = targetReceiver;
return this;
@@ -83,6 +90,7 @@
return new ForwardMethodSourceCode(
receiver,
method,
+ originalMethod,
targetReceiver,
target,
invokeType,
@@ -103,6 +111,7 @@
ForwardMethodSourceCode(
DexType receiver,
DexMethod method,
+ DexMethod originalMethod,
DexType targetReceiver,
DexMethod target,
InvokeType invokeType,
@@ -110,7 +119,7 @@
boolean isInterface,
boolean castResult,
boolean extraNullParameter) {
- super(receiver, method, callerPosition);
+ super(receiver, method, callerPosition, originalMethod);
assert (targetReceiver == null) == (invokeType == InvokeType.STATIC);
this.target = target;
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index 46a3a3a..f9c13e9 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -45,6 +45,11 @@
private final Position position;
protected SyntheticSourceCode(DexType receiver, DexMethod method, Position callerPosition) {
+ this(receiver, method, callerPosition, method);
+ }
+
+ protected SyntheticSourceCode(
+ DexType receiver, DexMethod method, Position callerPosition, DexMethod originalMethod) {
assert method != null;
this.receiver = receiver;
this.method = method;
@@ -59,16 +64,14 @@
for (int i = 0; i < paramCount; i++) {
this.paramRegisters[i] = nextRegister(ValueType.fromDexType(params[i]));
}
- // If there is a caller position that is the position of this synthetic code, otherwise
- // build up a synthetic position.
- this.position =
- callerPosition != null
- ? callerPosition
- : SyntheticPosition.builder()
- .setLine(0)
- .setMethod(method)
- .setIsD8R8Synthesized(true)
- .build();
+
+ position =
+ SyntheticPosition.builder()
+ .setLine(0)
+ .setMethod(originalMethod)
+ .setCallerPosition(callerPosition)
+ .setIsD8R8Synthesized(true)
+ .build();
}
protected final void add(Consumer<IRBuilder> constructor) {
diff --git a/src/main/java/com/android/tools/r8/lightir/IR2LirConverter.java b/src/main/java/com/android/tools/r8/lightir/IR2LirConverter.java
index 4c78283..2e191a7 100644
--- a/src/main/java/com/android/tools/r8/lightir/IR2LirConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/IR2LirConverter.java
@@ -39,11 +39,7 @@
this.strategy = strategy;
this.bytecodeMetadataProvider = bytecodeMetadataProvider;
this.builder =
- new LirBuilder<>(
- irCode.context().getReference(),
- irCode.context().getDefinition().isD8R8Synthesized(),
- strategy,
- options)
+ new LirBuilder<>(irCode.context().getReference(), strategy, options)
.setMetadata(irCode.metadata())
.prepareForBytecodeInstructionMetadata(bytecodeMetadataProvider.size());
}
diff --git a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
index 1bd59ff..877794a 100644
--- a/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
+++ b/src/main/java/com/android/tools/r8/lightir/Lir2IRConverter.java
@@ -31,6 +31,7 @@
import com.android.tools.r8.ir.code.ArrayLength;
import com.android.tools.r8.ir.code.ArrayPut;
import com.android.tools.r8.ir.code.BasicBlock;
+import com.android.tools.r8.ir.code.CanonicalPositions;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.CheckCast;
import com.android.tools.r8.ir.code.Cmp;
@@ -81,6 +82,7 @@
import com.android.tools.r8.ir.code.Or;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.RecordFieldValues;
import com.android.tools.r8.ir.code.Rem;
import com.android.tools.r8.ir.code.Return;
@@ -102,6 +104,7 @@
import com.android.tools.r8.lightir.LirBuilder.IntSwitchPayload;
import com.android.tools.r8.lightir.LirBuilder.StringSwitchPayload;
import com.android.tools.r8.lightir.LirCode.PositionEntry;
+import com.android.tools.r8.lightir.LirCode.StructuredPositionEntry;
import com.android.tools.r8.lightir.LirCode.TryCatchTable;
import com.android.tools.r8.naming.dexitembasedstring.NameComputationInfo;
import com.android.tools.r8.utils.ListUtils;
@@ -128,11 +131,12 @@
AppView<?> appView,
Position callerPosition,
RewrittenPrototypeDescription protoChanges,
+ DexMethod originalMethod,
MutableMethodConversionOptions conversionOptions) {
Parser<EV> parser =
new Parser<>(
lirCode,
- method.getReference(),
+ originalMethod,
method.getDefinition().isD8R8Synthesized(),
appView,
strategy,
@@ -164,7 +168,7 @@
private final AppView<?> appView;
private final LirCode<EV> code;
- private final DexMethod method;
+ private final DexMethod originalMethod;
private final LirDecodingStrategy<Value, EV> strategy;
private final NumberGenerator basicBlockNumberGenerator = new NumberGenerator();
private final RewrittenPrototypeDescription protoChanges;
@@ -184,7 +188,7 @@
public Parser(
LirCode<EV> code,
- DexMethod method,
+ DexMethod originalMethod,
boolean isD8R8Synthesized,
AppView<?> appView,
LirDecodingStrategy<Value, EV> strategy,
@@ -193,7 +197,7 @@
super(code);
this.appView = appView;
this.code = code;
- this.method = method;
+ this.originalMethod = originalMethod;
this.strategy = strategy;
this.protoChanges = protoChanges;
assert protoChanges != null;
@@ -201,14 +205,43 @@
buildForInlining = false;
positionTable = code.getPositionTable();
// Recreate the preamble position. This is active for arguments and code with no positions.
- currentPosition = code.getPreamblePosition(method, isD8R8Synthesized);
+ currentPosition = SyntheticPosition.builder().setLine(0).setMethod(originalMethod).build();
} else {
buildForInlining = true;
- positionTable =
- code.getPositionTableAsInlining(
- callerPosition, method, isD8R8Synthesized, preamble -> currentPosition = preamble);
+ PositionEntry[] inlineePositions = code.getPositionTable();
+ Position inlineePreamble = null;
+ if (inlineePositions.length > 0 && inlineePositions[0].getFromInstructionIndex() == 0) {
+ inlineePreamble = inlineePositions[0].getPosition(originalMethod);
+ }
+ CanonicalPositions canonicalPositions =
+ new CanonicalPositions(
+ callerPosition,
+ inlineePositions.length,
+ originalMethod,
+ isD8R8Synthesized,
+ inlineePreamble);
+ currentPosition = canonicalPositions.getPreamblePosition();
+ positionTable = new PositionEntry[inlineePositions.length];
+ for (int i = 0; i < inlineePositions.length; i++) {
+ PositionEntry inlineeEntry = inlineePositions[i];
+ Position inlineePosition = inlineeEntry.getPosition(originalMethod);
+ positionTable[i] =
+ new StructuredPositionEntry(
+ inlineeEntry.getFromInstructionIndex(),
+ canonicalPositions.getCanonical(
+ inlineePosition
+ .builderWithCopy()
+ .setCallerPosition(
+ canonicalPositions.canonicalizeCallerPosition(
+ inlineePosition.getCallerPosition()))
+ .build()));
+ }
}
- entryPosition = currentPosition;
+ if (positionTable.length > 0 && positionTable[0].getFromInstructionIndex() == 0) {
+ entryPosition = positionTable[0].getPosition(originalMethod);
+ } else {
+ entryPosition = currentPosition;
+ }
}
@Override
@@ -242,9 +275,7 @@
private void ensureCurrentPosition() {
if (nextPositionEntry != null
&& nextPositionEntry.getFromInstructionIndex() <= nextInstructionIndex) {
- currentPosition =
- nextPositionEntry.getPosition(
- method, entryPosition.getOutermostCaller().isD8R8Synthesized());
+ currentPosition = nextPositionEntry.getPosition(originalMethod);
advanceNextPositionEntry();
}
}
@@ -470,6 +501,7 @@
private Argument internalAddArgument(Value dest, boolean isBooleanType) {
assert currentBlock != null;
+ assert currentPosition.isSyntheticPosition() || buildForInlining;
// Arguments are not included in the "instructions" so this does not call "addInstruction"
// which would otherwise advance the state.
Argument argument = new Argument(dest, currentBlock.size(), isBooleanType);
diff --git a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
index 5d988d8..d222f5f 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirBuilder.java
@@ -276,21 +276,13 @@
}
public LirBuilder(
- DexMethod method,
- boolean isD8R8Synthesized,
- LirEncodingStrategy<V, EV> strategy,
- InternalOptions options) {
+ DexMethod method, LirEncodingStrategy<V, EV> strategy, InternalOptions options) {
useDexEstimationStrategy = options.isGeneratingDex();
factory = options.dexItemFactory();
constants = new Reference2IntOpenHashMap<>();
positionTable = new ArrayList<>();
this.strategy = strategy;
- currentPosition =
- SyntheticPosition.builder()
- .setLine(0)
- .setMethod(method)
- .setIsD8R8Synthesized(isD8R8Synthesized)
- .build();
+ currentPosition = SyntheticPosition.builder().setLine(0).setMethod(method).build();
flushedPosition = currentPosition;
}
diff --git a/src/main/java/com/android/tools/r8/lightir/LirCode.java b/src/main/java/com/android/tools/r8/lightir/LirCode.java
index 8270d8a..f79a18f 100644
--- a/src/main/java/com/android/tools/r8/lightir/LirCode.java
+++ b/src/main/java/com/android/tools/r8/lightir/LirCode.java
@@ -21,14 +21,12 @@
import com.android.tools.r8.graph.bytecodemetadata.BytecodeMetadata;
import com.android.tools.r8.graph.lens.GraphLens;
import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
-import com.android.tools.r8.ir.code.CanonicalPositions;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.IRMetadata;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SourcePosition;
-import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
import com.android.tools.r8.ir.conversion.MethodConversionOptions;
import com.android.tools.r8.ir.conversion.MethodConversionOptions.MutableMethodConversionOptions;
@@ -61,8 +59,6 @@
public abstract static class PositionEntry implements StructuralItem<PositionEntry> {
- public static final PositionEntry[] EMPTY_ARRAY = new PositionEntry[0];
-
private final int fromInstructionIndex;
PositionEntry(int fromInstructionIndex) {
@@ -73,7 +69,7 @@
return fromInstructionIndex;
}
- public abstract Position getPosition(DexMethod method, boolean isD8R8Synthesized);
+ public abstract Position getPosition(DexMethod method);
abstract int getOrder();
@@ -120,12 +116,8 @@
}
@Override
- public Position getPosition(DexMethod method, boolean isD8R8Synthesized) {
- return (isD8R8Synthesized ? SyntheticPosition.builder() : SourcePosition.builder())
- .setMethod(method)
- .setIsD8R8Synthesized(isD8R8Synthesized)
- .setLine(line)
- .build();
+ public Position getPosition(DexMethod method) {
+ return SourcePosition.builder().setMethod(method).setLine(line).build();
}
@Override
@@ -153,7 +145,7 @@
}
@Override
- public Position getPosition(DexMethod method, boolean isD8R8Synthesized) {
+ public Position getPosition(DexMethod method) {
return position;
}
@@ -352,11 +344,8 @@
private Int2ReferenceMap<BytecodeInstructionMetadata> metadataMap;
public static <V, EV> LirBuilder<V, EV> builder(
- DexMethod method,
- boolean isD8R8Synthesized,
- LirEncodingStrategy<V, EV> strategy,
- InternalOptions options) {
- return new LirBuilder<>(method, isD8R8Synthesized, strategy, options);
+ DexMethod method, LirEncodingStrategy<V, EV> strategy, InternalOptions options) {
+ return new LirBuilder<>(method, strategy, options);
}
private static <EV> void specify(StructuralSpecification<LirCode<EV>, ?> spec) {
@@ -377,7 +366,7 @@
LirCode(
IRMetadata irMetadata,
LirConstant[] constants,
- PositionEntry[] positionTable,
+ PositionEntry[] positions,
int argumentCount,
byte[] instructions,
int instructionCount,
@@ -386,10 +375,9 @@
LirStrategyInfo<EV> strategyInfo,
boolean useDexEstimationStrategy,
Int2ReferenceMap<BytecodeInstructionMetadata> metadataMap) {
- assert positionTable != null;
this.irMetadata = irMetadata;
this.constants = constants;
- this.positionTable = positionTable;
+ this.positionTable = positions;
this.argumentCount = argumentCount;
this.instructions = instructions;
this.instructionCount = instructionCount;
@@ -552,6 +540,7 @@
appView,
callerPosition,
protoChanges,
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
conversionOptions);
}
@@ -645,78 +634,9 @@
}
}
- public Position getPreamblePosition(DexMethod method, boolean isD8R8Synthesized) {
- if (positionTable.length > 0 && positionTable[0].fromInstructionIndex == 0) {
- return positionTable[0].getPosition(method, isD8R8Synthesized);
- }
- return SyntheticPosition.builder()
- .setLine(0)
- .setMethod(method)
- .setIsD8R8Synthesized(isD8R8Synthesized)
- .build();
- }
-
- public PositionEntry[] getPositionTableAsInlining(
- Position callerPosition,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- Consumer<Position> preamblePositionConsumer) {
- // Fast path for moving a synthetic method with no actual line info.
- if (isCalleeD8R8Synthesized && positionTable.length == 0) {
- preamblePositionConsumer.accept(callerPosition);
- return PositionEntry.EMPTY_ARRAY;
- }
- Position calleePreamble = getPreamblePosition(callee, isCalleeD8R8Synthesized);
- CanonicalPositions canonicalPositions =
- new CanonicalPositions(
- callerPosition, positionTable.length, callee, isCalleeD8R8Synthesized, calleePreamble);
- PositionEntry[] newPositionTable;
- if (positionTable.length == 0) {
- newPositionTable =
- new PositionEntry[] {
- new StructuredPositionEntry(0, canonicalPositions.getPreamblePosition())
- };
- } else {
- newPositionTable = new PositionEntry[positionTable.length];
- for (int i = 0; i < positionTable.length; i++) {
- PositionEntry inlineeEntry = positionTable[i];
- Position inlineePosition = inlineeEntry.getPosition(callee, isCalleeD8R8Synthesized);
- newPositionTable[i] =
- new StructuredPositionEntry(
- inlineeEntry.getFromInstructionIndex(),
- canonicalPositions.canonicalizePositionWithCaller(inlineePosition));
- }
- }
- preamblePositionConsumer.accept(canonicalPositions.getPreamblePosition());
- return newPositionTable;
- }
-
@Override
- public Code getCodeAsInlining(
- DexMethod caller,
- boolean isCallerD8R8Synthesized,
- DexMethod callee,
- boolean isCalleeD8R8Synthesized,
- DexItemFactory factory) {
- Position callerPosition =
- SyntheticPosition.builder().setLine(0).setMethod(caller).setIsD8R8Synthesized(true).build();
- PositionEntry[] newPositionTable =
- getPositionTableAsInlining(callerPosition, callee, isCalleeD8R8Synthesized, unused -> {});
- if (Arrays.equals(positionTable, newPositionTable)) {
- return this;
- }
- return new LirCode<>(
- irMetadata,
- constants,
- newPositionTable,
- argumentCount,
- instructions,
- instructionCount,
- tryCatchTable,
- debugLocalInfoTable,
- strategyInfo,
- useDexEstimationStrategy,
- metadataMap);
+ public Code getCodeAsInlining(DexMethod caller, DexEncodedMethod callee, DexItemFactory factory) {
+ throw new Unimplemented();
}
@Override
@@ -742,10 +662,9 @@
}
@Override
- public void forEachPosition(
- DexMethod method, boolean isD8R8Synthesized, Consumer<Position> positionConsumer) {
+ public void forEachPosition(DexMethod method, Consumer<Position> positionConsumer) {
for (PositionEntry entry : positionTable) {
- positionConsumer.accept(entry.getPosition(method, isD8R8Synthesized));
+ positionConsumer.accept(entry.getPosition(method));
}
}
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
index 588666a..24fb83a 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapMinifier.java
@@ -8,7 +8,6 @@
import static com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper.defaultAsMethodOfCompanionClass;
import static com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper.getInterfaceClassType;
import static com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper.isCompanionClassType;
-import static com.android.tools.r8.ir.desugar.itf.InterfaceDesugaringSyntheticHelper.staticAsMethodOfCompanionClass;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
@@ -78,7 +77,7 @@
// To keep the order deterministic, we sort the classes by their type, which is a unique key.
private final Set<ProgramOrClasspathClass> mappedClasses = Sets.newIdentityHashSet();
private final Map<DexReference, MemberNaming> memberNames = Maps.newIdentityHashMap();
- private final Map<DexMethod, DexString> companionClassInterfaceMethodImplementationNames =
+ private final Map<DexMethod, DexString> defaultInterfaceMethodImplementationNames =
Maps.newIdentityHashMap();
private final Map<DexMethod, DexString> additionalMethodNamings = Maps.newIdentityHashMap();
private final Map<DexField, DexString> additionalFieldNamings = Maps.newIdentityHashMap();
@@ -136,7 +135,7 @@
new MethodNameMinifier(appView, nameStrategy)
.computeRenaming(interfaces, subtypingInfo, executorService, timing);
// Amend the method renamings with the default interface methods.
- methodRenaming.renaming.putAll(companionClassInterfaceMethodImplementationNames);
+ methodRenaming.renaming.putAll(defaultInterfaceMethodImplementationNames);
methodRenaming.renaming.putAll(additionalMethodNamings);
timing.end();
@@ -330,16 +329,19 @@
// TODO(b/150736225): Is this sound? What if the type is a library type that has been pruned?
DexClass dexClass = appView.appInfo().definitionForWithoutExistenceAssert(type);
if (dexClass == null || dexClass.isClasspathClass()) {
- computeCompanionClassInterfaceMethodMappingsForType(
- type, classNaming, companionClassInterfaceMethodImplementationNames);
+ computeDefaultInterfaceMethodMappingsForType(
+ type,
+ classNaming,
+ defaultInterfaceMethodImplementationNames);
}
}
}
- private void computeCompanionClassInterfaceMethodMappingsForType(
+ @SuppressWarnings("ReferenceEquality")
+ private void computeDefaultInterfaceMethodMappingsForType(
DexType type,
ClassNamingForMapApplier classNaming,
- Map<DexMethod, DexString> companionClassInterfaceMethodImplementationNames) {
+ Map<DexMethod, DexString> defaultInterfaceMethodImplementationNames) {
// If the class does not resolve, then check if it is a companion class for an interface on
// the class path.
if (!isCompanionClassType(type)) {
@@ -358,26 +360,12 @@
MemberNaming naming = namings.get(0);
MethodSignature signature = (MethodSignature) naming.getOriginalSignature();
if (signature.name.startsWith(interfaceType.type.toSourceString())) {
- DexMethod originalReference =
- signature.toUnqualified().toDexMethod(factory, interfaceType.type);
- DexEncodedMethod originalDefinition = interfaceType.lookupMethod(originalReference);
- if (originalDefinition == null) {
- assert false;
- continue;
- }
- DexMethod originalDesugaredMethod;
- if (originalDefinition.isStatic()) {
- originalDesugaredMethod = staticAsMethodOfCompanionClass(originalReference, factory);
- } else if (originalDefinition.isNonAbstractVirtualMethod()) {
- originalDesugaredMethod = defaultAsMethodOfCompanionClass(originalReference, factory);
- } else {
- // There is no implementation for private interface methods as those are not accessible
- // outside the interface itself and should never need to be represented for apply mapping.
- continue;
- }
- assert type.isIdenticalTo(originalDesugaredMethod.holder);
- DexString renamed = factory.createString(naming.getRenamedName());
- companionClassInterfaceMethodImplementationNames.put(originalDesugaredMethod, renamed);
+ DexMethod defaultMethod =
+ defaultAsMethodOfCompanionClass(
+ signature.toUnqualified().toDexMethod(factory, interfaceType.type), factory);
+ assert defaultMethod.holder == type;
+ defaultInterfaceMethodImplementationNames.put(
+ defaultMethod, factory.createString(naming.getRenamedName()));
}
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/accessmodification/AccessModifier.java b/src/main/java/com/android/tools/r8/optimize/accessmodification/AccessModifier.java
index c97f10b..fba2f6f 100644
--- a/src/main/java/com/android/tools/r8/optimize/accessmodification/AccessModifier.java
+++ b/src/main/java/com/android/tools/r8/optimize/accessmodification/AccessModifier.java
@@ -317,10 +317,7 @@
lensBuilder.recordMove(method.getReference(), newMethodReference);
method =
new ProgramMethod(
- holder,
- method
- .getDefinition()
- .toTypeSubstitutedMethodAsInlining(newMethodReference, appView.dexItemFactory()));
+ holder, method.getDefinition().toTypeSubstitutedMethod(newMethodReference));
}
if (method.getAccessFlags().isPromotedFromPrivateToPublic()
&& method.getAccessFlags().belongsToVirtualPool()) {
diff --git a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
index 3d7c4e6..12a71ce 100644
--- a/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
+++ b/src/main/java/com/android/tools/r8/optimize/argumentpropagation/ArgumentPropagatorApplicationFixer.java
@@ -102,9 +102,8 @@
}
DexEncodedMethod replacement =
- method.toTypeSubstitutedMethodAsInlining(
+ method.toTypeSubstitutedMethod(
methodReferenceAfterParameterRemoval,
- appView.dexItemFactory(),
builder -> {
if (graphLens.hasPrototypeChanges(methodReferenceAfterParameterRemoval)) {
RewrittenPrototypeDescription prototypeChanges =
diff --git a/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java b/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java
index 387d67d..d8149d7 100644
--- a/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java
+++ b/src/main/java/com/android/tools/r8/optimize/bridgehoisting/BridgeHoisting.java
@@ -263,9 +263,7 @@
DexMethod newMethodReference =
appView.dexItemFactory().createMethod(clazz.type, method.proto, method.name);
DexEncodedMethod newMethod =
- representative
- .getDefinition()
- .toTypeSubstitutedMethodAsInlining(newMethodReference, appView.dexItemFactory());
+ representative.getDefinition().toTypeSubstitutedMethod(newMethodReference);
if (newMethod.getAccessFlags().isFinal()) {
newMethod.getAccessFlags().demoteFromFinal();
}
diff --git a/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java b/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java
index 902fb45..3cac2b3 100644
--- a/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java
+++ b/src/main/java/com/android/tools/r8/optimize/proto/ProtoNormalizer.java
@@ -136,9 +136,8 @@
// this should simply clear the optimization info, or replace it by a
// ThrowingMethodOptimizationInfo since we should never use the optimization
// info after this point.
- return method.toTypeSubstitutedMethodAsInlining(
+ return method.toTypeSubstitutedMethod(
newMethodReference,
- dexItemFactory,
builder -> {
if (!prototypeChanges.isEmpty()) {
builder
diff --git a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
index 55501d8..1b9b6c3 100644
--- a/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
+++ b/src/main/java/com/android/tools/r8/repackaging/Repackaging.java
@@ -14,7 +14,6 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.graph.InnerClassAttribute;
@@ -116,11 +115,6 @@
protected boolean isLegitimateToHaveEmptyMappings() {
return true;
}
-
- @Override
- public <T extends DexReference> boolean isSimpleRenaming(T from, T to) {
- return getPrevious().isSimpleRenaming(from, to);
- }
};
DirectMappedDexApplication newApplication =
appView
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index ce3827c..0f3b284 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -67,6 +67,7 @@
import com.android.tools.r8.graph.lens.NonIdentityGraphLens;
import com.android.tools.r8.graph.proto.RewrittenPrototypeDescription;
import com.android.tools.r8.ir.code.InvokeType;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedbackSimple;
@@ -1013,9 +1014,7 @@
virtualMethod.getProto().prependParameter(source.getType(), dexItemFactory),
dexItemFactory.createGloballyFreshMemberString(resultingMethodBaseName));
assert availableMethodSignatures.test(resultingMethodReference);
- resultingMethod =
- virtualMethod.toTypeSubstitutedMethodAsInlining(
- resultingMethodReference, dexItemFactory);
+ resultingMethod = virtualMethod.toTypeSubstitutedMethod(resultingMethodReference);
makeStatic(resultingMethod);
} else {
// This virtual method could be called directly from a sub class via an invoke-super in-
@@ -1444,6 +1443,7 @@
SynthesizedBridgeCode code =
new SynthesizedBridgeCode(
newMethod,
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
invocationTarget.getReference(),
invocationTarget.isStatic()
? STATIC
@@ -1562,8 +1562,7 @@
count++;
} while (!availableMethodSignatures.test(newSignature));
- DexEncodedMethod result =
- method.toTypeSubstitutedMethodAsInlining(newSignature, appView.dexItemFactory());
+ DexEncodedMethod result = method.toTypeSubstitutedMethod(newSignature);
result.getMutableOptimizationInfo().markForceInline();
deferredRenamings.map(method.getReference(), result.getReference());
deferredRenamings.recordMove(method.getReference(), result.getReference());
@@ -1617,7 +1616,7 @@
throw new Unreachable();
}
- return method.toTypeSubstitutedMethodAsInlining(newSignature, appView.dexItemFactory());
+ return method.toTypeSubstitutedMethod(newSignature);
}
private DexEncodedField renameFieldIfNeeded(
@@ -2246,16 +2245,19 @@
protected static class SynthesizedBridgeCode extends AbstractSynthesizedCode {
private DexMethod method;
+ private DexMethod originalMethod;
private DexMethod invocationTarget;
private InvokeType type;
private final boolean isInterface;
public SynthesizedBridgeCode(
DexMethod method,
+ DexMethod originalMethod,
DexMethod invocationTarget,
InvokeType type,
boolean isInterface) {
this.method = method;
+ this.originalMethod = originalMethod;
this.invocationTarget = invocationTarget;
this.type = type;
this.isInterface = isInterface;
@@ -2283,12 +2285,20 @@
ForwardMethodSourceCode.builder(method);
forwardSourceCodeBuilder
.setReceiver(method.holder)
+ .setOriginalMethod(originalMethod)
.setTargetReceiver(type.isStatic() ? null : method.holder)
.setTarget(invocationTarget)
.setInvokeType(type)
.setIsInterface(isInterface);
return (context, callerPosition) -> {
- return forwardSourceCodeBuilder.build(context, callerPosition);
+ SyntheticPosition caller =
+ SyntheticPosition.builder()
+ .setLine(0)
+ .setMethod(method)
+ .setIsD8R8Synthesized(true)
+ .setCallerPosition(callerPosition)
+ .build();
+ return forwardSourceCodeBuilder.build(context, caller);
};
}
diff --git a/src/main/java/com/android/tools/r8/utils/DexDebugUtils.java b/src/main/java/com/android/tools/r8/utils/DexDebugUtils.java
index 54b8da6..adfda77 100644
--- a/src/main/java/com/android/tools/r8/utils/DexDebugUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/DexDebugUtils.java
@@ -37,13 +37,13 @@
}
public static PositionInfo computePreamblePosition(
- DexMethod method, boolean isD8R8Synthesized, EventBasedDebugInfo debugInfo) {
+ DexMethod method, EventBasedDebugInfo debugInfo) {
if (debugInfo == null) {
return PositionInfo.builder().build();
}
Box<Position> existingPositionFrame = new Box<>();
DexDebugPositionState visitor =
- new DexDebugPositionState(debugInfo.startLine, method, isD8R8Synthesized) {
+ new DexDebugPositionState(debugInfo.startLine, method) {
@Override
public void visit(SetPositionFrame setPositionFrame) {
super.visit(setPositionFrame);
diff --git a/src/main/java/com/android/tools/r8/utils/positions/ClassFilePositionToMappedRangeMapper.java b/src/main/java/com/android/tools/r8/utils/positions/ClassFilePositionToMappedRangeMapper.java
index 08d30ac..787dd32 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/ClassFilePositionToMappedRangeMapper.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/ClassFilePositionToMappedRangeMapper.java
@@ -70,20 +70,17 @@
// If a method with overloads does not have an actual position then map it to the implicit
// preamble position.
DexMethod reference = method.getReference();
+ DexMethod original = appView.graphLens().getOriginalMethodSignature(reference);
CfPosition preamblePositionForOverload =
new CfPosition(
new CfLabel(),
remapAndAdd(
- SyntheticPosition.builder()
- .setMethod(reference)
- .setLine(0)
- .setIsD8R8Synthesized(method.getDefinition().isD8R8Synthesized())
- .build(),
+ SyntheticPosition.builder().setMethod(original).setLine(0).build(),
positionRemapper,
mappedPositions));
List<CfInstruction> shiftedPositions = new ArrayList<>(oldInstructions.size() + 2);
- shiftedPositions.add(preamblePositionForOverload.getLabel());
shiftedPositions.add(preamblePositionForOverload);
+ shiftedPositions.add(preamblePositionForOverload.getLabel());
shiftedPositions.addAll(newInstructions);
newInstructions = shiftedPositions;
}
diff --git a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java
index 099e233..8e0fcbb 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java
@@ -99,9 +99,8 @@
List<DexDebugEvent> processedEvents,
DexItemFactory factory,
int startLine,
- DexMethod method,
- boolean isD8R8Synthesized) {
- super(startLine, method, isD8R8Synthesized);
+ DexMethod method) {
+ super(startLine, method);
this.positionEventEmitter = positionEventEmitter;
this.mappedPositions = mappedPositions;
this.positionRemapper = positionRemapper;
@@ -190,9 +189,12 @@
getEventBasedDebugInfo(method.getDefinition(), dexCode, appView);
List<DexDebugEvent> processedEvents = new ArrayList<>();
+
PositionEventEmitter positionEventEmitter =
new PositionEventEmitter(
- application.dexItemFactory, method.getReference(), processedEvents);
+ application.dexItemFactory,
+ appView.graphLens().getOriginalMethodSignature(method.getReference()),
+ processedEvents);
DexDebugPositionStateVisitor visitor =
new DexDebugPositionStateVisitor(
@@ -202,8 +204,7 @@
processedEvents,
appView.dexItemFactory(),
debugInfo.startLine,
- method.getReference(),
- method.getDefinition().isD8R8Synthesized());
+ appView.graphLens().getOriginalMethodSignature(method.getReference()));
DexDebugEvent[] events = debugInfo.events;
for (DexDebugEvent event : events) {
@@ -218,7 +219,7 @@
assert !isIdentityMapping
|| visitor.inlinedOriginalPosition
- || verifyIdentityMapping(method, debugInfo, optimizedDebugInfo);
+ || verifyIdentityMapping(debugInfo, optimizedDebugInfo);
dexCode.setDebugInfo(optimizedDebugInfo);
return mappedPositions;
@@ -241,12 +242,7 @@
}
private static boolean verifyIdentityMapping(
- ProgramMethod method,
- EventBasedDebugInfo originalDebugInfo,
- EventBasedDebugInfo optimizedDebugInfo) {
- if (isTrivialSyntheticMethod(method, originalDebugInfo)) {
- return true;
- }
+ EventBasedDebugInfo originalDebugInfo, EventBasedDebugInfo optimizedDebugInfo) {
assert optimizedDebugInfo.startLine == originalDebugInfo.startLine;
assert optimizedDebugInfo.events.length == originalDebugInfo.events.length;
for (int i = 0; i < originalDebugInfo.events.length; ++i) {
@@ -254,27 +250,4 @@
}
return true;
}
-
- private static boolean isTrivialSyntheticMethod(
- ProgramMethod method, EventBasedDebugInfo originalDebugInfo) {
- if (!method.getDefinition().isD8R8Synthesized()) {
- return false;
- }
- // A synthetic method may have different debug info but still be trivial if it holds that all
- // the frames are just trivial frames for the synthetic method itself.
- for (DexDebugEvent event : originalDebugInfo.events) {
- if (event.isPositionFrame()) {
- Position position = event.asSetPositionFrame().getPosition();
- if (!method.getReference().isIdenticalTo(position.getMethod())
- || !position.isD8R8Synthesized()
- || position.hasCallerPosition()
- || position.isOutline()
- || position.isRemoveInnerFramesIfThrowingNpe()) {
- // If the frame is not trivial then break and assert the usual identity property.
- return false;
- }
- }
- }
- return true;
- }
}
diff --git a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java
index a1bb8a5..ecc6468 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java
@@ -45,8 +45,7 @@
DexDebugEventVisitor visitor =
new DexDebugPositionState(
debugInfo.startLine,
- method.getReference(),
- method.getDefinition().isD8R8Synthesized()) {
+ appView.graphLens().getOriginalMethodSignature(method.getReference())) {
@Override
public void visit(Default defaultEvent) {
super.visit(defaultEvent);
diff --git a/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
index 12a6f21..c91839c 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
@@ -147,7 +147,9 @@
for (ProgramMethod method : methods) {
DexEncodedMethod definition = method.getDefinition();
+ DexMethod methodReference = method.getReference();
if (methodName == method.getName()
+ && appView.graphLens().getOriginalMethodSignature(methodReference) == methodReference
&& !mustHaveResidualDebugInfo(appView.options(), definition)
&& !definition.isD8R8Synthesized()
&& methods.size() <= 1) {
diff --git a/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java b/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java
index 80e22b5..41a3ecc 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/MappedPositionToClassNameMapperBuilder.java
@@ -18,7 +18,6 @@
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.OutlineCallerPosition;
-import com.android.tools.r8.ir.code.Position.OutlinePosition;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.ClassNaming;
import com.android.tools.r8.naming.ClassNamingForNameMapper.MappedRange;
@@ -225,6 +224,10 @@
PositionRemapper positionRemapper,
boolean canUseDexPc) {
DexEncodedMethod definition = method.getDefinition();
+ DexMethod originalMethod =
+ appView.graphLens().getOriginalMethodSignatureForMapping(method.getReference());
+ MethodSignature originalSignature =
+ MethodSignature.fromDexMethod(originalMethod, originalMethod.holder != originalType);
OneShotCollectionConsumer<MappingInformation> methodSpecificMappingInformation =
OneShotCollectionConsumer.wrap(new ArrayList<>());
@@ -233,25 +236,13 @@
// classes in the library. Additionally, this is one place where it is helpful for developers
// to also get reported synthesized frames since stubbing can change control-flow and
// exceptions.
- boolean canStripOuterFrame = canStripOuterFrame(method, mappedPositions);
- boolean residualIsD8R8Synthesized =
- method.getDefinition().isD8R8Synthesized()
- && !appView.getSyntheticItems().isGlobalSyntheticClass(method.getHolder())
- // TODO(b/302509457): Currently we can only represent moves on methods that have code
- // and thus positions. For methods with no code, use the lens to find the original.
- && method.getDefinition().hasCode();
- if (residualIsD8R8Synthesized && !canStripOuterFrame) {
+ if (isD8R8Synthesized(method, mappedPositions)
+ && !appView.getSyntheticItems().isGlobalSyntheticClass(method.getHolder())) {
methodSpecificMappingInformation.add(CompilerSynthesizedMappingInformation.getInstance());
}
DexMethod residualMethod =
appView.getNamingLens().lookupMethod(method.getReference(), appView.dexItemFactory());
- MethodSignature residualSignature = MethodSignature.fromDexMethod(residualMethod);
-
- DexMethod originalMethod =
- appView.graphLens().getOriginalMethodSignatureForMapping(method.getReference());
- MethodSignature originalSignature =
- MethodSignature.fromDexMethod(originalMethod, originalMethod.holder != originalType);
MapVersion mapFileVersion = appView.options().getMapFileVersion();
if (isIdentityMapping(
@@ -266,32 +257,13 @@
|| appView.isCfByteCodePassThrough(definition);
return this;
}
+ MethodSignature residualSignature = MethodSignature.fromDexMethod(residualMethod);
- if (ResidualSignatureMappingInformation.isSupported(mapFileVersion)) {
- boolean isSame = true;
- if (canStripOuterFrame) {
- for (MappedPosition mappedPosition : mappedPositions) {
- Position outerMostAfterStrip = mappedPosition.getPosition();
- while (outerMostAfterStrip.getCallerPosition().hasCallerPosition()) {
- outerMostAfterStrip = outerMostAfterStrip.getCallerPosition();
- }
- MethodSignature positionSignature =
- MethodSignature.fromDexMethod(outerMostAfterStrip.getMethod());
- if (!positionSignature.type.equals(residualSignature.type)
- || !Arrays.equals(positionSignature.parameters, residualSignature.parameters)) {
- isSame = false;
- break;
- }
- }
- } else {
- isSame =
- originalSignature.type.equals(residualSignature.type)
- && Arrays.equals(originalSignature.parameters, residualSignature.parameters);
- }
- if (!isSame) {
- methodSpecificMappingInformation.add(
- ResidualMethodSignatureMappingInformation.fromDexMethod(residualMethod));
- }
+ if (ResidualSignatureMappingInformation.isSupported(mapFileVersion)
+ && (!originalSignature.type.equals(residualSignature.type)
+ || !Arrays.equals(originalSignature.parameters, residualSignature.parameters))) {
+ methodSpecificMappingInformation.add(
+ ResidualMethodSignatureMappingInformation.fromDexMethod(residualMethod));
}
MemberNaming memberNaming = new MemberNaming(originalSignature, residualSignature);
@@ -321,11 +293,11 @@
});
// Check if mapped position is an outline
- DexMethod outlineMethodKey = getOutlineMethodKey(mappedPositions);
- if (outlineMethodKey != null) {
+ DexMethod outlineMethod = getOutlineMethod(mappedPositions.get(0).getPosition());
+ if (outlineMethod != null) {
outlinesToFix
.computeIfAbsent(
- outlineMethodKey,
+ outlineMethod,
outline -> new OutlineFixupBuilder(computeMappedMethod(outline, appView)))
.setMappedPositionsOutline(mappedPositions);
methodSpecificMappingInformation.add(OutlineMappingInformation.builder().build());
@@ -376,11 +348,6 @@
Range originalRange =
nonCardinalRangeCache.get(firstPosition.getLine(), lastPosition.getLine());
- boolean hasSyntheticOuterFrameAndNonSyntheticInner =
- residualIsD8R8Synthesized && firstPosition.hasCallerPosition();
- assert !hasSyntheticOuterFrameAndNonSyntheticInner
- || firstPosition.getOutermostCaller().isD8R8Synthesized();
-
MappedRange lastMappedRange =
getMappedRangesForPosition(
appView,
@@ -391,8 +358,7 @@
obfuscatedRange,
originalRange,
prunedInlinedClasses,
- cardinalRangeCache,
- canStripOuterFrame);
+ cardinalRangeCache);
// firstPosition will contain a potential outline caller.
if (firstPosition.isOutlineCaller()) {
outlineCallerPositions.putIfAbsent(firstPosition.asOutlineCaller(), lastMappedRange);
@@ -429,8 +395,7 @@
placeHolderLineToBeFixed, placeHolderLineToBeFixed),
nonCardinalRangeCache.get(position.getLine(), position.getLine()),
prunedInlinedClasses,
- cardinalRangeCache,
- canStripOuterFrame);
+ cardinalRangeCache);
maxPc.set(lastRange.minifiedRange.to);
});
outlinesToFix
@@ -444,40 +409,10 @@
return this;
}
- private boolean canStripOuterFrame(ProgramMethod method, List<MappedPosition> mappedPositions) {
- assert verifySyntheticPositions(method, mappedPositions);
- if (!method.getDefinition().isD8R8Synthesized() || mappedPositions.isEmpty()) {
- return false;
- }
- for (MappedPosition mappedPosition : mappedPositions) {
- Position position = mappedPosition.getPosition();
- if (!position.hasCallerPosition()) {
- // At least one position only has the synthetic method as its frame, so we can't strip it.
- return false;
- }
- if (position.isOutline() || position.isOutlineCaller()) {
- return false;
- }
- }
- return true;
- }
-
- private boolean verifySyntheticPositions(
- ProgramMethod method, List<MappedPosition> mappedPositions) {
- DexMethod thisMethod = method.getReference();
- boolean d8R8Synthesized = method.getDefinition().isD8R8Synthesized();
- for (MappedPosition mappedPosition : mappedPositions) {
- Position position = mappedPosition.getPosition();
- while (position.hasCallerPosition()) {
- assert !position.isOutline();
- assert !position.isD8R8Synthesized();
- position = position.getCallerPosition();
- }
- DexMethod outerCaller = position.getMethod();
- assert thisMethod.isIdenticalTo(outerCaller);
- assert d8R8Synthesized == position.isD8R8Synthesized();
- }
- return true;
+ private boolean isD8R8Synthesized(ProgramMethod method, List<MappedPosition> mappedPositions) {
+ return method.getDefinition().isD8R8Synthesized()
+ || (!mappedPositions.isEmpty()
+ && mappedPositions.get(0).getPosition().isD8R8Synthesized());
}
private MethodReference computeMappedMethod(DexMethod current, AppView<?> appView) {
@@ -497,15 +432,13 @@
Range obfuscatedRange,
Range originalLine,
Map<DexType, String> prunedInlineHolder,
- CardinalPositionRangeAllocator cardinalRangeCache,
- boolean canStripOuterFrame) {
+ CardinalPositionRangeAllocator cardinalRangeCache) {
MappedRange lastMappedRange = null;
int inlineFramesCount = -1;
do {
- if (canStripOuterFrame && !position.hasCallerPosition()) {
- assert position.isD8R8Synthesized();
- assert lastMappedRange != null;
- break;
+ if (position.isD8R8Synthesized() && position.hasCallerPosition()) {
+ position = position.getCallerPosition();
+ continue;
}
inlineFramesCount += 1;
DexType holderType = position.getMethod().getHolderType();
@@ -540,15 +473,16 @@
return lastMappedRange;
}
- private DexMethod getOutlineMethodKey(List<MappedPosition> mappedPositions) {
- for (MappedPosition mappedPosition : mappedPositions) {
- Position position = mappedPosition.getPosition().getOutermostCaller();
- if (position.isOutline()) {
- OutlinePosition outline = (OutlinePosition) position;
- return outline.getOutlineMethodKey();
- }
+ private DexMethod getOutlineMethod(Position mappedPosition) {
+ if (mappedPosition.isOutline()) {
+ return mappedPosition.getMethod();
}
- return null;
+ Position caller = mappedPosition.getCallerPosition();
+ if (caller == null) {
+ return null;
+ }
+ Position outermostCaller = caller.getOutermostCaller();
+ return outermostCaller.isOutline() ? outermostCaller.getMethod() : null;
}
@SuppressWarnings("ReferenceEquality")
diff --git a/src/main/java/com/android/tools/r8/utils/positions/PositionRemapper.java b/src/main/java/com/android/tools/r8/utils/positions/PositionRemapper.java
index 4026dc3..1d7e99f 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/PositionRemapper.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/PositionRemapper.java
@@ -77,9 +77,10 @@
}
@Override
+ @SuppressWarnings("ReferenceEquality")
public Pair<Position, Position> createRemappedPosition(Position position) {
assert position.getMethod() != null;
- if (position.getMethod().isIdenticalTo(previousMethod)) {
+ if (previousMethod == position.getMethod()) {
assert previousSourceLine >= 0;
if (position.getLine() > previousSourceLine
&& position.getLine() - previousSourceLine <= maxLineDelta) {
diff --git a/src/test/examples/shaking1/print-mapping-cf.ref b/src/test/examples/shaking1/print-mapping-cf.ref
new file mode 100644
index 0000000..8b38084
--- /dev/null
+++ b/src/test/examples/shaking1/print-mapping-cf.ref
@@ -0,0 +1,7 @@
+shaking1.Shaking -> shaking1.Shaking:
+shaking1.Used -> a.a:
+ 1:2:void <init>(java.lang.String):12:13 -> <init>
+ 1:1:java.lang.String aMethodThatIsNotUsedButKept():21:21 -> aMethodThatIsNotUsedButKept
+ 1:2:void main(java.lang.String[]):8:9 -> main
+ 1:1:java.lang.String method():17:17 -> a
+ java.lang.String name -> a
\ No newline at end of file
diff --git a/src/test/examples/shaking1/print-mapping-dex.ref b/src/test/examples/shaking1/print-mapping-dex.ref
new file mode 100644
index 0000000..cd0d3a3
--- /dev/null
+++ b/src/test/examples/shaking1/print-mapping-dex.ref
@@ -0,0 +1,8 @@
+shaking1.Shaking -> shaking1.Shaking:
+ 0:8:void main(java.lang.String[]):8:8 -> main
+ 9:21:void main(java.lang.String[]):9:9 -> main
+shaking1.Used -> a.a:
+ java.lang.String name -> a
+ 0:5:void <init>(java.lang.String):12:12 -> <init>
+ 0:16:java.lang.String method():17:17 -> a
+ 0:2:java.lang.String aMethodThatIsNotUsedButKept():0:0 -> aMethodThatIsNotUsedButKept
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java
index e88c86e..57e100b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClassesWithOverlappingVisibilitiesTest.java
@@ -43,14 +43,14 @@
ClassSubject bClassSubject = codeInspector.clazz(B.class);
assertThat(bClassSubject, isPresent());
- methodSubject = getUniqueDispatchBridgeMethod(bClassSubject);
+ methodSubject = bClassSubject.method("void", "foo$bridge");
assertThat(methodSubject, isPackagePrivate());
assertThat(codeInspector.clazz(C.class), isAbsent());
ClassSubject dClassSubject = codeInspector.clazz(D.class);
assertThat(dClassSubject, isPresent());
- methodSubject = getUniqueDispatchBridgeMethod(dClassSubject);
+ methodSubject = dClassSubject.method("void", "foo$bridge");
assertThat(methodSubject, isPublic());
ClassSubject eClassSubject = codeInspector.clazz(E.class);
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java
index 7dee4de..e7723fd 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingOverlapTest.java
@@ -49,7 +49,7 @@
assertThat(otherInitSubject, isPresent());
assertThat(otherInitSubject, writesInstanceField(classIdFieldSubject.getDexField()));
- MethodSubject printSubject = getUniqueDispatchBridgeMethod(aClassSubject);
+ MethodSubject printSubject = aClassSubject.method("void", "print$bridge");
assertThat(printSubject, isPresent());
assertThat(printSubject, readsInstanceField(classIdFieldSubject.getDexField()));
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
index ac23576..9288d9b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingPreoptimizedTest.java
@@ -61,7 +61,7 @@
assertThat(otherInitSubject, isPresent());
assertThat(otherInitSubject, writesInstanceField(classIdFieldSubject.getDexField()));
- MethodSubject printSubject = getUniqueDispatchBridgeMethod(aClassSubject);
+ MethodSubject printSubject = aClassSubject.method("void", "print$bridge");
assertThat(printSubject, isPresent());
assertThat(printSubject, readsInstanceField(classIdFieldSubject.getDexField()));
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java
index 2be25d3..ba27f46 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ConstructorMergingTrivialOverlapTest.java
@@ -49,7 +49,7 @@
assertThat(otherInitSubject, isPresent());
assertThat(otherInitSubject, writesInstanceField(classIdFieldSubject.getDexField()));
- MethodSubject printSubject = getUniqueDispatchBridgeMethod(aClassSubject);
+ MethodSubject printSubject = aClassSubject.method("void", "print$bridge");
assertThat(printSubject, isPresent());
assertThat(printSubject, readsInstanceField(classIdFieldSubject.getDexField()));
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java
index 0c564bc..a24aca6 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/HorizontalClassMergingTestBase.java
@@ -12,7 +12,6 @@
import com.android.tools.r8.horizontalclassmerging.ClassMerger;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.FieldSubject;
-import com.android.tools.r8.utils.codeinspector.MethodSubject;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -30,10 +29,6 @@
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
- public static MethodSubject getUniqueDispatchBridgeMethod(ClassSubject clazz) {
- return clazz.uniqueMethodThatMatches(m -> m.isVirtual() && m.isCompilerSynthesized());
- }
-
protected FieldSubject classMergerClassIdField(ClassSubject classSubject) {
assertTrue(classSubject.isPresent());
FieldSubject[] classIds =
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java
index 4f7faad..915e10b 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorForwardingTest.java
@@ -51,7 +51,7 @@
assertThat(otherInitSubject, isPresent());
assertThat(otherInitSubject, writesInstanceField(classIdFieldSubject.getDexField()));
- MethodSubject printSubject = getUniqueDispatchBridgeMethod(aClassSubject);
+ MethodSubject printSubject = aClassSubject.method("void", "print$bridge");
assertThat(printSubject, isPresent());
assertThat(printSubject, readsInstanceField(classIdFieldSubject.getDexField()));
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
index 3126419..655e6a8 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/MergedConstructorWithEquivalenceStackTraceTest.java
@@ -4,87 +4,36 @@
package com.android.tools.r8.classmerging.horizontal;
-import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForLineNumbers;
+import static com.android.tools.r8.naming.retrace.StackTrace.isSame;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NoVerticalClassMerging;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.TestRuntime.CfRuntime;
import com.android.tools.r8.naming.retrace.StackTrace;
-import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
+import org.junit.BeforeClass;
import org.junit.Test;
public class MergedConstructorWithEquivalenceStackTraceTest extends HorizontalClassMergingTestBase {
+ private static StackTrace expectedStackTrace;
+
public MergedConstructorWithEquivalenceStackTraceTest(TestParameters parameters) {
super(parameters);
}
- private final String FILE_NAME =
- ToolHelper.getSourceFileForTestClass(getClass()).getFileName().toString();
-
- private StackTrace getExpectedStackTrace() {
- return StackTrace.builder()
- .add(
- StackTraceLine.builder()
- .setFileName(FILE_NAME)
- .setClassName(typeName(Parent.class))
- .setMethodName("<init>")
- .build())
- .add(
- StackTraceLine.builder()
- .setFileName(FILE_NAME)
- .setClassName(typeName(A.class))
- .setMethodName("<init>")
- .build())
- .add(
- StackTraceLine.builder()
- .setFileName(FILE_NAME)
- .setClassName(typeName(Main.class))
- .setMethodName("main")
- .build())
- .build();
- }
-
- // TODO(b/301920457): The constructors should be merged in such a way that the original stack can
- // be recovered.
- private StackTrace getUnxpectedStackTrace() {
- return StackTrace.builder()
- .add(
- StackTraceLine.builder()
- .setFileName(FILE_NAME)
- .setClassName(typeName(Parent.class))
- .setMethodName("<init>")
- .build())
- .add(
- StackTraceLine.builder()
- .setFileName(FILE_NAME)
- .setClassName(typeName(Main.class))
- .setMethodName("main")
- .build())
- .build();
- }
-
- private void checkRetracedStackTrace(StackTrace expectedStackTrace, StackTrace stackTrace) {
- assertThat(stackTrace, isSameExceptForLineNumbers(expectedStackTrace));
- for (StackTraceLine line : stackTrace.getStackTraceLines()) {
- assertTrue(line.lineNumber > 0);
- }
- }
-
- @Test
- public void testReference() throws Exception {
- parameters.assumeJvmTestParameters();
+ @BeforeClass
+ public static void setup() throws Exception {
// Get the expected stack trace by running on the JVM.
- testForJvm(parameters)
- .addTestClasspath()
- .run(parameters.getRuntime(), Main.class)
- .assertFailure()
- .inspectStackTrace(actual -> checkRetracedStackTrace(getExpectedStackTrace(), actual));
+ expectedStackTrace =
+ testForJvm(getStaticTemp())
+ .addTestClasspath()
+ .run(CfRuntime.getSystemRuntime(), Main.class)
+ .assertFailure()
+ .map(StackTrace::extractFromJvm);
}
@Test
@@ -105,8 +54,17 @@
.inspectStackTrace(
(stackTrace, codeInspector) -> {
assertThat(codeInspector.clazz(A.class), isPresent());
+ StackTrace expectedStackTraceWithMergedConstructor =
+ StackTrace.builder()
+ .add(expectedStackTrace)
+ // TODO(b/124483578): Stack trace lines from the merging of equivalent
+ // constructors should retrace to the set of lines from each of the
+ // individual source constructors.
+ .map(
+ 1, stackTraceLine -> stackTraceLine.builderOf().setLineNumber(-1).build())
+ .build();
+ assertThat(stackTrace, isSame(expectedStackTraceWithMergedConstructor));
assertThat(codeInspector.clazz(B.class), not(isPresent()));
- checkRetracedStackTrace(getUnxpectedStackTrace(), stackTrace);
});
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonFinalOverrideOfFinalMethodNonTrivialMergeTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonFinalOverrideOfFinalMethodNonTrivialMergeTest.java
index 625af3f..478958e 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonFinalOverrideOfFinalMethodNonTrivialMergeTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonFinalOverrideOfFinalMethodNonTrivialMergeTest.java
@@ -47,7 +47,7 @@
ClassSubject classSubject = inspector.clazz(A.class);
assertThat(classSubject, isPresent());
- MethodSubject methodSubject = getUniqueDispatchBridgeMethod(classSubject);
+ MethodSubject methodSubject = classSubject.uniqueMethodWithOriginalName("foo$bridge");
assertThat(methodSubject, isPresent());
assertFalse(methodSubject.isFinal());
})
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonPublicOverrideOfPublicMethodAfterClassMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonPublicOverrideOfPublicMethodAfterClassMergingTest.java
index 33a04c3..1edbf47 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NonPublicOverrideOfPublicMethodAfterClassMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NonPublicOverrideOfPublicMethodAfterClassMergingTest.java
@@ -59,8 +59,7 @@
ClassSubject iClassSubject = inspector.clazz(I.class);
assertThat(iClassSubject, isPresent());
assertThat(
- iClassSubject.uniqueMethodThatMatches(m -> !m.isInstanceInitializer()),
- allOf(isPresent(), isPublic()));
+ iClassSubject.uniqueMethodWithOriginalName("m"), allOf(isPresent(), isPublic()));
ClassSubject aClassSubject = inspector.clazz(A.class);
assertThat(aClassSubject, isPresent());
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/StrictMethodMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/StrictMethodMergingTest.java
index 834f76d..0b644b8 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/StrictMethodMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/StrictMethodMergingTest.java
@@ -47,7 +47,7 @@
assertThat(aClassSubject, isPresent());
MethodSubject synchronizedMethodSubject =
- getUniqueDispatchBridgeMethod(aClassSubject);
+ aClassSubject.uniqueMethodWithOriginalName("m$bridge");
assertThat(synchronizedMethodSubject, isPresent());
assertTrue(synchronizedMethodSubject.getAccessFlags().isStrict());
@@ -55,7 +55,7 @@
assertThat(cClassSubject, isPresent());
MethodSubject unsynchronizedMethodSubject =
- getUniqueDispatchBridgeMethod(cClassSubject);
+ cClassSubject.uniqueMethodWithOriginalName("m$bridge");
assertThat(unsynchronizedMethodSubject, isPresent());
assertFalse(unsynchronizedMethodSubject.getAccessFlags().isStrict());
})
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedMethodMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedMethodMergingTest.java
index 9eeea86..dd93d69 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedMethodMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/SynchronizedMethodMergingTest.java
@@ -47,7 +47,7 @@
assertThat(aClassSubject, isPresent());
MethodSubject synchronizedMethodSubject =
- getUniqueDispatchBridgeMethod(aClassSubject);
+ aClassSubject.uniqueMethodWithOriginalName("m$bridge");
assertThat(synchronizedMethodSubject, isPresent());
assertTrue(synchronizedMethodSubject.isSynchronized());
@@ -55,7 +55,7 @@
assertThat(cClassSubject, isPresent());
MethodSubject unsynchronizedMethodSubject =
- getUniqueDispatchBridgeMethod(cClassSubject);
+ cClassSubject.uniqueMethodWithOriginalName("m$bridge");
assertThat(unsynchronizedMethodSubject, isPresent());
assertFalse(unsynchronizedMethodSubject.isSynchronized());
})
diff --git a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java
index 29d8d11..851d489 100644
--- a/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/lambdas/LambdaInStacktraceTest.java
@@ -32,6 +32,7 @@
"lambda$main$1(" + fileName + ")",
"main(" + fileName + ")");
+ // TODO(b/187491007): The "call" frame should have a file name.
static final String EXPECTED_D8 =
StringUtils.lines(
"getStacktraceWithFileNames(" + fileName + ")",
@@ -43,6 +44,17 @@
"call(D8$$SyntheticClass)",
"main(" + fileName + ")");
+ static final String EXPECTED_D8_ANDROID_O =
+ StringUtils.lines(
+ "getStacktraceWithFileNames(" + fileName + ")",
+ "lambda$main$0(" + fileName + ")",
+ "call(NULL)",
+ "main(" + fileName + ")",
+ "getStacktraceWithFileNames(" + fileName + ")",
+ "lambda$main$1(" + fileName + ")",
+ "call(NULL)",
+ "main(" + fileName + ")");
+
private final TestParameters parameters;
private final boolean isAndroidOOrLater;
private final boolean isDalvik;
@@ -76,7 +88,7 @@
.addInnerClasses(LambdaInStacktraceTest.class)
.setMinApi(parameters)
.run(parameters.getRuntime(), TestRunner.class, Boolean.toString(isDalvik))
- .assertSuccessWithOutput(EXPECTED_D8);
+ .assertSuccessWithOutput(isAndroidOOrLater ? EXPECTED_D8_ANDROID_O : EXPECTED_D8);
}
@Test
diff --git a/src/test/java/com/android/tools/r8/lightir/LirBasicCallbackTest.java b/src/test/java/com/android/tools/r8/lightir/LirBasicCallbackTest.java
index a6cc50b..909c083 100644
--- a/src/test/java/com/android/tools/r8/lightir/LirBasicCallbackTest.java
+++ b/src/test/java/com/android/tools/r8/lightir/LirBasicCallbackTest.java
@@ -80,7 +80,7 @@
.dexItemFactory()
.createMethod(Reference.methodFromDescriptor("LFoo;", "bar", "()V"));
LirCode<?> code =
- LirCode.builder(method, false, new ThrowingStrategy(), options)
+ LirCode.builder(method, new ThrowingStrategy(), options)
.setMetadata(IRMetadata.unknown())
.addConstNull()
.addConstInt(42)
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/InvokeSpecialToVirtualMethodProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/InvokeSpecialToVirtualMethodProfileRewritingTest.java
index a1c6307..1f7da5f 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/InvokeSpecialToVirtualMethodProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/InvokeSpecialToVirtualMethodProfileRewritingTest.java
@@ -4,11 +4,10 @@
package com.android.tools.r8.profile.art.completeness;
-import static com.android.tools.r8.synthesis.SyntheticItemsTestUtils.syntheticInvokeSpecialMethod;
-import static com.android.tools.r8.utils.codeinspector.CodeMatchers.isInvokeWithTarget;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -16,15 +15,13 @@
import com.android.tools.r8.profile.art.model.ExternalArtProfile;
import com.android.tools.r8.profile.art.utils.ArtProfileInspector;
import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
import com.android.tools.r8.utils.BooleanBox;
import com.android.tools.r8.utils.InternalOptions.InlinerOptions;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.CodeMatchers;
-import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -107,28 +104,20 @@
private void inspect(ArtProfileInspector profileInspector, CodeInspector inspector)
throws Exception {
- Method mMethod = Main.class.getDeclaredMethod("m");
ClassSubject mainClassSubject = inspector.clazz(Main.class);
assertThat(mainClassSubject, isPresent());
- // Find the two methods named 'm'. Avoid encoding the order and inspect which is the caller.
- List<FoundMethodSubject> methods =
- mainClassSubject.allMethods(
- m -> {
- String originalName = m.getOriginalName();
- return originalName.equals("m")
- || originalName.equals(syntheticInvokeSpecialMethod(mMethod).getMethodName());
- });
- assertEquals(2, methods.size());
- FoundMethodSubject mMethodSubject = methods.get(0);
- FoundMethodSubject mMovedMethodSubject = methods.get(1);
- if (!mMethodSubject
- .streamInstructions()
- .anyMatch(isInvokeWithTarget(mMovedMethodSubject.getFinalReference()))) {
- mMethodSubject = methods.get(1);
- mMovedMethodSubject = methods.get(0);
- }
- assertThat(mMethodSubject, CodeMatchers.invokesMethod(mMovedMethodSubject));
+ MethodSubject mMethodSubject = mainClassSubject.uniqueMethodWithOriginalName("m");
+ assertThat(mMethodSubject, isPresent());
+
+ MethodSubject mMovedMethodSubject =
+ mainClassSubject.method(
+ SyntheticItemsTestUtils.syntheticInvokeSpecialMethod(
+ Main.class.getDeclaredMethod("m")));
+ assertThat(mMovedMethodSubject, isPresent());
+ assertNotEquals(
+ mMethodSubject.getProgramMethod().getName(),
+ mMovedMethodSubject.getProgramMethod().getName());
// Verify residual profile contains private synthetic method when present.
profileInspector
diff --git a/src/test/java/com/android/tools/r8/profile/art/completeness/MovedPrivateInterfaceMethodProfileRewritingTest.java b/src/test/java/com/android/tools/r8/profile/art/completeness/MovedPrivateInterfaceMethodProfileRewritingTest.java
index 82edb64..9d36b97 100644
--- a/src/test/java/com/android/tools/r8/profile/art/completeness/MovedPrivateInterfaceMethodProfileRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/profile/art/completeness/MovedPrivateInterfaceMethodProfileRewritingTest.java
@@ -132,17 +132,11 @@
inspector.clazz(SyntheticItemsTestUtils.syntheticCompanionClass(I.class));
assertThat(companionClassSubject, isPresent());
- String mMethodOnI = typeName(I.class) + ".m";
- String mMethodNameOnICC =
- SyntheticItemsTestUtils.syntheticPrivateInterfaceMethodAsCompanionMethod(
- I.class.getDeclaredMethod("m"))
- .getMethodName();
MethodSubject privateInterfaceMethodSubject =
- companionClassSubject.uniqueMethodThatMatches(
- m -> {
- String originalName = m.getOriginalName();
- return originalName.equals(mMethodOnI) || originalName.equals(mMethodNameOnICC);
- });
+ companionClassSubject.uniqueMethodWithOriginalName(
+ SyntheticItemsTestUtils.syntheticPrivateInterfaceMethodAsCompanionMethod(
+ I.class.getDeclaredMethod("m"))
+ .getMethodName());
assertThat(privateInterfaceMethodSubject, isPresent());
profileInspector
diff --git a/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java b/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java
index 1aaffaf..8ce1d80 100644
--- a/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/NonVirtualOverrideTest.java
@@ -8,7 +8,6 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresentAndRenamed;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
import com.android.tools.r8.ByteDataView;
import com.android.tools.r8.ClassFileConsumer.ArchiveConsumer;
@@ -153,12 +152,10 @@
CodeInspector inspector = compiled.inspector();
ClassSubject classSubject = inspector.clazz(B.class.getName());
assertThat(classSubject, isPresentAndRenamed());
+ assertThat(classSubject.method("void", "m1", ImmutableList.of()), isPresent());
assertThat(classSubject.method("void", "m2", ImmutableList.of()), isAbsent());
assertThat(classSubject.method("void", "m3", ImmutableList.of()), isAbsent());
assertThat(classSubject.method("void", "m4", ImmutableList.of()), isAbsent());
- assertThat(classSubject.uniqueInstanceInitializer(), isPresent());
- // The remaining method is the private method corresponding to m1 to ensure IAE.
- assertEquals(2, classSubject.allMethods().size());
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java
index 2e03043..3f11198 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingSpecificTest.java
@@ -15,17 +15,24 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.diagnostic.MissingDefinitionsDiagnostic;
-import com.android.tools.r8.mappingcompose.ComposeTestHelpers;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
+import java.io.BufferedReader;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+@Ignore("Will be fixed by update in CL 84843")
@RunWith(Parameterized.class)
public class TreeShakingSpecificTest extends TestBase {
@@ -87,36 +94,6 @@
});
}
- private String getExpectedCf() {
- return StringUtils.lines(
- "shaking1.Shaking -> shaking1.Shaking:",
- "# {'id':'sourceFile','fileName':'Shaking.java'}",
- " 1:2:void main(java.lang.String[]):8:9 -> main",
- "shaking1.Used -> a.a:",
- "# {'id':'sourceFile','fileName':'Used.java'}",
- " java.lang.String name -> a",
- " 1:14:void <init>(java.lang.String):0:13 -> <init>",
- " 1:1:java.lang.String method():17:17 -> a",
- " 1:1:java.lang.String aMethodThatIsNotUsedButKept():21:21 "
- + "-> aMethodThatIsNotUsedButKept");
- }
-
- private String getExpectedDex() {
- return StringUtils.lines(
- "shaking1.Shaking -> shaking1.Shaking:",
- "# {'id':'sourceFile','fileName':'Shaking.java'}",
- " 0:6:void main(java.lang.String[]):8:8 -> main",
- " 7:21:void main(java.lang.String[]):9:9 -> main",
- "shaking1.Used -> a.a:",
- "# {'id':'sourceFile','fileName':'Used.java'}",
- " java.lang.String name -> a",
- " 0:2:void <init>(java.lang.String):12:12 -> <init>",
- " 3:5:void <init>(java.lang.String):13:13 -> <init>",
- " 0:16:java.lang.String method():17:17 -> a",
- " 0:2:java.lang.String aMethodThatIsNotUsedButKept():21:21 "
- + "-> aMethodThatIsNotUsedButKept");
- }
-
@Test
public void testPrintMapping() throws Throwable {
// Generate R8 processed version without library option.
@@ -129,20 +106,25 @@
.compile()
.inspectProguardMap(
proguardMap -> {
- // Remove header.
- List<String> lines = StringUtils.splitLines(proguardMap);
- int firstNonHeaderLine = 0;
- for (String line : lines) {
- if (line.startsWith("#")) {
- firstNonHeaderLine++;
- } else {
- break;
- }
- }
- assertEquals(
- backend.isCf() ? getExpectedCf() : getExpectedDex(),
- ComposeTestHelpers.doubleToSingleQuote(
- StringUtils.lines(lines.subList(firstNonHeaderLine, lines.size()))));
+ // Remove comments.
+ String actualMapping =
+ Stream.of(proguardMap.split("\n"))
+ .filter(line -> !line.startsWith("#"))
+ .collect(Collectors.joining("\n"));
+ String refMapping =
+ new String(
+ Files.readAllBytes(
+ Paths.get(
+ EXAMPLES_DIR,
+ "shaking1",
+ "print-mapping-" + StringUtils.toLowerCase(backend.name()) + ".ref")),
+ StandardCharsets.UTF_8);
+ assertEquals(sorted(refMapping), sorted(actualMapping));
});
}
+
+ private static String sorted(String str) {
+ return new BufferedReader(new StringReader(str))
+ .lines().sorted().filter(s -> !s.isEmpty()).collect(Collectors.joining("\n"));
+ }
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index e7146dc..dc0053b 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -696,10 +696,4 @@
System.out.println(processResult.stdout);
return processResult.stdout;
}
-
- public MemberNaming getMethodMappingInfo(DexEncodedMethod dexMethod) {
- return mapping
- .getNaming()
- .lookup(MethodSignature.fromDexMethod(dexMethod.getReference(), false));
- }
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 8cc6ab0..fd18f5a 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -340,8 +340,7 @@
}
Object2IntMap<InstructionSubject> lineNumberTable = new Object2IntOpenHashMap<>();
DexDebugPositionState state =
- new DexDebugPositionState(
- info.startLine, getMethod().getReference(), getMethod().isD8R8Synthesized());
+ new DexDebugPositionState(info.startLine, getMethod().getReference());
Iterator<DexDebugEvent> iterator = Arrays.asList(info.events).iterator();
for (DexInstruction insn : code.instructions) {
int offset = insn.getOffset();
@@ -447,10 +446,4 @@
getDefaultMethodPrefix() + reference.getMethodName(),
p);
}
-
- @Override
- public boolean isCompilerSynthesized() {
- MemberNaming naming = clazz.getMethodMappingInfo(dexMethod);
- return naming.isCompilerSynthesized();
- }
}