/** * Returns whether any traced but unnecessary instruction between the two * given offsets is branching over the second given offset. */ private boolean isAnyUnnecessaryInstructionBranchingOver(int instructionOffset1, int instructionOffset2) { for (int offset = instructionOffset1; offset < instructionOffset2; offset++) { // Is it a traced but unmarked straddling branch? if (partialEvaluator.isTraced(offset) && !isInstructionNecessary(offset) && isAnyLargerThan(partialEvaluator.branchTargets(offset), instructionOffset2)) { return true; } } return false; }
/** * Pushes a specified type of stack entry before or at the given offset. * The instruction is marked as necessary. */ private void insertPushInstructions(int offset, boolean replace, boolean before, int computationalType) { // We can edit an instruction without marking it. //markInstruction(offset); // Create a simple push instrucion. Instruction replacementInstruction = new SimpleInstruction(pushOpcode(computationalType)); if (DEBUG) System.out.println(": "+replacementInstruction.toString(offset)); // Replace or insert the push instruction. insertInstruction(offset, replace, before, replacementInstruction); }
visitCodeAttribute0(clazz, method, codeAttribute);
new SimpleInstruction(InstructionConstants.OP_POP); insertInstruction(offset, replace, before, popInstruction); break; new SimpleInstruction(InstructionConstants.OP_POP2); insertInstruction(offset, replace, before, popInstruction); break; insertInstructions(offset, replace, before,
initializeNecessary(codeAttribute); markInstruction(superInitializationOffset); markInstruction(offset); markInstruction(offset); if (isInstructionNecessary(offset)) markStraddlingBranches(offset, partialEvaluator.branchTargets(offset), true); markStraddlingBranches(offset, partialEvaluator.branchOrigins(offset), false); !isInstructionNecessary(offset)) isVariableInitializationNecessary(clazz, method, codeAttribute, markInstruction(offset); markStraddlingBranches(offset, partialEvaluator.branchTargets(offset), true);
public ClassVisitor createClassVisitor() { // Perform partial evaluation again, now loading any previously stored // values for fields, method parameters, and method return values. ValueFactory valueFactory = new IdentifiedValueFactory(); SimplifiedInvocationUnit loadingInvocationUnit = new LoadingInvocationUnit(valueFactory, fieldPropagationValue, methodPropagationParameter, methodPropagationReturnvalue); // Trace the construction of reference values. ReferenceTracingValueFactory referenceTracingValueFactory = new ReferenceTracingValueFactory(valueFactory); return new AllMethodVisitor( new AllAttributeVisitor( new DebugAttributeVisitor("Shrinking code", new OptimizationCodeAttributeFilter( new EvaluationShrinker( new InstructionUsageMarker( new PartialEvaluator(referenceTracingValueFactory, new ParameterTracingInvocationUnit(loadingInvocationUnit), !codeSimplificationAdvanced, referenceTracingValueFactory), true), true, deletedCounter, addedCounter))))); } };
/** * Returns whether any traced but unnecessary instruction between the two * given offsets is branching over the second given offset. */ private boolean isAnyUnnecessaryInstructionBranchingOver(int instructionOffset1, int instructionOffset2) { for (int offset = instructionOffset1; offset < instructionOffset2; offset++) { // Is it a traced but unmarked straddling branch? if (instructionUsageMarker.isTraced(offset) && !instructionUsageMarker.isInstructionNecessary(offset) && isAnyLargerThan(instructionUsageMarker.branchTargets(offset), instructionOffset2)) { return true; } } return false; }
/** * Pushes a specified type of stack entry before or at the given offset. * The instruction is marked as necessary. */ private void insertPushInstructions(int offset, boolean replace, int computationalType) { // Mark this instruction. markInstruction(offset); // Create a simple push instrucion. Instruction replacementInstruction = new SimpleInstruction(pushOpcode(computationalType)); if (DEBUG) System.out.println(": "+replacementInstruction.toString(offset)); // Replace or insert the push instruction. if (replace) { // Replace the push instruction. codeAttributeEditor.replaceInstruction(offset, replacementInstruction); } else { // Insert the push instruction. codeAttributeEditor.insertBeforeInstruction(offset, replacementInstruction); if (extraAddedInstructionVisitor != null) { replacementInstruction.accept(null, null, null, offset, extraAddedInstructionVisitor); } } }
new SimpleInstruction(InstructionConstants.OP_POP); insertInstruction(offset, replace, before, popInstruction); break; new SimpleInstruction(InstructionConstants.OP_POP2); insertInstruction(offset, replace, before, popInstruction); break; insertInstructions(offset, replace, before,
public ClassVisitor createClassVisitor() { // Perform partial evaluation again, now loading any previously stored // values for fields, method parameters, and method return values. ValueFactory valueFactory = new IdentifiedValueFactory(); SimplifiedInvocationUnit loadingInvocationUnit = new LoadingInvocationUnit(valueFactory, fieldPropagationValue, methodPropagationParameter, methodPropagationReturnvalue); // Trace the construction of reference values. ReferenceTracingValueFactory referenceTracingValueFactory = new ReferenceTracingValueFactory(valueFactory); return new AllMethodVisitor( new AllAttributeVisitor( new DebugAttributeVisitor("Shrinking code", new OptimizationCodeAttributeFilter( new EvaluationShrinker( new InstructionUsageMarker( new PartialEvaluator(referenceTracingValueFactory, new ParameterTracingInvocationUnit(loadingInvocationUnit), !codeSimplificationAdvanced, referenceTracingValueFactory), true), true, deletedCounter, addedCounter))))); } };
/** * Returns whether any traced but unnecessary instruction between the two * given offsets is branching over the second given offset. */ private boolean isAnyUnnecessaryInstructionBranchingOver(int instructionOffset1, int instructionOffset2) { for (int offset = instructionOffset1; offset < instructionOffset2; offset++) { // Is it a traced but unmarked straddling branch? if (instructionUsageMarker.isTraced(offset) && !instructionUsageMarker.isInstructionNecessary(offset) && isAnyLargerThan(instructionUsageMarker.branchTargets(offset), instructionOffset2)) { return true; } } return false; }
/** * Pushes a specified type of stack entry before or at the given offset. * The instruction is marked as necessary. */ private void insertPushInstructions(int offset, boolean replace, boolean before, int computationalType) { // We can edit an instruction without marking it. //markInstruction(offset); // Create a simple push instrucion. Instruction replacementInstruction = new SimpleInstruction(pushOpcode(computationalType)); if (DEBUG) System.out.println(": "+replacementInstruction.toString(offset)); // Replace or insert the push instruction. insertInstruction(offset, replace, before, replacementInstruction); }
new SimpleInstruction(InstructionConstants.OP_POP); insertInstruction(offset, replace, before, popInstruction); break; new SimpleInstruction(InstructionConstants.OP_POP2); insertInstruction(offset, replace, before, popInstruction); break; insertInstructions(offset, replace, before,
public ClassVisitor createClassVisitor() { // Perform partial evaluation again, now loading any previously stored // values for fields, method parameters, and method return values. ValueFactory valueFactory = new IdentifiedValueFactory(); SimplifiedInvocationUnit loadingInvocationUnit = new LoadingInvocationUnit(valueFactory, fieldPropagationValue, methodPropagationParameter, methodPropagationReturnvalue); // Trace the construction of reference values. ReferenceTracingValueFactory referenceTracingValueFactory = new ReferenceTracingValueFactory(valueFactory); return new AllMethodVisitor( new AllAttributeVisitor( new DebugAttributeVisitor("Shrinking code", new OptimizationCodeAttributeFilter( new EvaluationShrinker( new InstructionUsageMarker( new PartialEvaluator(referenceTracingValueFactory, new ParameterTracingInvocationUnit(loadingInvocationUnit), !codeSimplificationAdvanced, referenceTracingValueFactory), true), true, deletedCounter, addedCounter))))); } };
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) { // DEBUG = DEBUG_RESULTS = // clazz.getName().equals("abc/Def") && // method.getName(clazz).equals("abc"); // TODO: Remove this when the evaluation shrinker has stabilized. // Catch any unexpected exceptions from the actual visiting method. try { // Process the code. visitCodeAttribute0(clazz, method, codeAttribute); } catch (RuntimeException ex) { System.err.println("Unexpected error while shrinking instructions after partial evaluation:"); System.err.println(" Class = ["+clazz.getName()+"]"); System.err.println(" Method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]"); System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")"); System.err.println("Not optimizing this method"); if (DEBUG) { method.accept(clazz, new ClassPrinter()); throw ex; } } }
/** * Returns whether any traced but unnecessary instruction between the two * given offsets is branching over the second given offset. */ private boolean isAnyUnnecessaryInstructionBranchingOver(int instructionOffset1, int instructionOffset2) { for (int offset = instructionOffset1; offset < instructionOffset2; offset++) { // Is it a traced but unmarked straddling branch? if (instructionUsageMarker.isTraced(offset) && !instructionUsageMarker.isInstructionNecessary(offset) && isAnyLargerThan(instructionUsageMarker.branchTargets(offset), instructionOffset2)) { return true; } } return false; }
/** * Pushes a specified type of stack entry before or at the given offset. * The instruction is marked as necessary. */ private void insertPushInstructions(int offset, boolean replace, boolean before, int computationalType) { // We can edit an instruction without marking it. //markInstruction(offset); // Create a simple push instrucion. Instruction replacementInstruction = new SimpleInstruction(pushOpcode(computationalType)); if (DEBUG) System.out.println(": "+replacementInstruction.toString(offset)); // Replace or insert the push instruction. insertInstruction(offset, replace, before, replacementInstruction); }
new AllMethodVisitor( new AllAttributeVisitor( new EvaluationShrinker( new PartialEvaluator(valueFactory, loadingInvocationUnit, !codeSimplificationAdvanced), deletedCounter, addedCounter))));
visitCodeAttribute0(clazz, method, codeAttribute);
visitCodeAttribute0(clazz, method, codeAttribute);