@Nonnull private BuilderInstruction35c newBuilderInstruction35c(@Nonnull Instruction35c instruction) { return new BuilderInstruction35c( instruction.getOpcode(), instruction.getRegisterCount(), instruction.getRegisterC(), instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(), instruction.getRegisterG(), convertReference(instruction.getReference())); }
boolean canPeepStringInit(int address) { BuilderInstruction original = manipulator.getInstruction(address); if (original.getOpcode() != Opcode.INVOKE_DIRECT) { return false; } Instruction35c instr = (Instruction35c) original; MethodReference methodReference = (MethodReference) instr.getReference(); String methodDescriptor = ReferenceUtil.getMethodDescriptor(methodReference); if (!methodDescriptor.startsWith("Ljava/lang/String;-><init>(")) { return false; } int instanceRegister = instr.getRegisterC(); HeapItem item = manipulator.getRegisterConsensus(address, instanceRegister); if (!(item.getValue() instanceof String)) { return false; } return true; }
@Override boolean isUsedAsFloatingPoint(DexBody body, int register) { Instruction35c i = (Instruction35c) instruction; Type arrayType = DexType.toSoot((TypeReference) i.getReference()); return isRegisterUsed(register) && isFloatLike(arrayType); }
void peepStringInit() { List<Integer> peepAddresses = addresses.stream().filter(this::canPeepStringInit).collect(Collectors.toList()); if (0 == peepAddresses.size()) { return; } madeChanges = true; peepCount += peepAddresses.size(); Collections.sort(peepAddresses, Collections.reverseOrder()); for (int address : peepAddresses) { BuilderInstruction original = manipulator.getInstruction(address); Instruction35c instr = (Instruction35c) original; int instanceRegister = instr.getRegisterC(); HeapItem item = manipulator.getRegisterConsensus(address, instanceRegister); BuilderInstruction replacement = ConstantBuilder.buildConstant(item.getValue(), item.getUnboxedType(), instanceRegister, manipulator.getDexBuilder()); if (log.isDebugEnabled()) { log.debug("Peeping string init @{} {}", address, manipulator.getOp(address)); } manipulator.replaceInstruction(address, replacement); } }
public int getRegisterF() { return instruction.getRegisterF(); } }
public int getRegisterD() { return instruction.getRegisterD(); }
public int getRegisterE() { return instruction.getRegisterE(); }
public int getRegisterG() { return instruction.getRegisterG(); }
Assert.assertEquals(Opcode.INVOKE_STATIC, instruction.getOpcode()); MethodReference method = (MethodReference)instruction.getReference(); Assert.assertEquals(classDef.getType(), method.getDefiningClass()); Assert.assertEquals("toString", method.getName()); Assert.assertEquals(Opcode.INVOKE_STATIC, instruction.getOpcode()); method = (MethodReference)instruction.getReference(); Assert.assertEquals(classDef.getType(), method.getDefiningClass()); Assert.assertEquals("V", method.getName()); Assert.assertEquals(Opcode.INVOKE_STATIC, instruction.getOpcode()); method = (MethodReference)instruction.getReference(); Assert.assertEquals(classDef.getType(), method.getDefiningClass()); Assert.assertEquals("I", method.getName());
public int getRegisterCount() { return instruction.getRegisterCount(); }
@Test public void invokeClassForNameForUnknownValueIsNotReplaced() { ExecutionGraphManipulator manipulator = getOptimizedGraph(METHOD_NAME, 0, new UnknownValue(), "Ljava/lang/String;"); Instruction35c instruction = (Instruction35c) manipulator.getInstruction(ADDRESS); String methodDescriptor = ReferenceUtil.getMethodDescriptor((MethodReference) instruction.getReference()); assertEquals("Ljava/lang/Class;->forName(Ljava/lang/String;)Ljava/lang/Class;", methodDescriptor); }
public int getRegisterC() { return instruction.getRegisterC(); }
public int getRegisterF() { return instruction.getRegisterF(); } }
public int getRegisterD() { return instruction.getRegisterD(); }
public int getRegisterE() { return instruction.getRegisterE(); }
public int getRegisterG() { return instruction.getRegisterG(); }
public int getRegisterCount() { return instruction.getRegisterCount(); }
/** * Check if register is referenced by this instruction. * */ private boolean isRegisterUsed(int register) { Instruction35c i = (Instruction35c) instruction; return register == i.getRegisterD() || register == i.getRegisterE() || register == i.getRegisterF() || register == i.getRegisterG() || register == i.getRegisterC(); }
@Test public void stringInitWithUnknownValueIsNotReplaced() { VirtualType instanceType = vm.getClassManager().getVirtualType("Ljava/lang/String;"); ExecutionGraphManipulator manipulator = getOptimizedGraph(vm, METHOD_NAME, 0, new UninitializedInstance(instanceType), "Ljava/lang/String;", 1, new UnknownValue(), "[B"); Instruction35c instruction = (Instruction35c) manipulator.getInstruction(ADDRESS); String methodDescriptor = ReferenceUtil.getMethodDescriptor((MethodReference) instruction.getReference()); assertEquals("Ljava/lang/String;-><init>([B)V", methodDescriptor); }
public int getRegisterC() { return instruction.getRegisterC(); }