Merge "Sort members by renamed name in Proguard map"
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexList.java b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
index 26097c1..fe946da 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexList.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexList.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.MainDexListBuilder;
@@ -41,7 +42,7 @@
AppInfoWithSubtyping appInfo = new AppInfoWithSubtyping(application);
RootSet mainDexRootSet =
new RootSetBuilder(appInfo, application, options.mainDexKeepRules, options).run(executor);
- Enqueuer enqueuer = new Enqueuer(appInfo, options, true);
+ Enqueuer enqueuer = new Enqueuer(appInfo, GraphLense.getIdentityLense(), options, true);
AppInfoWithLiveness mainDexAppInfo = enqueuer.traceMainDex(mainDexRootSet, executor, timing);
// LiveTypes is the result.
Set<DexType> mainDexClasses =
diff --git a/src/main/java/com/android/tools/r8/PrintSeeds.java b/src/main/java/com/android/tools/r8/PrintSeeds.java
index 782c91d..4410d8a 100644
--- a/src/main/java/com/android/tools/r8/PrintSeeds.java
+++ b/src/main/java/com/android/tools/r8/PrintSeeds.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.RootSetBuilder;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
@@ -84,7 +85,7 @@
new RootSetBuilder(
appInfo, application, options.proguardConfiguration.getRules(), options)
.run(executor);
- Enqueuer enqueuer = new Enqueuer(appInfo, options, false);
+ Enqueuer enqueuer = new Enqueuer(appInfo, GraphLense.getIdentityLense(), options, false);
appInfo = enqueuer.traceApplication(rootSet, executor, timing);
RootSetBuilder.writeSeeds(
appInfo.withLiveness(),
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index c03d928..16858af 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -292,6 +292,7 @@
Enqueuer enqueuer =
new Enqueuer(
appView.getAppInfo(),
+ appView.getGraphLense(),
options,
options.forceProguardCompatibility,
compatibility,
@@ -380,10 +381,9 @@
.rewrittenWithLense(application.asDirect(), appView.getGraphLense()));
}
// Collect switch maps and ordinals maps.
+ appViewWithLiveness.setAppInfo(new SwitchMapCollector(appViewWithLiveness, options).run());
appViewWithLiveness.setAppInfo(
- new SwitchMapCollector(appViewWithLiveness.getAppInfo(), options).run());
- appViewWithLiveness.setAppInfo(
- new EnumOrdinalMapCollector(appViewWithLiveness.getAppInfo(), options).run());
+ new EnumOrdinalMapCollector(appViewWithLiveness, options).run());
// TODO(b/79143143): re-enable once fixed.
// graphLense = new BridgeMethodAnalysis(graphLense, appInfo.withLiveness()).run();
@@ -419,7 +419,8 @@
if (!options.mainDexKeepRules.isEmpty()) {
appView.setAppInfo(new AppInfoWithSubtyping(application));
- Enqueuer enqueuer = new Enqueuer(appView.getAppInfo(), options, true);
+ Enqueuer enqueuer =
+ new Enqueuer(appView.getAppInfo(), appView.getGraphLense(), options, true);
// Lets find classes which may have code executed before secondary dex files installation.
RootSet mainDexRootSet =
new RootSetBuilder(appView.getAppInfo(), application, options.mainDexKeepRules, options)
@@ -443,7 +444,11 @@
timing.begin("Post optimization code stripping");
try {
Enqueuer enqueuer =
- new Enqueuer(appView.getAppInfo(), options, options.forceProguardCompatibility);
+ new Enqueuer(
+ appView.getAppInfo(),
+ appView.getGraphLense(),
+ options,
+ options.forceProguardCompatibility);
appView.setAppInfo(enqueuer.traceApplication(rootSet, executorService, timing));
AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
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 776cc42..e41120d 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -201,14 +201,19 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin) {
- return internalBuild(encodedMethod, appInfo, options, null, null, origin);
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin) {
+ return internalBuild(encodedMethod, appInfo, graphLense, options, null, null, origin);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
@@ -216,12 +221,13 @@
assert valueNumberGenerator != null;
assert callerPosition != null;
return internalBuild(
- encodedMethod, appInfo, options, valueNumberGenerator, callerPosition, origin);
+ encodedMethod, appInfo, graphLense, options, valueNumberGenerator, callerPosition, origin);
}
private IRCode internalBuild(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition,
@@ -235,14 +241,11 @@
new CfSourceCode(
this,
encodedMethod,
+ graphLense.getOriginalMethodSignature(encodedMethod.method),
callerPosition,
origin,
options.lineNumberOptimization == LineNumberOptimization.ON);
- IRBuilder builder =
- (generator == null)
- ? new IRBuilder(encodedMethod, appInfo, source, options)
- : new IRBuilder(encodedMethod, appInfo, source, options, generator);
- return builder.build();
+ return new IRBuilder(encodedMethod, appInfo, source, options, generator).build();
}
@Override
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 60a5ef5..0484a63 100644
--- a/src/main/java/com/android/tools/r8/graph/Code.java
+++ b/src/main/java/com/android/tools/r8/graph/Code.java
@@ -17,11 +17,16 @@
public abstract class Code extends CachedHashValueDexItem {
public abstract IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin);
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin);
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
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 b1b5f8a..4a0a483 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -164,10 +164,18 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin) {
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin) {
DexSourceCode source =
new DexSourceCode(
- this, encodedMethod, null, options.lineNumberOptimization == LineNumberOptimization.ON);
+ this,
+ encodedMethod,
+ graphLense.getOriginalMethodSignature(encodedMethod.method),
+ null,
+ options.lineNumberOptimization == LineNumberOptimization.ON);
IRBuilder builder = new IRBuilder(encodedMethod, appInfo, source, options);
return builder.build();
}
@@ -176,6 +184,7 @@
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
@@ -184,6 +193,7 @@
new DexSourceCode(
this,
encodedMethod,
+ graphLense.getOriginalMethodSignature(encodedMethod.method),
callerPosition,
options.lineNumberOptimization == LineNumberOptimization.ON);
IRBuilder builder =
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 a6032e4..cf1a105 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -252,23 +252,26 @@
compilationState = CompilationState.NOT_PROCESSED;
}
- public IRCode buildIR(AppInfo appInfo, InternalOptions options, Origin origin) {
- return code == null ? null : code.buildIR(this, appInfo, options, origin);
+ public IRCode buildIR(
+ AppInfo appInfo, GraphLense graphLense, InternalOptions options, Origin origin) {
+ return code == null ? null : code.buildIR(this, appInfo, graphLense, options, origin);
}
public IRCode buildInliningIRForTesting(
InternalOptions options, ValueNumberGenerator valueNumberGenerator) {
- return buildInliningIR(null, options, valueNumberGenerator, null, Origin.unknown());
+ return buildInliningIR(
+ null, GraphLense.getIdentityLense(), options, valueNumberGenerator, null, Origin.unknown());
}
public IRCode buildInliningIR(
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
return code.buildInliningIR(
- this, appInfo, options, valueNumberGenerator, callerPosition, origin);
+ this, appInfo, graphLense, options, valueNumberGenerator, callerPosition, origin);
}
public void setCode(Code code) {
diff --git a/src/main/java/com/android/tools/r8/graph/JarCode.java b/src/main/java/com/android/tools/r8/graph/JarCode.java
index a48841f..28143ad 100644
--- a/src/main/java/com/android/tools/r8/graph/JarCode.java
+++ b/src/main/java/com/android/tools/r8/graph/JarCode.java
@@ -108,17 +108,22 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin) {
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin) {
triggerDelayedParsingIfNeccessary();
return options.debug
- ? internalBuildWithLocals(encodedMethod, appInfo, options, null, null)
- : internalBuild(encodedMethod, appInfo, options, null, null);
+ ? internalBuildWithLocals(encodedMethod, appInfo, graphLense, options, null, null)
+ : internalBuild(encodedMethod, appInfo, graphLense, options, null, null);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition,
@@ -126,41 +131,45 @@
assert generator != null;
triggerDelayedParsingIfNeccessary();
return options.debug
- ? internalBuildWithLocals(encodedMethod, appInfo, options, generator, callerPosition)
- : internalBuild(encodedMethod, appInfo, options, generator, callerPosition);
+ ? internalBuildWithLocals(
+ encodedMethod, appInfo, graphLense, options, generator, callerPosition)
+ : internalBuild(encodedMethod, appInfo, graphLense, options, generator, callerPosition);
}
private IRCode internalBuildWithLocals(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition) {
try {
- return internalBuild(encodedMethod, appInfo, options, generator, callerPosition);
+ return internalBuild(encodedMethod, appInfo, graphLense, options, generator, callerPosition);
} catch (InvalidDebugInfoException e) {
options.warningInvalidDebugInfo(encodedMethod, origin, e);
node.localVariables.clear();
- return internalBuild(encodedMethod, appInfo, options, generator, callerPosition);
+ return internalBuild(encodedMethod, appInfo, graphLense, options, generator, callerPosition);
}
}
private IRCode internalBuild(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator generator,
Position callerPosition) {
if (!options.debug) {
node.localVariables.clear();
}
- JarSourceCode source = new JarSourceCode(
- method.getHolder(), node, application, encodedMethod.method, callerPosition);
- IRBuilder builder =
- (generator == null)
- ? new IRBuilder(encodedMethod, appInfo, source, options)
- : new IRBuilder(encodedMethod, appInfo, source, options, generator);
- return builder.build();
+ JarSourceCode source =
+ new JarSourceCode(
+ method.getHolder(),
+ node,
+ application,
+ graphLense.getOriginalMethodSignature(encodedMethod.method),
+ callerPosition);
+ return new IRBuilder(encodedMethod, appInfo, source, options, generator).build();
}
@Override
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 afc2969..b6eb879 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -175,20 +175,32 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin) {
- return asCfCode().buildIR(encodedMethod, appInfo, options, origin);
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin) {
+ return asCfCode().buildIR(encodedMethod, appInfo, graphLense, options, origin);
}
@Override
public IRCode buildInliningIR(
DexEncodedMethod encodedMethod,
AppInfo appInfo,
+ GraphLense graphLense,
InternalOptions options,
ValueNumberGenerator valueNumberGenerator,
Position callerPosition,
Origin origin) {
- return asCfCode().buildInliningIR(
- encodedMethod, appInfo, options, valueNumberGenerator, callerPosition, origin);
+ return asCfCode()
+ .buildInliningIR(
+ encodedMethod,
+ appInfo,
+ graphLense,
+ options,
+ valueNumberGenerator,
+ callerPosition,
+ origin);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index f5b0a31..35ce779 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -76,6 +76,7 @@
private final Int2ReferenceMap<DebugLocalInfo> emittedLocals = new Int2ReferenceOpenHashMap<>();
private Int2ReferenceMap<DebugLocalInfo> pendingLocals = null;
private boolean pendingLocalChanges = false;
+ private BasicBlock pendingFrame = null;
private final List<LocalVariableInfo> localVariablesTable = new ArrayList<>();
private final Int2ReferenceMap<LocalVariableInfo> openLocalVariables =
@@ -259,7 +260,6 @@
BasicBlock block = blockIterator.next();
CfLabel tryCatchStart = null;
CatchHandlers<BasicBlock> tryCatchHandlers = CatchHandlers.EMPTY_BASIC_BLOCK;
- BasicBlock pendingFrame = null;
boolean previousFallthrough = false;
do {
assert stack.isEmpty();
@@ -286,17 +286,6 @@
pendingFrame = block;
emitLabel(getLabel(block));
}
- if (pendingFrame != null) {
- boolean advancesPC = hasMaterializingInstructions(block, nextBlock);
- // If block has no materializing instructions, then we postpone emitting the frame
- // until the next block. In this case, nextBlock must be non-null
- // (or we would fall off the edge of the method).
- assert advancesPC || nextBlock != null;
- if (advancesPC) {
- addFrame(pendingFrame, Collections.emptyList());
- pendingFrame = null;
- }
- }
JumpInstruction exit = block.exit();
boolean fallthrough =
(exit.isGoto() && exit.asGoto().getTarget() == nextBlock)
@@ -308,7 +297,7 @@
pendingLocals = new Int2ReferenceOpenHashMap<>(locals);
pendingLocalChanges = true;
}
- buildCfInstructions(block, fallthrough, stack);
+ buildCfInstructions(block, nextBlock, fallthrough, stack);
block = nextBlock;
previousFallthrough = fallthrough;
} while (block != null);
@@ -346,7 +335,19 @@
return false;
}
- private void buildCfInstructions(BasicBlock block, boolean fallthrough, Stack stack) {
+ private void buildCfInstructions(
+ BasicBlock block, BasicBlock nextBlock, boolean fallthrough, Stack stack) {
+ if (pendingFrame != null) {
+ boolean advancesPC = hasMaterializingInstructions(block, nextBlock);
+ // If block has no materializing instructions, then we postpone emitting the frame
+ // until the next block. In this case, nextBlock must be non-null
+ // (or we would fall off the edge of the method).
+ assert advancesPC || nextBlock != null;
+ if (advancesPC) {
+ addFrame(pendingFrame, Collections.emptyList());
+ pendingFrame = null;
+ }
+ }
InstructionIterator it = block.iterator();
while (it.hasNext()) {
Instruction instruction = it.next();
@@ -394,30 +395,7 @@
}
CfLabel label = ensureLabel();
if (didLocalsChange) {
- Int2ReferenceSortedMap<DebugLocalInfo> ending =
- DebugLocalInfo.endingLocals(emittedLocals, pendingLocals);
- Int2ReferenceSortedMap<DebugLocalInfo> starting =
- DebugLocalInfo.startingLocals(emittedLocals, pendingLocals);
- assert !ending.isEmpty() || !starting.isEmpty();
- for (Entry<DebugLocalInfo> entry : ending.int2ReferenceEntrySet()) {
- int localIndex = entry.getIntKey();
- LocalVariableInfo info = openLocalVariables.remove(localIndex);
- info.setEnd(label);
- localVariablesTable.add(info);
- DebugLocalInfo removed = emittedLocals.remove(localIndex);
- assert removed == entry.getValue();
- }
- if (!starting.isEmpty()) {
- for (Entry<DebugLocalInfo> entry : starting.int2ReferenceEntrySet()) {
- int localIndex = entry.getIntKey();
- assert !emittedLocals.containsKey(localIndex);
- assert !openLocalVariables.containsKey(localIndex);
- openLocalVariables.put(
- localIndex, new LocalVariableInfo(localIndex, entry.getValue(), label));
- emittedLocals.put(localIndex, entry.getValue());
- }
- }
- pendingLocalChanges = false;
+ updateLocals(label);
}
if (didPositionChange) {
add(new CfPosition(label, position));
@@ -425,6 +403,33 @@
}
}
+ private void updateLocals(CfLabel label) {
+ Int2ReferenceSortedMap<DebugLocalInfo> ending =
+ DebugLocalInfo.endingLocals(emittedLocals, pendingLocals);
+ Int2ReferenceSortedMap<DebugLocalInfo> starting =
+ DebugLocalInfo.startingLocals(emittedLocals, pendingLocals);
+ assert !ending.isEmpty() || !starting.isEmpty();
+ for (Entry<DebugLocalInfo> entry : ending.int2ReferenceEntrySet()) {
+ int localIndex = entry.getIntKey();
+ LocalVariableInfo info = openLocalVariables.remove(localIndex);
+ info.setEnd(label);
+ localVariablesTable.add(info);
+ DebugLocalInfo removed = emittedLocals.remove(localIndex);
+ assert removed == entry.getValue();
+ }
+ if (!starting.isEmpty()) {
+ for (Entry<DebugLocalInfo> entry : starting.int2ReferenceEntrySet()) {
+ int localIndex = entry.getIntKey();
+ assert !emittedLocals.containsKey(localIndex);
+ assert !openLocalVariables.containsKey(localIndex);
+ openLocalVariables.put(
+ localIndex, new LocalVariableInfo(localIndex, entry.getValue(), label));
+ emittedLocals.put(localIndex, entry.getValue());
+ }
+ }
+ pendingLocalChanges = false;
+ }
+
private boolean localsChanged() {
if (!pendingLocalChanges) {
return false;
@@ -461,11 +466,25 @@
Collection<Value> locals = registerAllocator.getLocalsAtBlockEntry(block);
Int2ReferenceSortedMap<FrameType> mapping = new Int2ReferenceAVLTreeMap<>();
-
for (Value local : locals) {
mapping.put(getLocalRegister(local), getFrameType(block, local));
}
- instructions.add(new CfFrame(mapping, stackTypes));
+ CfFrame frame = new CfFrame(mapping, stackTypes);
+
+ // Make sure to end locals on this transition before the synthetic CfFrame instruction.
+ // Otherwise we might extend the live range of a local across a CfFrame instruction that
+ // the local is not live across. For example if we have a return followed by a move exception
+ // where the locals end. Inserting a CfFrame instruction between the return and the move
+ // exception without ending the locals will lead to having the local alive on the CfFrame
+ // instruction which is not correct and will cause us to not be able to build IR from the
+ // CfCode.
+ boolean didLocalsChange = localsChanged();
+ if (didLocalsChange) {
+ CfLabel label = ensureLabel();
+ updateLocals(label);
+ }
+
+ instructions.add(frame);
}
private FrameType getFrameType(BasicBlock liveBlock, Value local) {
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 bc2222f..7892afb 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
@@ -20,6 +20,7 @@
import com.android.tools.r8.graph.DebugLocalInfo;
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.ir.code.CanonicalPositions;
import com.android.tools.r8.ir.code.CatchHandlers;
@@ -199,6 +200,7 @@
public CfSourceCode(
CfCode code,
DexEncodedMethod method,
+ DexMethod originalMethod,
Position callerPosition,
Origin origin,
boolean preserveCaller) {
@@ -217,7 +219,7 @@
}
this.state = new CfState(origin);
canonicalPositions =
- new CanonicalPositions(callerPosition, preserveCaller, cfPositionCount, this.method.method);
+ new CanonicalPositions(callerPosition, preserveCaller, cfPositionCount, originalMethod);
}
@Override
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 10bf6a5..94516a2 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
@@ -75,26 +75,30 @@
private List<DexDebugEntry> debugEntries = null;
// In case of inlining the position of the invoke in the caller.
- private final DexMethod method;
+ private final DexMethod originalMethod;
public DexSourceCode(
- DexCode code, DexEncodedMethod method, Position callerPosition, boolean preserveCaller) {
+ DexCode code,
+ DexEncodedMethod method,
+ DexMethod originalMethod,
+ Position callerPosition,
+ boolean preserveCaller) {
this.code = code;
this.proto = method.method.proto;
this.accessFlags = method.accessFlags;
- this.method = method.method;
+ this.originalMethod = originalMethod;
argumentTypes = computeArgumentTypes();
DexDebugInfo info = code.getDebugInfo();
if (info != null) {
- debugEntries = info.computeEntries(method.method);
+ debugEntries = info.computeEntries(originalMethod);
}
canonicalPositions =
new CanonicalPositions(
callerPosition,
preserveCaller,
debugEntries == null ? 0 : debugEntries.size(),
- this.method);
+ originalMethod);
}
@Override
@@ -253,7 +257,7 @@
private Position getCanonicalPositionAppendCaller(DexDebugEntry entry) {
// If this instruction has already been inlined then this.method must be the outermost caller.
assert entry.callerPosition == null
- || entry.callerPosition.getOutermostCaller().method == method;
+ || entry.callerPosition.getOutermostCaller().method == originalMethod;
return canonicalPositions.getCanonical(
new Position(
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 62450d4..98b4502 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -329,19 +329,23 @@
// Flag indicating if the instructions define values with imprecise types.
private boolean hasImpreciseInstructionOutValueTypes = false;
- public IRBuilder(DexEncodedMethod method, AppInfo appInfo,
- SourceCode source, InternalOptions options) {
+ public IRBuilder(
+ DexEncodedMethod method, AppInfo appInfo, SourceCode source, InternalOptions options) {
this(method, appInfo, source, options, new ValueNumberGenerator());
}
public IRBuilder(
- DexEncodedMethod method, AppInfo appInfo, SourceCode source,
- InternalOptions options, ValueNumberGenerator valueNumberGenerator) {
+ DexEncodedMethod method,
+ AppInfo appInfo,
+ SourceCode source,
+ InternalOptions options,
+ ValueNumberGenerator valueNumberGenerator) {
assert source != null;
this.method = method;
this.appInfo = appInfo;
this.source = source;
- this.valueNumberGenerator = valueNumberGenerator;
+ this.valueNumberGenerator =
+ valueNumberGenerator != null ? valueNumberGenerator : new ValueNumberGenerator();
this.options = options;
}
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 00c3754..f523b46 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
@@ -495,7 +495,8 @@
executorService.submit(
() -> {
IRCode code =
- method.buildIR(appInfo, options, appInfo.originFor(method.method.holder));
+ method.buildIR(
+ appInfo, graphLense, options, appInfo.originFor(method.method.holder));
assert code != null;
assert !method.getCode().isOutlineCode();
// Instead of repeating all the optimizations of rewriteCode(), only run the
@@ -637,7 +638,8 @@
feedback.markProcessed(method, ConstraintWithTarget.NEVER);
return;
}
- IRCode code = method.buildIR(appInfo, options, appInfo.originFor(method.method.holder));
+ IRCode code =
+ method.buildIR(appInfo, graphLense, options, appInfo.originFor(method.method.holder));
if (code == null) {
feedback.markProcessed(method, ConstraintWithTarget.NEVER);
return;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
index 1170dab..85a0f99 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/JarSourceCode.java
@@ -187,20 +187,20 @@
// Cooked position to indicate positions in synthesized code (ie, for synchronization).
private Position syntheticPosition = null;
- private final DexMethod method;
+ private final DexMethod originalMethod;
private final Position callerPosition;
public JarSourceCode(
DexType clazz,
MethodNode node,
JarApplicationReader application,
- DexMethod method,
+ DexMethod originalMethod,
Position callerPosition) {
assert node != null;
assert node.desc != null;
this.node = node;
this.application = application;
- this.method = method;
+ this.originalMethod = originalMethod;
this.clazz = clazz;
this.callerPosition = callerPosition;
parameterTypes = Arrays.asList(application.getArgumentTypes(node.desc));
@@ -2862,12 +2862,12 @@
private Position getCanonicalPosition(int line) {
return canonicalPositions.computeIfAbsent(
- line, l -> new Position(l, null, method, callerPosition));
+ line, l -> new Position(l, null, originalMethod, callerPosition));
}
private Position getPreamblePosition() {
if (preamblePosition == null) {
- preamblePosition = Position.synthetic(0, method, null);
+ preamblePosition = Position.synthetic(0, originalMethod, null);
}
return preamblePosition;
}
@@ -2891,8 +2891,8 @@
}
syntheticPosition =
(min == Integer.MAX_VALUE)
- ? Position.noneWithMethod(method, callerPosition)
- : Position.synthetic(min < max ? min - 1 : min, method, callerPosition);
+ ? Position.noneWithMethod(originalMethod, callerPosition)
+ : Position.synthetic(min < max ? min - 1 : min, originalMethod, callerPosition);
}
return syntheticPosition;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
index 1b68f7d..e23b534 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
@@ -3,10 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionIterator;
@@ -30,12 +32,14 @@
public class EnumOrdinalMapCollector {
private final AppInfoWithLiveness appInfo;
+ private final GraphLense graphLense;
private final InternalOptions options;
private final Map<DexType, Reference2IntMap<DexField>> ordinalsMaps = new IdentityHashMap<>();
- public EnumOrdinalMapCollector(AppInfoWithLiveness appInfo, InternalOptions options) {
- this.appInfo = appInfo;
+ public EnumOrdinalMapCollector(AppView<AppInfoWithLiveness> appView, InternalOptions options) {
+ this.appInfo = appView.getAppInfo();
+ this.graphLense = appView.getGraphLense();
this.options = options;
}
@@ -55,7 +59,8 @@
return;
}
DexEncodedMethod initializer = clazz.getClassInitializer();
- IRCode code = initializer.getCode().buildIR(initializer, appInfo, options, clazz.origin);
+ IRCode code =
+ initializer.getCode().buildIR(initializer, appInfo, graphLense, options, clazz.origin);
Reference2IntMap<DexField> ordinalsMap = new Reference2IntArrayMap<>();
ordinalsMap.defaultReturnValue(-1);
InstructionIterator it = code.instructionIterator();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 7ea7379..12baa2c 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -409,7 +409,8 @@
Position callerPosition) {
// Build the IR for a yet not processed method, and perform minimal IR processing.
Origin origin = appInfo.originFor(target.method.holder);
- IRCode code = target.buildInliningIR(appInfo, options, generator, callerPosition, origin);
+ IRCode code =
+ target.buildInliningIR(appInfo, graphLense, options, generator, callerPosition, origin);
if (!target.isProcessed()) {
new LensCodeRewriter(graphLense, appInfo).rewrite(code, target);
}
@@ -586,7 +587,8 @@
invokePosition = Position.noneWithMethod(method.method, null);
}
assert invokePosition.callerPosition == null
- || invokePosition.getOutermostCaller().method == method.method;
+ || invokePosition.getOutermostCaller().method
+ == graphLense.getOriginalMethodSignature(method.method);
IRCode inlinee =
result.buildInliningIR(
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 505d192..5f8fd6b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -20,6 +20,7 @@
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.graph.UseRegistry;
@@ -1164,10 +1165,13 @@
@Override
public IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin) {
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin) {
OutlineSourceCode source = new OutlineSourceCode(outline);
- IRBuilder builder = new IRBuilder(encodedMethod, appInfo, source, options);
- return builder.build();
+ return new IRBuilder(encodedMethod, appInfo, source, options).build();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
index a586355..c2fbc9e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
@@ -3,12 +3,14 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionIterator;
@@ -61,14 +63,16 @@
public class SwitchMapCollector {
private final AppInfoWithLiveness appInfo;
+ private final GraphLense graphLense;
private final InternalOptions options;
private final DexString switchMapPrefix;
private final DexType intArrayType;
private final Map<DexField, Int2ReferenceMap<DexField>> switchMaps = new IdentityHashMap<>();
- public SwitchMapCollector(AppInfoWithLiveness appInfo, InternalOptions options) {
- this.appInfo = appInfo;
+ public SwitchMapCollector(AppView<AppInfoWithLiveness> appView, InternalOptions options) {
+ this.appInfo = appView.getAppInfo();
+ this.graphLense = appView.getGraphLense();
this.options = options;
switchMapPrefix = appInfo.dexItemFactory.createString("$SwitchMap$");
intArrayType = appInfo.dexItemFactory.createType("[I");
@@ -92,7 +96,8 @@
List<DexEncodedField> switchMapFields = Arrays.stream(clazz.staticFields())
.filter(this::maybeIsSwitchMap).collect(Collectors.toList());
if (!switchMapFields.isEmpty()) {
- IRCode initializer = clazz.getClassInitializer().buildIR(appInfo, options, clazz.origin);
+ IRCode initializer =
+ clazz.getClassInitializer().buildIR(appInfo, graphLense, options, clazz.origin);
switchMapFields.forEach(field -> extractSwitchMap(field, initializer));
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
index 7835da2..aa6be96 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SynthesizedCode.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.UseRegistry;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Position;
@@ -47,16 +48,27 @@
@Override
public final IRCode buildIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options, Origin origin) {
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ Origin origin) {
return new IRBuilder(encodedMethod, appInfo, sourceCodeProvider.get(), options).build();
}
@Override
public IRCode buildInliningIR(
- DexEncodedMethod encodedMethod, AppInfo appInfo, InternalOptions options,
- ValueNumberGenerator valueNumberGenerator, Position callerPosition, Origin origin) {
- return new IRBuilder(encodedMethod, appInfo,
- sourceCodeProvider.get(), options, valueNumberGenerator).build();
+ DexEncodedMethod encodedMethod,
+ AppInfo appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
+ ValueNumberGenerator valueNumberGenerator,
+ Position callerPosition,
+ Origin origin) {
+ IRBuilder builder =
+ new IRBuilder(
+ encodedMethod, appInfo, sourceCodeProvider.get(), options, valueNumberGenerator);
+ return builder.build();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 6a12b60..bcd489e 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -94,6 +94,7 @@
private boolean tracingMainDex = false;
private final AppInfoWithSubtyping appInfo;
+ private final GraphLense graphLense;
private final InternalOptions options;
private RootSet rootSet;
@@ -218,15 +219,23 @@
*/
private final ProguardConfiguration.Builder compatibility;
- public Enqueuer(AppInfoWithSubtyping appInfo, InternalOptions options,
+ public Enqueuer(
+ AppInfoWithSubtyping appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
boolean forceProguardCompatibility) {
- this(appInfo, options, forceProguardCompatibility, null, null);
+ this(appInfo, graphLense, options, forceProguardCompatibility, null, null);
}
- public Enqueuer(AppInfoWithSubtyping appInfo, InternalOptions options,
+ public Enqueuer(
+ AppInfoWithSubtyping appInfo,
+ GraphLense graphLense,
+ InternalOptions options,
boolean forceProguardCompatibility,
- ProguardConfiguration.Builder compatibility, ProtoLiteExtension protoLiteExtension) {
+ ProguardConfiguration.Builder compatibility,
+ ProtoLiteExtension protoLiteExtension) {
this.appInfo = appInfo;
+ this.graphLense = graphLense;
this.compatibility = compatibility;
this.options = options;
this.protoLiteExtension = protoLiteExtension;
@@ -1478,7 +1487,7 @@
private void handleProguardReflectiveBehavior(DexEncodedMethod method) {
DexType originHolder = method.method.holder;
Origin origin = appInfo.originFor(originHolder);
- IRCode code = method.buildIR(appInfo, options, origin);
+ IRCode code = method.buildIR(appInfo, graphLense, options, origin);
code.instructionIterator().forEachRemaining(instr ->
handleProguardReflectiveBehavior(instr, originHolder));
}
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
index 59bd91b..a329513 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/NullabilityTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.ArrayGet;
import com.android.tools.r8.ir.code.IRCode;
@@ -58,7 +59,8 @@
AppInfo appInfo = new AppInfo(dexApplication);
CodeInspector codeInspector = new CodeInspector(appInfo.app);
DexEncodedMethod foo = codeInspector.clazz(mainClass.getName()).method(signature).getMethod();
- IRCode irCode = foo.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ foo.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
NonNullTracker nonNullTracker = new NonNullTracker();
nonNullTracker.addNonNull(irCode);
TypeAnalysis analysis = new TypeAnalysis(appInfo, foo, irCode);
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
index d3efebe..9c1214c 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/TypeAnalysisTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.ArrayLength;
import com.android.tools.r8.ir.code.CheckCast;
import com.android.tools.r8.ir.code.ConstString;
@@ -122,7 +123,8 @@
.method(
new MethodSignature("subtractConstants8bitRegisters", "int", ImmutableList.of()))
.getMethod();
- IRCode irCode = subtract.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ subtract.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, subtract, irCode);
analysis.forEach((v, l) -> {
assertEither(l, PRIMITIVE, NULL, TOP);
@@ -136,7 +138,8 @@
inspector.clazz("Test")
.method(new MethodSignature("fibonacci", "int", ImmutableList.of("int")))
.getMethod();
- IRCode irCode = fib.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ fib.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, fib, irCode);
analysis.forEach((v, l) -> {
assertEither(l, PRIMITIVE, NULL);
@@ -150,7 +153,8 @@
inspector.clazz("Test")
.method(new MethodSignature("test1", "int[]", ImmutableList.of()))
.getMethod();
- IRCode irCode = test1.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ test1.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, test1, irCode);
Value array = null;
InstructionIterator iterator = irCode.instructionIterator();
@@ -181,7 +185,8 @@
inspector.clazz("Test")
.method(new MethodSignature("test4", "int[]", ImmutableList.of()))
.getMethod();
- IRCode irCode = test4.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ test4.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, test4, irCode);
Value array = null;
InstructionIterator iterator = irCode.instructionIterator();
@@ -212,7 +217,8 @@
inspector.clazz("Test")
.method(new MethodSignature("loop2", "void", ImmutableList.of()))
.getMethod();
- IRCode irCode = loop2.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ loop2.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, loop2, irCode);
analysis.forEach((v, l) -> {
if (l.isClassTypeLatticeElement()) {
@@ -231,7 +237,8 @@
inspector.clazz("Test")
.method(new MethodSignature("test2_throw", "int", ImmutableList.of()))
.getMethod();
- IRCode irCode = test2.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ test2.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, test2, irCode);
analysis.forEach((v, l) -> {
if (l.isClassTypeLatticeElement()) {
@@ -257,7 +264,8 @@
ConstString.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, false),
CheckCast.class, new ClassTypeLatticeElement(test, true),
NewInstance.class, new ClassTypeLatticeElement(test, false));
- IRCode irCode = method.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ method.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, method, irCode);
analysis.forEach((v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
}
@@ -275,7 +283,8 @@
ConstString.class, new ClassTypeLatticeElement(appInfo.dexItemFactory.stringType, false),
InstanceOf.class, PRIMITIVE,
StaticGet.class, new ClassTypeLatticeElement(test, true));
- IRCode irCode = method.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ method.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
TypeAnalysis analysis = new TypeAnalysis(appInfo, method, irCode);
analysis.forEach((v, l) -> verifyTypeEnvironment(expectedLattices, v, l));
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java
index 9993b68..b1647cc 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/NonNullTrackerTest.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
@@ -48,7 +49,8 @@
AppInfo appInfo = new AppInfo(dexApplication);
CodeInspector codeInspector = new CodeInspector(appInfo.app);
DexEncodedMethod foo = codeInspector.clazz(testClass.getName()).method(signature).getMethod();
- IRCode irCode = foo.buildIR(appInfo, TEST_OPTIONS, Origin.unknown());
+ IRCode irCode =
+ foo.buildIR(appInfo, GraphLense.getIdentityLense(), TEST_OPTIONS, Origin.unknown());
checkCountOfNonNull(irCode, 0);
NonNullTracker nonNullTracker = new NonNullTracker();
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index fc41672..0df78bc 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -38,6 +38,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DirectMappedDexApplication;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.ir.code.CatchHandlers;
@@ -650,7 +651,8 @@
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
code);
- IRCode ir = code.buildIR(method, null, options, Origin.unknown());
+ IRCode ir =
+ code.buildIR(method, null, GraphLense.getIdentityLense(), options, Origin.unknown());
RegisterAllocator allocator = new LinearScanRegisterAllocator(ir, options);
method.setCode(ir, allocator, options);
directMethods[i] = method;
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index 5cc07a4..ed95627 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -84,7 +84,9 @@
new RootSetBuilder(appInfo, program, configuration.getRules(), options).run(executor);
}
- Enqueuer enqueuer = new Enqueuer(appInfo, options, options.forceProguardCompatibility);
+ Enqueuer enqueuer =
+ new Enqueuer(
+ appInfo, GraphLense.getIdentityLense(), options, options.forceProguardCompatibility);
appInfo = enqueuer.traceApplication(rootSet, executor, timing);
return new Minifier(appInfo.withLiveness(), rootSet, options).run(timing);
}
diff --git a/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java b/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
index 3421cfe..911ceb7 100644
--- a/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
+++ b/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
@@ -7,6 +7,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
@@ -16,10 +17,25 @@
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class Regress69825683Test extends TestBase {
+ private Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public Regress69825683Test(Backend backend) {
+ this.backend = backend;
+ }
@Test
public void outerConstructsInner() throws Exception {
@@ -32,9 +48,18 @@
"}",
"-dontobfuscate"),
Origin.unknown());
- builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+ if (backend == Backend.DEX) {
+ builder
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+ } else {
+ assert backend == Backend.CF;
+ builder
+ .setProgramConsumer(ClassFileConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getJava8RuntimeJar());
+ }
AndroidApp app = ToolHelper.runR8(builder.build(), o -> o.enableClassInlining = false);
- CodeInspector inspector = new CodeInspector(app);
+ CodeInspector inspector = new CodeInspector(app, o -> o.enableCfFrontend = true);
List<FoundClassSubject> classes = inspector.allClasses();
// Check that the synthetic class is still present.
@@ -51,7 +76,9 @@
String innerName = innerClass.getCanonicalName();
int index = innerName.lastIndexOf('.');
innerName = innerName.substring(0, index) + "$" + innerName.substring(index + 1);
- assertTrue(runOnArt(app, mainClass).startsWith(innerName));
+ assertTrue(
+ (backend == Backend.DEX ? runOnArt(app, mainClass) : runOnJava(app, mainClass))
+ .startsWith(innerName));
}
@Test
@@ -65,9 +92,18 @@
"}",
"-dontobfuscate"),
Origin.unknown());
- builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+ if (backend == Backend.DEX) {
+ builder
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+ } else {
+ assert backend == Backend.CF;
+ builder
+ .setProgramConsumer(ClassFileConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getJava8RuntimeJar());
+ }
AndroidApp app = ToolHelper.runR8(builder.build(), o -> o.enableClassInlining = false);
- CodeInspector inspector = new CodeInspector(app);
+ CodeInspector inspector = new CodeInspector(app, o -> o.enableCfFrontend = true);
List<FoundClassSubject> classes = inspector.allClasses();
// Check that the synthetic class is still present.
@@ -79,6 +115,8 @@
.count());
// Run code to check that the constructor with synthetic class as argument is present.
- assertTrue(runOnArt(app, mainClass).startsWith(mainClass.getCanonicalName()));
+ assertTrue(
+ (backend == Backend.DEX ? runOnArt(app, mainClass) : runOnJava(app, mainClass))
+ .startsWith(mainClass.getCanonicalName()));
}
}
diff --git a/src/test/java/com/android/tools/r8/regress/b71604169/Regress71604169Test.java b/src/test/java/com/android/tools/r8/regress/b71604169/Regress71604169Test.java
index f40ecfd..cc356c3 100644
--- a/src/test/java/com/android/tools/r8/regress/b71604169/Regress71604169Test.java
+++ b/src/test/java/com/android/tools/r8/regress/b71604169/Regress71604169Test.java
@@ -6,15 +6,32 @@
import static junit.framework.TestCase.assertEquals;
+import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.Origin;
import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collection;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class Regress71604169Test extends TestBase {
+ private Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public Regress71604169Test(Backend backend) {
+ this.backend = backend;
+ }
+
@Test
public void test() throws Exception {
R8Command.Builder builder = R8Command.builder();
@@ -28,7 +45,20 @@
builder.addProguardConfiguration(
ImmutableList.of(keepMainProguardConfiguration(mainClass, true, false)), Origin.unknown());
- builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
- assertEquals("Hello, world!", runOnArt(ToolHelper.runR8(builder.build()), mainClass));
+ if (backend == Backend.DEX) {
+ builder
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+ } else {
+ assert backend == Backend.CF;
+ builder
+ .setProgramConsumer(ClassFileConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getJava8RuntimeJar());
+ }
+ assertEquals(
+ "Hello, world!",
+ backend == Backend.DEX
+ ? runOnArt(ToolHelper.runR8(builder.build()), mainClass)
+ : runOnJava(ToolHelper.runR8(builder.build()), mainClass));
}
}
diff --git a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
index 22cab2a..23c8933 100644
--- a/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/SingleTargetLookupTest.java
@@ -11,6 +11,7 @@
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.GraphLense;
import com.android.tools.r8.resolution.singletarget.Main;
import com.android.tools.r8.resolution.singletarget.one.AbstractSubClass;
import com.android.tools.r8.resolution.singletarget.one.AbstractTopClass;
@@ -107,8 +108,13 @@
ExecutorService executor = Executors.newSingleThreadExecutor();
RootSet rootSet = new RootSetBuilder(appInfoWithSubtyping, application,
buildKeepRuleForClass(Main.class, application.dexItemFactory), options).run(executor);
- appInfo = new Enqueuer(appInfoWithSubtyping, options, options.forceProguardCompatibility)
- .traceApplication(rootSet, executor, timing);
+ appInfo =
+ new Enqueuer(
+ appInfoWithSubtyping,
+ GraphLense.getIdentityLense(),
+ options,
+ options.forceProguardCompatibility)
+ .traceApplication(rootSet, executor, timing);
// We do not run the tree pruner to ensure that the hierarchy is as designed and not modified
// due to liveness.
}
diff --git a/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java b/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java
index eab5197..d753632 100644
--- a/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/defaultmethods/DefaultMethodsTest.java
@@ -7,6 +7,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
@@ -19,18 +20,43 @@
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class DefaultMethodsTest extends TestBase {
+
+ private Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public DefaultMethodsTest(Backend backend) {
+ this.backend = backend;
+ }
+
private void runTest(List<String> additionalKeepRules, Consumer<CodeInspector> inspection)
throws Exception {
R8Command.Builder builder = R8Command.builder();
builder.addProgramFiles(ToolHelper.getClassFileForTestClass(InterfaceWithDefaultMethods.class));
builder.addProgramFiles(ToolHelper.getClassFileForTestClass(ClassImplementingInterface.class));
builder.addProgramFiles(ToolHelper.getClassFileForTestClass(TestClass.class));
- builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
- builder.setMinApiLevel(AndroidApiLevel.O.getLevel());
+ if (backend == Backend.DEX) {
+ builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+ int apiLevel = AndroidApiLevel.O.getLevel();
+ builder.setMinApiLevel(apiLevel);
+ builder.addLibraryFiles(ToolHelper.getAndroidJar(apiLevel));
+ } else {
+ assert backend == Backend.CF;
+ builder.setProgramConsumer(ClassFileConsumer.emptyConsumer());
+ builder.addLibraryFiles(ToolHelper.getJava8RuntimeJar());
+ }
// Always keep main in the test class, so the output never becomes empty.
builder.addProguardConfiguration(ImmutableList.of(
"-keep class " + TestClass.class.getCanonicalName() + "{",
diff --git a/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java b/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java
index 8d38aee..b22dc1e 100644
--- a/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java
@@ -6,14 +6,11 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.code.InvokeInterface;
-import com.android.tools.r8.code.InvokeVirtual;
-import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.invokesuper.Consumer;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.origin.Origin;
@@ -24,11 +21,32 @@
import com.android.tools.r8.shaking.proxy.testclasses.TestClass;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.InvokeInstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Streams;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
+import java.util.function.Predicate;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class ProxiesTest extends TestBase {
+ private Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public ProxiesTest(Backend backend) {
+ this.backend = backend;
+ }
private void runTest(List<String> additionalKeepRules, Consumer<CodeInspector> inspection,
String expectedResult)
@@ -49,52 +67,89 @@
Origin.unknown()
);
builder.addProguardConfiguration(additionalKeepRules, Origin.unknown());
- builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+ if (backend == Backend.DEX) {
+ builder
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+ } else {
+ assert backend == Backend.CF;
+ builder
+ .setProgramConsumer(ClassFileConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getJava8RuntimeJar());
+ }
AndroidApp app = ToolHelper.runR8(builder.build(), o -> o.enableDevirtualization = false);
- inspection.accept(new CodeInspector(app));
- assertEquals(expectedResult, runOnArt(app, mainClass));
+ inspection.accept(new CodeInspector(app, o -> o.enableCfFrontend = true));
+ assertEquals(
+ expectedResult,
+ backend == Backend.DEX ? runOnArt(app, mainClass) : runOnJava(app, mainClass));
}
- private int countInstructionInX(CodeInspector inspector, Class<? extends Instruction> invoke) {
+ private int countInstructionInX(CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForX =
new MethodSignature("x", "void", ImmutableList.of(BaseInterface.class.getCanonicalName()));
- DexCode x = inspector.clazz(Main.class).method(signatureForX).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(x, invoke).count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForX);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int) Streams.stream(foundMethod.iterateInstructions(invoke)).count();
}
- private int countInstructionInY(CodeInspector inspector, Class<? extends Instruction> invoke) {
+ private int countInstructionInY(CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForY =
new MethodSignature("y", "void", ImmutableList.of(SubInterface.class.getCanonicalName()));
- DexCode y = inspector.clazz(Main.class).method(signatureForY).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(y, invoke)
- .filter(instruction -> instruction.getMethod().qualifiedName().endsWith("method"))
- .count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForY);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int)
+ Streams.stream(foundMethod.iterateInstructions(invoke))
+ .filter(
+ instruction -> {
+ InvokeInstructionSubject invokeInstruction =
+ (InvokeInstructionSubject) instruction;
+ return invokeInstruction.invokedMethod().qualifiedName().endsWith("method");
+ })
+ .count();
}
- private int countInstructionInZ(CodeInspector inspector, Class<? extends Instruction> invoke) {
+ private int countInstructionInZ(CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForZ =
new MethodSignature("z", "void", ImmutableList.of(TestClass.class.getCanonicalName()));
- DexCode z = inspector.clazz(Main.class).method(signatureForZ).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(z, invoke)
- .filter(instruction -> instruction.getMethod().qualifiedName().endsWith("method"))
- .count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForZ);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int)
+ Streams.stream(foundMethod.iterateInstructions(invoke))
+ .filter(
+ instruction -> {
+ InvokeInstructionSubject invokeInstruction =
+ (InvokeInstructionSubject) instruction;
+ return invokeInstruction.invokedMethod().qualifiedName().endsWith("method");
+ })
+ .count();
}
private int countInstructionInZSubClass(
- CodeInspector inspector, Class<? extends Instruction> invoke) {
+ CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForZ =
new MethodSignature("z", "void", ImmutableList.of(SubClass.class.getCanonicalName()));
- DexCode z = inspector.clazz(Main.class).method(signatureForZ).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(z, invoke)
- .filter(instruction -> instruction.getMethod().qualifiedName().endsWith("method"))
- .count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForZ);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int)
+ Streams.stream(foundMethod.iterateInstructions(invoke))
+ .filter(
+ instruction -> {
+ InvokeInstructionSubject invokeInstruction =
+ (InvokeInstructionSubject) instruction;
+ return invokeInstruction.invokedMethod().qualifiedName().endsWith("method");
+ })
+ .count();
}
private void noInterfaceKept(CodeInspector inspector) {
// Indirectly assert that method is inlined into x, y and z.
- assertEquals(1, countInstructionInX(inspector, InvokeInterface.class));
- assertEquals(1, countInstructionInY(inspector, InvokeInterface.class));
- assertEquals(1, countInstructionInZ(inspector, InvokeVirtual.class));
+ assertEquals(1, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(1, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(1, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
@@ -106,11 +161,11 @@
private void baseInterfaceKept(CodeInspector inspector) {
// Indirectly assert that method is not inlined into x.
- assertEquals(3, countInstructionInX(inspector, InvokeInterface.class));
+ assertEquals(3, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
// Indirectly assert that method is inlined into y and z.
- assertEquals(1, countInstructionInY(inspector, InvokeInterface.class));
- assertEquals(1, countInstructionInZ(inspector, InvokeVirtual.class));
- assertEquals(1, countInstructionInZSubClass(inspector, InvokeVirtual.class));
+ assertEquals(1, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(1, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
+ assertEquals(1, countInstructionInZSubClass(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
@@ -126,11 +181,11 @@
private void subInterfaceKept(CodeInspector inspector) {
// Indirectly assert that method is not inlined into x or y.
- assertEquals(3, countInstructionInX(inspector, InvokeInterface.class));
- assertEquals(3, countInstructionInY(inspector, InvokeInterface.class));
+ assertEquals(3, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(3, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
// Indirectly assert that method is inlined into z.
- assertEquals(1, countInstructionInZ(inspector, InvokeVirtual.class));
- assertEquals(1, countInstructionInZSubClass(inspector, InvokeVirtual.class));
+ assertEquals(1, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
+ assertEquals(1, countInstructionInZSubClass(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
@@ -148,10 +203,10 @@
private void classKept(CodeInspector inspector) {
// Indirectly assert that method is not inlined into x, y or z.
- assertEquals(3, countInstructionInX(inspector, InvokeInterface.class));
- assertEquals(3, countInstructionInY(inspector, InvokeInterface.class));
- assertEquals(3, countInstructionInZ(inspector, InvokeVirtual.class));
- assertEquals(3, countInstructionInZSubClass(inspector, InvokeVirtual.class));
+ assertEquals(3, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(3, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(3, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
+ assertEquals(3, countInstructionInZSubClass(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java b/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java
index 147b1b4..d12f41a 100644
--- a/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/testrules/ForceInlineTest.java
@@ -13,6 +13,9 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
+import com.android.tools.r8.ClassFileConsumer;
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
@@ -20,17 +23,45 @@
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class ForceInlineTest extends TestBase {
+ private Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public ForceInlineTest(Backend backend) {
+ this.backend = backend;
+ }
private CodeInspector runTest(List<String> proguardConfiguration) throws Exception {
+ ProgramConsumer programConsumer;
+ Path library;
+ if (backend == Backend.DEX) {
+ programConsumer = DexIndexedConsumer.emptyConsumer();
+ library = ToolHelper.getDefaultAndroidJar();
+ } else {
+ assert backend == Backend.CF;
+ programConsumer = ClassFileConsumer.emptyConsumer();
+ library = ToolHelper.getJava8RuntimeJar();
+ }
R8Command.Builder builder =
- ToolHelper.prepareR8CommandBuilder(readClasses(Main.class, A.class, B.class, C.class));
+ ToolHelper.prepareR8CommandBuilder(
+ readClasses(Main.class, A.class, B.class, C.class), programConsumer)
+ .addLibraryFiles(library);
ToolHelper.allowTestProguardOptions(builder);
builder.addProguardConfiguration(proguardConfiguration, Origin.unknown());
- return new CodeInspector(ToolHelper.runR8(builder.build()));
+ return new CodeInspector(ToolHelper.runR8(builder.build(), o -> o.enableCfFrontend = true));
}
@Test
diff --git a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
index 6b90d88..00d385f 100644
--- a/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
+++ b/src/test/java/com/android/tools/r8/smali/CatchSuccessorFallthroughTest.java
@@ -7,6 +7,7 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Phi;
@@ -68,7 +69,9 @@
DexEncodedMethod method = getMethod(originalApplication, methodSig);
// Get the IR pre-optimization.
- IRCode code = method.buildIR(null, new InternalOptions(), Origin.unknown());
+ IRCode code =
+ method.buildIR(
+ null, GraphLense.getIdentityLense(), new InternalOptions(), Origin.unknown());
// Find the exit block and assert that the value is a phi merging the exceptional edge
// with the normal edge.