diff options
author | Orion Hodson <oth@google.com> | 2018-12-21 09:37:49 -0800 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-12-21 09:37:49 -0800 |
commit | 1ea5ef90cae1ed6bfc5867ef9a96c87ff760535b (patch) | |
tree | b630d08d3f3089cf376e2d23bb313f1db6c15766 | |
parent | 4999049f2c44eeacef207a4f4264784eb53d96a3 (diff) | |
parent | 70302690ba85875887b7de765cde29d2c6c94b42 (diff) | |
download | dalvik-1ea5ef90cae1ed6bfc5867ef9a96c87ff760535b.tar.gz |
Merge "dx: workaround a verifier bug" am: efc11dda34 am: f0ea23ec09
am: 70302690ba
Change-Id: I397aa333c97647a6f261461bf74a399700e112d6
-rw-r--r-- | dx/src/com/android/dx/dex/code/OutputCollector.java | 12 | ||||
-rw-r--r-- | dx/src/com/android/dx/dex/code/OutputFinisher.java | 8 | ||||
-rw-r--r-- | dx/src/com/android/dx/dex/code/RopTranslator.java | 32 |
3 files changed, 51 insertions, 1 deletions
diff --git a/dx/src/com/android/dx/dex/code/OutputCollector.java b/dx/src/com/android/dx/dex/code/OutputCollector.java index 833c0f21b..8c8867a0b 100644 --- a/dx/src/com/android/dx/dex/code/OutputCollector.java +++ b/dx/src/com/android/dx/dex/code/OutputCollector.java @@ -65,6 +65,18 @@ public final class OutputCollector { finisher.add(insn); } + public DalvInsn get(int at) { + if (at >= finisher.size() || at < 0) { + return null; + } else { + return finisher.get(at); + } + } + + public int size() { + return finisher.size(); + } + /** * Reverses a branch which is buried a given number of instructions * backward in the output. It is illegal to call this unless the diff --git a/dx/src/com/android/dx/dex/code/OutputFinisher.java b/dx/src/com/android/dx/dex/code/OutputFinisher.java index 3b711fb32..82a4725f5 100644 --- a/dx/src/com/android/dx/dex/code/OutputFinisher.java +++ b/dx/src/com/android/dx/dex/code/OutputFinisher.java @@ -256,6 +256,14 @@ public final class OutputFinisher { updateInfo(insn); } + public DalvInsn get(int at) { + return insns.get(at); + } + + public int size() { + return insns.size(); + } + /** * Helper for {@link #add} and {@link #insert}, * which updates the position and local info flags. diff --git a/dx/src/com/android/dx/dex/code/RopTranslator.java b/dx/src/com/android/dx/dex/code/RopTranslator.java index 8375f9ee3..517b4f855 100644 --- a/dx/src/com/android/dx/dex/code/RopTranslator.java +++ b/dx/src/com/android/dx/dex/code/RopTranslator.java @@ -762,7 +762,27 @@ public final class RopTranslator { */ di = new CstInsn(opcode, pos, regs, cst); } - + // (b/120985556) update the following code + // move-object vX, vY + // instance-of vY, vX, LMyClass; + // into + // move-object vX, vY + // nop + // instance-of vY, vX, LMyClass; + DalvInsn previousDi = getPrevNonSpecialInsn(); + if (opcode.getOpcode() == Opcodes.INSTANCE_OF && previousDi != null) { + int prevOpcode = previousDi.getOpcode().getOpcode(); + if (prevOpcode == Opcodes.MOVE_OBJECT + || prevOpcode == Opcodes.MOVE_OBJECT_FROM16 + || prevOpcode == Opcodes.MOVE_OBJECT_16) { + if (di.getRegisters().size() > 0 && previousDi.getRegisters().size() > 1 + && (di.getRegisters().get(0).getReg() + == previousDi.getRegisters().get(1).getReg())) { + DalvInsn nopDi = new SimpleInsn(Dops.NOP, pos, RegisterSpecList.EMPTY); + addOutput(nopDi); + } + } + } addOutput(di); } } @@ -830,6 +850,16 @@ public final class RopTranslator { output.add(insn); } + protected DalvInsn getPrevNonSpecialInsn() { + for (int i = output.size() - 1; i >= 0; --i) { + DalvInsn insn = output.get(i); + if (insn.getOpcode().getOpcode() != Opcodes.SPECIAL_FORMAT) { + return insn; + } + } + return null; + } + /** * Adds to the output suffix. * |