aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2016-10-16 13:45:30 -0700
committerBen Gruver <bgruv@google.com>2016-10-16 13:45:30 -0700
commita6593575e71a9cccf2d9711b774223aca12c22df (patch)
tree9949478247d8b9a5fb32d463f3a046266e93eed9
parent22e85fc3ff3d85e8a30fc42438ccb942fc5d80df (diff)
downloadsmali-a6593575e71a9cccf2d9711b774223aca12c22df.tar.gz
Be more precise about narrowing after an instance-of
Only do the additional narrowing when all predecessors of the instance-of are equivalent move instructions.
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java52
1 files changed, 37 insertions, 15 deletions
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java
index 0da57f16..0c073b39 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/analysis/MethodAnalyzer.java
@@ -1216,35 +1216,57 @@ public class MethodAnalyzer {
}
AnalyzedInstruction prevAnalyzedInstruction = analyzedInstruction.getPredecessors().first();
if (prevAnalyzedInstruction.instruction.getOpcode() == Opcode.INSTANCE_OF) {
+ Instruction22c instanceOfInstruction = (Instruction22c)prevAnalyzedInstruction.instruction;
if (canNarrowAfterInstanceOf(prevAnalyzedInstruction, analyzedInstruction, classPath)) {
List<Integer> narrowingRegisters = Lists.newArrayList();
RegisterType newType = RegisterType.getRegisterType(classPath,
- (TypeReference)((Instruction22c)prevAnalyzedInstruction.instruction).getReference());
+ (TypeReference)instanceOfInstruction.getReference());
if (instructionIndex > 1) {
// If we have something like:
// move-object/from16 v0, p1
// instance-of v2, v0, Lblah;
// if-eqz v2, :target
- // Then we need to narrow both v0 AND p1
- AnalyzedInstruction prevPrevAnalyzedInstruction =
- analyzedInstructions.valueAt(instructionIndex - 2);
- Opcode opcode = prevPrevAnalyzedInstruction.instruction.getOpcode();
- if (opcode == Opcode.MOVE_OBJECT || opcode == Opcode.MOVE_OBJECT_16 ||
- opcode == Opcode.MOVE_OBJECT_FROM16) {
- TwoRegisterInstruction moveInstruction =
- ((TwoRegisterInstruction)prevPrevAnalyzedInstruction.instruction);
- RegisterType originalType =
- prevPrevAnalyzedInstruction.getPostInstructionRegisterType(
- moveInstruction.getRegisterB());
- if (originalType.type != null) {
+ // Then we need to narrow both v0 AND p1, but only if all predecessors of instance-of are a
+ // move-object for the same registers
+
+ int additionalNarrowingRegister = -1;
+ for (AnalyzedInstruction prevPrevAnalyzedInstruction: prevAnalyzedInstruction.predecessors) {
+ Opcode opcode = prevPrevAnalyzedInstruction.instruction.getOpcode();
+ if (opcode == Opcode.MOVE_OBJECT || opcode == Opcode.MOVE_OBJECT_16 ||
+ opcode == Opcode.MOVE_OBJECT_FROM16) {
+ TwoRegisterInstruction moveInstruction =
+ ((TwoRegisterInstruction)prevPrevAnalyzedInstruction.instruction);
+ RegisterType originalType =
+ prevPrevAnalyzedInstruction.getPostInstructionRegisterType(
+ moveInstruction.getRegisterB());
+ if (moveInstruction.getRegisterA() != instanceOfInstruction.getRegisterB()) {
+ additionalNarrowingRegister = -1;
+ break;
+ }
+ if (originalType.type == null) {
+ additionalNarrowingRegister = -1;
+ break;
+ }
if (isNarrowingConversion(originalType, newType)) {
- narrowingRegisters.add(
- ((TwoRegisterInstruction)prevPrevAnalyzedInstruction.instruction).getRegisterB());
+ if (additionalNarrowingRegister != -1) {
+ if (additionalNarrowingRegister != moveInstruction.getRegisterB()) {
+ additionalNarrowingRegister = -1;
+ break;
+ }
+ } else {
+ additionalNarrowingRegister = moveInstruction.getRegisterB();
+ }
}
+ } else {
+ additionalNarrowingRegister = -1;
+ break;
}
}
+ if (additionalNarrowingRegister != -1) {
+ narrowingRegisters.add(additionalNarrowingRegister);
+ }
}
// Propagate the original type to the failing branch, and the new type to the successful branch