public final int getAddress() { return location.getCodeAddress(); }
@Override public String toString() { StringBuilder sb = new StringBuilder(getName()); sb.append(" r").append(register1); if (!compareToZero) { sb.append(", r").append(register2); } sb.append(", :addr_").append(target.getCodeAddress()); return sb.toString(); }
@Override public String toString() { StringBuilder sb = new StringBuilder(getName()); int childAddress = getChildren()[0].getCodeAddress(); sb.append(" :addr_").append(childAddress); return sb.toString(); }
public void addInstruction(int index, BuilderInstruction instruction) { // the end check here is intentially >= rather than >, because the list always includes an "empty" // (null instruction) MethodLocation at the end. To add an instruction to the end of the list, the user would // provide the index of this empty item, which would be size() - 1. if (index >= instructionList.size()) { throw new IndexOutOfBoundsException(); } if (index == instructionList.size() - 1) { addInstruction(instruction); return; } int codeAddress = instructionList.get(index).getCodeAddress(); MethodLocation newLoc = new MethodLocation(instruction, codeAddress, index); instructionList.add(index, newLoc); instruction.location = newLoc; codeAddress += instruction.getCodeUnits(); for (int i = index + 1; i < instructionList.size(); i++) { MethodLocation location = instructionList.get(i); location.index++; location.codeAddress = codeAddress; if (location.instruction != null) { codeAddress += location.instruction.getCodeUnits(); } else { // only the last MethodLocation should have a null instruction assert i == instructionList.size() - 1; } } this.fixInstructions = true; }
private static void spawnChildren(ExecutionGraph graph, ExecutionNode parentNode) { // Each visit adds a new ExecutionNode to the pile. These piles can be inspected for register or field // consensus, or other optimizations. for (MethodLocation childLocation : parentNode.getChildLocations()) { spawnChild(graph, parentNode, childLocation.getCodeAddress()); } }
@Override public String toString() { return getName() + " r" + register + ", :addr_" + getChildren()[0].getCodeAddress(); }
@Override public String toString() { return getName() + " r" + register + ", :addr_" + getChildren()[0].getCodeAddress(); }
public static MethodLocation getNextLocation(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation) { int address = location.getCodeAddress(); int nextAddress = address + location.getInstruction().getCodeUnits(); return addressToLocation.get(nextAddress); }
protected static TIntObjectMap<MethodLocation> buildAddressToLocation(MutableMethodImplementation implementation) { List<BuilderInstruction> instructions = implementation.getInstructions(); TIntObjectMap<MethodLocation> addressToLocation = new TIntObjectHashMap<>(instructions.size()); for (BuilderInstruction instruction : instructions) { MethodLocation location = instruction.getLocation(); int address = location.getCodeAddress(); addressToLocation.put(address, location); } return addressToLocation; }
@Nonnull private BuilderInstruction31t newBuilderInstruction31t(@Nonnull MethodLocation location, int[] codeAddressToIndex, @Nonnull Instruction31t instruction) { int codeAddress = location.getCodeAddress(); Label newLabel; if (instruction.getOpcode() != Opcode.FILL_ARRAY_DATA) { // if it's a sparse switch or packed switch newLabel = newSwitchPayloadReferenceLabel(location, codeAddressToIndex, codeAddress + instruction.getCodeOffset()); } else { newLabel = newLabel(codeAddressToIndex, codeAddress + instruction.getCodeOffset()); } return new BuilderInstruction31t( instruction.getOpcode(), instruction.getRegisterA(), newLabel); }
@Before public void setUp() { vm = mock(VirtualMachine.class); mState = mock(MethodState.class); node = mock(ExecutionNode.class); location = mock(MethodLocation.class); when(location.getCodeAddress()).thenReturn(ADDRESS); addressToLocation = new TIntObjectHashMap<MethodLocation>(); addressToLocation.put(ADDRESS, location); opFactory = new IfOpFactory(); }
@Before public void setUp() { vm = mock(VirtualMachine.class); mState = mock(MethodState.class); node = mock(ExecutionNode.class); location = mock(MethodLocation.class); when(location.getCodeAddress()).thenReturn(ADDRESS); ExceptionFactory exceptionFactory = mock(ExceptionFactory.class); when(vm.getExceptionFactory()).thenReturn(exceptionFactory); addressToLocation = new TIntObjectHashMap<MethodLocation>(); addressToLocation.put(ADDRESS, location); opFactory = new BinaryMathOpFactory(); }
@Before public void setUp() { vm = mock(VirtualMachine.class); classManager = mock(ClassManager.class); when(vm.getClassManager()).thenReturn(classManager); location = mock(MethodLocation.class); instruction = mock(BuilderInstruction.class, withSettings().extraInterfaces(SwitchPayload.class)); when(location.getInstruction()).thenReturn(instruction); when(location.getCodeAddress()).thenReturn(ADDRESS); when(instruction.getLocation()).thenReturn(location); when(instruction.getCodeUnits()).thenReturn(0); addressToLocation = new TIntObjectHashMap<MethodLocation>(); addressToLocation.put(ADDRESS, location); opFactory = new SwitchPayloadOpFactory(); }
@Before public void setUp() { vm = mock(VirtualMachine.class); mState = mock(MethodState.class); node = mock(ExecutionNode.class); item = mock(HeapItem.class); when(mState.readRegister(REGISTER_B)).thenReturn(item); location = mock(MethodLocation.class); instruction = mock(BuilderInstruction.class, withSettings().extraInterfaces(Instruction12x.class)); when(location.getInstruction()).thenReturn(instruction); when(location.getCodeAddress()).thenReturn(ADDRESS); when(instruction.getLocation()).thenReturn(location); when(instruction.getCodeUnits()).thenReturn(0); when(((Instruction12x) instruction).getRegisterA()).thenReturn(REGISTER_A); when(((Instruction12x) instruction).getRegisterB()).thenReturn(REGISTER_B); addressToLocation = new TIntObjectHashMap<MethodLocation>(); addressToLocation.put(ADDRESS, location); opFactory = new UnaryMathOpFactory(); }
private static int[] buildTerminatingAddresses(List<BuilderInstruction> instructions) { TIntList addresses = new TIntLinkedList(); for (BuilderInstruction instruction : instructions) { int address = instruction.getLocation().getCodeAddress(); Opcode op = instruction.getOpcode(); switch (op) { case RETURN_VOID: case RETURN: case RETURN_WIDE: case RETURN_OBJECT: case THROW: break; default: continue; } addresses.add(address); } return addresses.toArray(); }
@Before public void setUp() { vm = mock(VirtualMachine.class); node = mock(ExecutionNode.class); mState = mock(MethodState.class); location = mock(MethodLocation.class); instruction = mock(BuilderInstruction.class, withSettings().extraInterfaces(Instruction3rc.class, VariableRegisterInstruction.class, ReferenceInstruction.class, RegisterRangeInstruction.class)); when(location.getInstruction()).thenReturn(instruction); when(location.getCodeAddress()).thenReturn(ADDRESS); when(instruction.getLocation()).thenReturn(location); when(instruction.getCodeUnits()).thenReturn(0); Reference ref = new ImmutableTypeReference("[I"); when(((ReferenceInstruction) instruction).getReference()).thenReturn(ref); addressToLocation = new TIntObjectHashMap<MethodLocation>(); addressToLocation.put(ADDRESS, location); opFactory = new FilledNewArrayOpFactory(); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { MethodLocation child = Utils.getNextLocation(location, addressToLocation); int address = location.getCodeAddress(); int branchOffset = ((OffsetInstruction) location.getInstruction()).getCodeOffset(); int targetAddress = address + branchOffset; MethodLocation target = addressToLocation.get(targetAddress); Instruction31t instr = (Instruction31t) location.getInstruction(); int register = instr.getRegisterA(); return new SwitchOp(location, child, target, register); }
@Override public void execute(ExecutionNode node, MethodState mState) { // Pseudo points to instruction *after* switch op. MethodLocation returnLocation = mState.getPseudoInstructionReturnInstruction(); int branchFromAddress = returnLocation.getCodeAddress() - SWITCH_OP_CODE_UNITS; HeapItem targetItem = mState.readResultRegister(); if (targetItem.isUnknown()) { List<MethodLocation> childList = getTargets(branchFromAddress, targetKeyToOffset); childList.add(returnLocation); MethodLocation[] children = childList.toArray(new MethodLocation[childList.size()]); node.setChildLocations(children); return; } int targetKey = Utils.getIntegerValue(targetItem.getValue()); if (targetKeyToOffset.containsKey(targetKey)) { int targetOffset = branchFromAddress + targetKeyToOffset.get(targetKey); MethodLocation child = addressToLocation.get(targetOffset); node.setChildLocations(child); return; } // Branch target is unspecified. Continue to next op. node.setChildLocations(returnLocation); }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { BuilderInstruction instruction = (BuilderInstruction) location.getInstruction(); int address = instruction.getLocation().getCodeAddress(); int returnAddress = address + instruction.getCodeUnits(); MethodLocation returnLocation = addressToLocation.get(returnAddress); int branchOffset = ((OffsetInstruction) instruction).getCodeOffset(); int childAddress = address + branchOffset; MethodLocation child = addressToLocation.get(childAddress); Instruction31t instr = (Instruction31t) location.getInstruction(); int register = instr.getRegisterA(); return new FillArrayDataOp(location, child, returnLocation, register); } }
@Override public Op create(MethodLocation location, TIntObjectMap<MethodLocation> addressToLocation, VirtualMachine vm) { BuilderInstruction instruction = (BuilderInstruction) location.getInstruction(); int address = instruction.getLocation().getCodeAddress(); int branchOffset = ((OffsetInstruction) instruction).getCodeOffset(); int targetAddress = address + branchOffset; MethodLocation child = Utils.getNextLocation(location, addressToLocation); MethodLocation target = addressToLocation.get(targetAddress); String opName = instruction.getOpcode().name; IfType ifType = getIfType(opName); int register1 = ((OneRegisterInstruction) instruction).getRegisterA(); if (instruction instanceof Instruction22t) { // if-* vA, vB, :label Instruction22t instr = (Instruction22t) location.getInstruction(); return new IfOp(location, child, ifType, target, register1, instr.getRegisterB()); } else { // if-*z vA, vB, :label (Instruction 21t) return new IfOp(location, child, ifType, target, register1); } }