Minor cleanup of IdentifierNameStringMarker
Change-Id: Ibb0f07ac52e7b84848e892cd86174d3ca4891c1d
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
index 87dc516..b2c5675 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
@@ -48,11 +48,12 @@
private final AppView<AppInfoWithLiveness> appView;
private final Object2BooleanMap<DexReference> identifierNameStrings;
+ private final ThrowingInfo throwingInfo;
public IdentifierNameStringMarker(AppView<AppInfoWithLiveness> appView) {
this.appView = appView;
- // Note that this info is only available at AppInfoWithLiveness.
this.identifierNameStrings = appView.appInfo().identifierNameStrings;
+ this.throwingInfo = ThrowingInfo.defaultForConstString(appView.options());
}
public void decoupleIdentifierNameStringsInFields() {
@@ -83,8 +84,6 @@
if (!code.hasConstString) {
return;
}
- ThrowingInfo throwingInfo = ThrowingInfo.defaultForConstString(appView.options());
- DexType originHolder = code.method.method.holder;
ListIterator<BasicBlock> blocks = code.listIterator();
while (blocks.hasNext()) {
BasicBlock block = blocks.next();
@@ -103,183 +102,201 @@
// v_n' <- DexItemBasedString("Lx/y/z;") // decoupled
// this.fld <- v_n' // fieldPut
if (instruction.isStaticPut() || instruction.isInstancePut()) {
- FieldInstruction fieldPut = instruction.asFieldInstruction();
- DexField field = fieldPut.getField();
- if (!identifierNameStrings.containsKey(field)) {
- continue;
- }
- Value in = instruction.isStaticPut()
- ? instruction.asStaticPut().inValue()
- : instruction.asInstancePut().value();
- if (!in.isConstString()) {
- warnUndeterminedIdentifierIfNecessary(field, originHolder, instruction, null);
- continue;
- }
- DexString original = in.getConstInstruction().asConstString().getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
- if (itemBasedString == null) {
- warnUndeterminedIdentifierIfNecessary(field, originHolder, instruction, original);
- continue;
- }
- // Move the cursor back to $fieldPut
- assert iterator.peekPrevious() == fieldPut;
- iterator.previous();
- // Prepare $decoupled just before $fieldPut
- Value newIn = code.createValue(in.getTypeLattice(), in.getLocalInfo());
- DexItemBasedConstString decoupled =
- new DexItemBasedConstString(newIn, itemBasedString, throwingInfo);
- decoupled.setPosition(fieldPut.getPosition());
- // If the current block has catch handler, split into two blocks.
- // Because const-string we're about to add is also a throwing instr, we need to split
- // before adding it.
- BasicBlock blockWithFieldInstruction =
- block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
- if (blockWithFieldInstruction != block) {
- // If we split, add const-string at the end of the currently visiting block.
- iterator = block.listIterator(block.getInstructions().size());
- iterator.previous();
- iterator.add(decoupled);
- // Restore the cursor and block.
- iterator = blockWithFieldInstruction.listIterator();
- assert iterator.peekNext() == fieldPut;
- iterator.next();
- block = blockWithFieldInstruction;
- } else {
- // Otherwise, just add it to the current block at the position of the iterator.
- iterator.add(decoupled);
- // Restore the cursor.
- assert iterator.peekNext() == fieldPut;
- iterator.next();
- }
- if (instruction.isStaticPut()) {
- iterator.replaceCurrentInstruction(new StaticPut(newIn, field));
- } else {
- assert instruction.isInstancePut();
- InstancePut instancePut = instruction.asInstancePut();
- iterator.replaceCurrentInstruction(new InstancePut(field, instancePut.object(), newIn));
- }
- encodedMethod.getMutableOptimizationInfo().markUseIdentifierNameString();
+ iterator =
+ decoupleIdentifierNameStringForFieldPutInstruction(
+ code, encodedMethod, blocks, iterator, instruction.asFieldInstruction());
} else if (instruction.isInvokeMethod()) {
- InvokeMethod invoke = instruction.asInvokeMethod();
- DexMethod invokedMethod = invoke.getInvokedMethod();
- if (!identifierNameStrings.containsKey(invokedMethod)) {
- continue;
- }
- List<Value> ins = invoke.arguments();
- Value[] changes = new Value [ins.size()];
- if (isReflectionMethod(appView.dexItemFactory(), invokedMethod)) {
- DexReference itemBasedString = identifyIdentifier(invoke, appView);
- if (itemBasedString == null) {
- warnUndeterminedIdentifierIfNecessary(invokedMethod, originHolder, instruction, null);
- continue;
- }
- DexType returnType = invoke.getReturnType();
- boolean isClassForName =
- returnType.descriptor == appView.dexItemFactory().classDescriptor;
- boolean isReferenceFieldUpdater =
- returnType.descriptor == appView.dexItemFactory().referenceFieldUpdaterDescriptor;
- int positionOfIdentifier = isClassForName ? 0 : (isReferenceFieldUpdater ? 2 : 1);
- Value in = invoke.arguments().get(positionOfIdentifier);
- // Move the cursor back to $invoke
- assert iterator.peekPrevious() == invoke;
- iterator.previous();
- // Prepare $decoupled just before $invoke
- Value newIn = code.createValue(in.getTypeLattice(), in.getLocalInfo());
- DexItemBasedConstString decoupled =
- new DexItemBasedConstString(newIn, itemBasedString, throwingInfo);
- decoupled.setPosition(invoke.getPosition());
- changes[positionOfIdentifier] = newIn;
- // If the current block has catch handler, split into two blocks.
- // Because const-string we're about to add is also a throwing instr, we need to split
- // before adding it.
- BasicBlock blockWithInvoke =
- block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
- if (blockWithInvoke != block) {
- // If we split, add const-string at the end of the currently visiting block.
- iterator = block.listIterator(block.getInstructions().size());
- iterator.previous();
- iterator.add(decoupled);
- // Restore the cursor and block.
- iterator = blockWithInvoke.listIterator();
- assert iterator.peekNext() == invoke;
- iterator.next();
- block = blockWithInvoke;
- } else {
- // Otherwise, just add it to the current block at the position of the iterator.
- iterator.add(decoupled);
- // Restore the cursor.
- assert iterator.peekNext() == invoke;
- iterator.next();
- }
- } else {
- // For general invoke. Multiple arguments can be string literals to be renamed.
- for (int i = 0; i < ins.size(); i++) {
- Value in = ins.get(i);
- if (!in.isConstString()) {
- warnUndeterminedIdentifierIfNecessary(
- invokedMethod, originHolder, instruction, null);
- continue;
- }
- DexString original = in.getConstInstruction().asConstString().getValue();
- DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
- if (itemBasedString == null) {
- warnUndeterminedIdentifierIfNecessary(
- invokedMethod, originHolder, instruction, original);
- continue;
- }
- // Move the cursor back to $invoke
- assert iterator.peekPrevious() == invoke;
- iterator.previous();
- // Prepare $decoupled just before $invoke
- Value newIn = code.createValue(in.getTypeLattice(), in.getLocalInfo());
- DexItemBasedConstString decoupled =
- new DexItemBasedConstString(newIn, itemBasedString, throwingInfo);
- decoupled.setPosition(invoke.getPosition());
- changes[i] = newIn;
- // If the current block has catch handler, split into two blocks.
- // Because const-string we're about to add is also a throwing instr, we need to split
- // before adding it.
- BasicBlock blockWithInvoke =
- block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
- if (blockWithInvoke != block) {
- // If we split, add const-string at the end of the currently visiting block.
- iterator = block.listIterator(block.getInstructions().size());
- iterator.previous();
- iterator.add(decoupled);
- // Restore the cursor and block.
- iterator = blockWithInvoke.listIterator();
- assert iterator.peekNext() == invoke;
- iterator.next();
- block = blockWithInvoke;
- } else {
- // Otherwise, just add it to the current block at the position of the iterator.
- iterator.add(decoupled);
- // Restore the cursor.
- assert iterator.peekNext() == invoke;
- iterator.next();
- }
- }
- }
- if (!Arrays.stream(changes).allMatch(Objects::isNull)) {
- List<Value> newIns =
- Streams.mapWithIndex(
- ins.stream(),
- (in, index) -> changes[(int) index] != null ? changes[(int) index] : in)
- .collect(Collectors.toList());
- iterator.replaceCurrentInstruction(
- Invoke.create(
- invoke.getType(),
- invokedMethod,
- invokedMethod.proto,
- invoke.outValue(),
- newIns));
- encodedMethod.getMutableOptimizationInfo().markUseIdentifierNameString();
- }
+ iterator =
+ decoupleIdentifierNameStringForInvokeInstruction(
+ code, encodedMethod, blocks, iterator, instruction.asInvokeMethod());
}
}
}
}
+ private InstructionListIterator decoupleIdentifierNameStringForFieldPutInstruction(
+ IRCode code,
+ DexEncodedMethod method,
+ ListIterator<BasicBlock> blocks,
+ InstructionListIterator iterator,
+ FieldInstruction instruction) {
+ assert instruction.isInstancePut() || instruction.isStaticPut();
+ FieldInstruction fieldPut = instruction.asFieldInstruction();
+ DexField field = fieldPut.getField();
+ if (!identifierNameStrings.containsKey(field)) {
+ return iterator;
+ }
+ Value in =
+ instruction.isStaticPut()
+ ? instruction.asStaticPut().inValue()
+ : instruction.asInstancePut().value();
+ if (!in.isConstString()) {
+ warnUndeterminedIdentifierIfNecessary(field, method.method.holder, instruction, null);
+ return iterator;
+ }
+ DexString original = in.getConstInstruction().asConstString().getValue();
+ DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
+ if (itemBasedString == null) {
+ warnUndeterminedIdentifierIfNecessary(field, method.method.holder, instruction, original);
+ return iterator;
+ }
+ // Move the cursor back to $fieldPut
+ assert iterator.peekPrevious() == fieldPut;
+ iterator.previous();
+ // Prepare $decoupled just before $fieldPut
+ Value newIn = code.createValue(in.getTypeLattice(), in.getLocalInfo());
+ DexItemBasedConstString decoupled =
+ new DexItemBasedConstString(newIn, itemBasedString, throwingInfo);
+ decoupled.setPosition(fieldPut.getPosition());
+ // If the current block has catch handler, split into two blocks.
+ // Because const-string we're about to add is also a throwing instr, we need to split
+ // before adding it.
+ BasicBlock block = instruction.getBlock();
+ BasicBlock blockWithFieldInstruction =
+ block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
+ if (blockWithFieldInstruction != block) {
+ // If we split, add const-string at the end of the currently visiting block.
+ iterator = block.listIterator(block.getInstructions().size() - 1);
+ iterator.add(decoupled);
+ // Restore the cursor and block.
+ iterator = blockWithFieldInstruction.listIterator();
+ assert iterator.peekNext() == fieldPut;
+ iterator.next();
+ } else {
+ // Otherwise, just add it to the current block at the position of the iterator.
+ iterator.add(decoupled);
+ // Restore the cursor.
+ assert iterator.peekNext() == fieldPut;
+ iterator.next();
+ }
+ if (instruction.isStaticPut()) {
+ iterator.replaceCurrentInstruction(new StaticPut(newIn, field));
+ } else {
+ assert instruction.isInstancePut();
+ InstancePut instancePut = instruction.asInstancePut();
+ iterator.replaceCurrentInstruction(new InstancePut(field, instancePut.object(), newIn));
+ }
+ method.getMutableOptimizationInfo().markUseIdentifierNameString();
+ return iterator;
+ }
+
+ private InstructionListIterator decoupleIdentifierNameStringForInvokeInstruction(
+ IRCode code,
+ DexEncodedMethod method,
+ ListIterator<BasicBlock> blocks,
+ InstructionListIterator iterator,
+ InvokeMethod invoke) {
+ DexMethod invokedMethod = invoke.getInvokedMethod();
+ if (!identifierNameStrings.containsKey(invokedMethod)) {
+ return iterator;
+ }
+ List<Value> ins = invoke.arguments();
+ Value[] changes = new Value[ins.size()];
+ if (isReflectionMethod(appView.dexItemFactory(), invokedMethod)) {
+ DexReference itemBasedString = identifyIdentifier(invoke, appView);
+ if (itemBasedString == null) {
+ DexType context = method.method.holder;
+ warnUndeterminedIdentifierIfNecessary(invokedMethod, context, invoke, null);
+ return iterator;
+ }
+ DexType returnType = invoke.getReturnType();
+ boolean isClassForName = returnType.descriptor == appView.dexItemFactory().classDescriptor;
+ boolean isReferenceFieldUpdater =
+ returnType.descriptor == appView.dexItemFactory().referenceFieldUpdaterDescriptor;
+ int positionOfIdentifier = isClassForName ? 0 : (isReferenceFieldUpdater ? 2 : 1);
+ Value in = invoke.arguments().get(positionOfIdentifier);
+ // Move the cursor back to $invoke
+ assert iterator.peekPrevious() == invoke;
+ iterator.previous();
+ // Prepare $decoupled just before $invoke
+ Value newIn = code.createValue(in.getTypeLattice(), in.getLocalInfo());
+ DexItemBasedConstString decoupled =
+ new DexItemBasedConstString(newIn, itemBasedString, throwingInfo);
+ decoupled.setPosition(invoke.getPosition());
+ changes[positionOfIdentifier] = newIn;
+ // If the current block has catch handler, split into two blocks.
+ // Because const-string we're about to add is also a throwing instr, we need to split
+ // before adding it.
+ BasicBlock block = invoke.getBlock();
+ BasicBlock blockWithInvoke = block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
+ if (blockWithInvoke != block) {
+ // If we split, add const-string at the end of the currently visiting block.
+ iterator = block.listIterator(block.getInstructions().size());
+ iterator.previous();
+ iterator.add(decoupled);
+ // Restore the cursor and block.
+ iterator = blockWithInvoke.listIterator();
+ assert iterator.peekNext() == invoke;
+ iterator.next();
+ } else {
+ // Otherwise, just add it to the current block at the position of the iterator.
+ iterator.add(decoupled);
+ // Restore the cursor.
+ assert iterator.peekNext() == invoke;
+ iterator.next();
+ }
+ } else {
+ // For general invoke. Multiple arguments can be string literals to be renamed.
+ for (int i = 0; i < ins.size(); i++) {
+ Value in = ins.get(i);
+ if (!in.isConstString()) {
+ warnUndeterminedIdentifierIfNecessary(invokedMethod, method.method.holder, invoke, null);
+ continue;
+ }
+ DexString original = in.getConstInstruction().asConstString().getValue();
+ DexReference itemBasedString = inferMemberOrTypeFromNameString(appView, original);
+ if (itemBasedString == null) {
+ warnUndeterminedIdentifierIfNecessary(
+ invokedMethod, method.method.holder, invoke, original);
+ continue;
+ }
+ // Move the cursor back to $invoke
+ assert iterator.peekPrevious() == invoke;
+ iterator.previous();
+ // Prepare $decoupled just before $invoke
+ Value newIn = code.createValue(in.getTypeLattice(), in.getLocalInfo());
+ DexItemBasedConstString decoupled =
+ new DexItemBasedConstString(newIn, itemBasedString, throwingInfo);
+ decoupled.setPosition(invoke.getPosition());
+ changes[i] = newIn;
+ // If the current block has catch handler, split into two blocks.
+ // Because const-string we're about to add is also a throwing instr, we need to split
+ // before adding it.
+ BasicBlock block = invoke.getBlock();
+ BasicBlock blockWithInvoke =
+ block.hasCatchHandlers() ? iterator.split(code, blocks) : block;
+ if (blockWithInvoke != block) {
+ // If we split, add const-string at the end of the currently visiting block.
+ iterator = block.listIterator(block.getInstructions().size());
+ iterator.previous();
+ iterator.add(decoupled);
+ // Restore the cursor and block.
+ iterator = blockWithInvoke.listIterator();
+ assert iterator.peekNext() == invoke;
+ iterator.next();
+ } else {
+ // Otherwise, just add it to the current block at the position of the iterator.
+ iterator.add(decoupled);
+ // Restore the cursor.
+ assert iterator.peekNext() == invoke;
+ iterator.next();
+ }
+ }
+ }
+ if (!Arrays.stream(changes).allMatch(Objects::isNull)) {
+ List<Value> newIns =
+ Streams.mapWithIndex(
+ ins.stream(),
+ (in, index) -> changes[(int) index] != null ? changes[(int) index] : in)
+ .collect(Collectors.toList());
+ iterator.replaceCurrentInstruction(
+ Invoke.create(
+ invoke.getType(), invokedMethod, invokedMethod.proto, invoke.outValue(), newIns));
+ method.getMutableOptimizationInfo().markUseIdentifierNameString();
+ }
+ return iterator;
+ }
+
private void warnUndeterminedIdentifierIfNecessary(
DexReference member, DexType originHolder, Instruction instruction, DexString original) {
assert member.isDexField() || member.isDexMethod();