private static Set<Integer> getNormalRegistersAssigned(MethodState mState) { Set<Integer> assigned = new HashSet<>(); for (int register : mState.getRegistersAssigned()) { if (register < 0) { continue; } assigned.add(register); } for (int i = 0; i < mState.getParameterCount(); i++) { int parameterRegister = mState.getParameterStart() + i; assigned.remove(parameterRegister); } return assigned; }
@Override public void execute(ExecutionNode node, MethodState mState) { MethodState parent = mState.getParent(); int targetRegister = parent.getRegistersAssigned()[0]; // Peek rather than read. This pseudo-instruction shouldn't count as an actual usage for the optimizer. HeapItem arrayItem = mState.peekRegister(targetRegister); if (!arrayItem.isUnknown()) { Object array = arrayItem.getValue(); Class<?> expectedClass = array.getClass().getComponentType(); for (int i = 0; i < arrayElements.size(); i++) { Number number = arrayElements.get(i); Object value = getProperValue(number, expectedClass); Array.set(array, i, value); } // Poke rather than assign for the optimizer. mState.pokeRegister(targetRegister, arrayItem); } MethodLocation returnLocation = mState.getParent().getPseudoInstructionReturnInstruction(); node.setChildLocations(returnLocation); }
private static void testException(String methodDescriptor, Class<?> exceptionClass, String exceptionMessage, VMState initial) { ExecutionGraph graph = VMTester.execute(CLASS_NAME, methodDescriptor, initial); HeapItem item = graph.getTerminatingRegisterConsensus(0); Assert.assertEquals(exceptionClass, item.getValue().getClass()); Assert.assertEquals(ClassNameUtils.toInternal(exceptionClass), item.getType()); Assert.assertEquals(exceptionMessage, ((Throwable) item.getValue()).getMessage()); assertFalse("Should not reach next instruction in non-exception execution path", graph.wasAddressReached(1)); MethodState mState = graph.getNodePile(0).get(0).getContext().getMethodState(); Assert.assertEquals(0, mState.getRegistersAssigned().length); }
@Test public void removeInstructionWithParentModifiesStateCorrectly() { //@formatter:off Object[][] expected = new Object[][] { { 0, Opcode.CONST_4, new Object[][][] { { { 1, Opcode.CONST_4 } } } }, { 1, Opcode.CONST_4, new Object[][][] { { { 2, Opcode.CONST_4 } } } }, { 2, Opcode.CONST_4, new Object[][][] { { { 3, Opcode.CONST_4 } } } }, { 3, Opcode.CONST_4, new Object[][][] { { { 4, Opcode.RETURN_VOID } } } }, { 4, Opcode.RETURN_VOID, new Object[1][0][0] }, }; //@formatter:on manipulator = OptimizerTester.getGraphManipulator(CLASS_NAME, "verySimple()V"); manipulator.removeInstruction(1); test(expected, manipulator); testHeritage(manipulator, 0); testHeritage(manipulator, 1); testHeritage(manipulator, 2); MethodState parentState = manipulator.getNodePile(0).get(0).getContext().getMethodState(); assertArrayEquals(new int[] { 0 }, parentState.getRegistersAssigned()); MethodState childState = manipulator.getNodePile(1).get(0).getContext().getMethodState(); assertArrayEquals(new int[] { 2 }, childState.getRegistersAssigned()); MethodState grandchildState = manipulator.getNodePile(2).get(0).getContext().getMethodState(); assertArrayEquals(new int[] { 3 }, grandchildState.getRegistersAssigned()); }
private static void testException(String methodDescriptor, Class<?> exceptionClass, String exceptionMessage, VMState initial) { ExecutionGraph graph = VMTester.execute(CLASS_NAME, methodDescriptor, initial); HeapItem item = graph.getTerminatingRegisterConsensus(0); Assert.assertEquals(exceptionClass, item.getValue().getClass()); Assert.assertEquals(ClassNameUtils.toInternal(exceptionClass), item.getType()); Assert.assertEquals(exceptionMessage, ((Throwable) item.getValue()).getMessage()); assertFalse("Should not reach next instruction in non-exception execution path", graph.wasAddressReached(1)); MethodState mState = graph.getNodePile(0).get(0).getContext().getMethodState(); Assert.assertEquals(0, mState.getRegistersAssigned().length); }
private static void testException(String methodDescriptor, Class<?> exceptionClass, String exceptionMessage, VMState initial) { ExecutionGraph graph = VMTester.execute(CLASS_NAME, methodDescriptor, initial); HeapItem item = graph.getTerminatingRegisterConsensus(0); Assert.assertEquals(exceptionClass, item.getValue().getClass()); Assert.assertEquals(ClassNameUtils.toInternal(exceptionClass), item.getType()); Assert.assertEquals(exceptionMessage, ((Throwable) item.getValue()).getMessage()); assertFalse("Should not reach next instruction in non-exception execution path", graph.wasAddressReached(1)); MethodState mState = graph.getNodePile(0).get(0).getContext().getMethodState(); Assert.assertEquals(0, mState.getRegistersAssigned().length); }
private static void testException(String methodDescriptor, Class<?> exceptionClass, VMState initial) { ExecutionGraph graph = VMTester.execute(CLASS_NAME, methodDescriptor, initial); HeapItem item = graph.getTerminatingRegisterConsensus(0); Assert.assertEquals(exceptionClass, item.getValue().getClass()); Assert.assertEquals(ClassNameUtils.toInternal(exceptionClass), item.getType()); assertFalse("Should not reach next instruction in non-exception execution path", graph.wasAddressReached(2)); MethodState mState = graph.getNodePile(0).get(0).getContext().getMethodState(); Assert.assertEquals(0, mState.getRegistersAssigned().length); }
private static void testException(String methodDescriptor, Class<?> exceptionClass) { ExecutionGraph graph = VMTester.execute(CLASS_NAME, methodDescriptor); HeapItem item = graph.getTerminatingRegisterConsensus(0); assertEquals(exceptionClass, item.getValue().getClass()); assertEquals(ClassNameUtils.toInternal(exceptionClass), item.getType()); assertFalse(graph.wasAddressReached(2)); MethodState mState = graph.getNodePile(0).get(0).getContext().getMethodState(); assertEquals(0, mState.getRegistersAssigned().length); }
private static void testException(String methodDescriptor, Class<?> exceptionClass, VMState initial) { ExecutionGraph graph = VMTester.execute(CLASS_NAME, methodDescriptor, initial); HeapItem item = graph.getTerminatingRegisterConsensus(0); assertEquals(exceptionClass, item.getValue().getClass()); assertEquals(ClassNameUtils.toInternal(exceptionClass), item.getType()); assertFalse("Should not reach next instruction in non-exception execution path", graph.wasAddressReached(2)); MethodState mState = graph.getNodePile(0).get(0).getContext().getMethodState(); assertEquals(0, mState.getRegistersAssigned().length); }