diff options
Diffstat (limited to 'src/proguard/optimize/evaluation/PartialEvaluator.java')
-rw-r--r-- | src/proguard/optimize/evaluation/PartialEvaluator.java | 141 |
1 files changed, 64 insertions, 77 deletions
diff --git a/src/proguard/optimize/evaluation/PartialEvaluator.java b/src/proguard/optimize/evaluation/PartialEvaluator.java index b2776d1..5790a36 100644 --- a/src/proguard/optimize/evaluation/PartialEvaluator.java +++ b/src/proguard/optimize/evaluation/PartialEvaluator.java @@ -2,7 +2,7 @@ * ProGuard -- shrinking, optimization, obfuscation, and preverification * of Java bytecode. * - * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu) + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -31,8 +31,6 @@ import proguard.evaluation.*; import proguard.evaluation.value.*; import proguard.optimize.peephole.BranchTargetFinder; -import java.util.Arrays; - /** * This AttributeVisitor performs partial evaluation on the code attributes * that it visits. @@ -70,6 +68,7 @@ implements AttributeVisitor, private TracedStack[] stacksAfter = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH]; private boolean[] generalizedContexts = new boolean[ClassConstants.TYPICAL_CODE_LENGTH]; private int[] evaluationCounts = new int[ClassConstants.TYPICAL_CODE_LENGTH]; + private int[] initializedVariables = new int[ClassConstants.TYPICAL_CODE_LENGTH]; private boolean evaluateExceptions; private final BasicBranchUnit branchUnit; @@ -190,47 +189,6 @@ implements AttributeVisitor, if (DEBUG) { method.accept(clazz, new ClassPrinter()); - - System.out.println("Evaluation results:"); - - int offset = 0; - do - { - if (isBranchOrExceptionTarget(offset)) - { - System.out.println("Branch target from ["+branchOriginValues[offset]+"]:"); - if (isTraced(offset)) - { - System.out.println(" Vars: "+variablesBefore[offset]); - System.out.println(" Stack: "+stacksBefore[offset]); - } - } - - Instruction instruction = InstructionFactory.create(codeAttribute.code, - offset); - System.out.println(instruction.toString(offset)); - - if (isTraced(offset)) - { - int initializationOffset = branchTargetFinder.initializationOffset(offset); - if (initializationOffset != NONE) - { - System.out.println(" is to be initialized at ["+initializationOffset+"]"); - } - - InstructionOffsetValue branchTargets = branchTargets(offset); - if (branchTargets != null) - { - System.out.println(" has overall been branching to "+branchTargets); - } - - System.out.println(" Vars: "+variablesAfter[offset]); - System.out.println(" Stack: "+stacksAfter[offset]); - } - - offset += instruction.length(offset); - } - while (offset < codeAttribute.u4codeLength); } throw ex; @@ -254,8 +212,7 @@ implements AttributeVisitor, TracedStack stack = new TracedStack(codeAttribute.u2maxStack); // Initialize the reusable arrays and variables. - initializeArrays(codeAttribute); - initializeParameters(clazz, method, codeAttribute, variables); + initializeVariables(clazz, method, codeAttribute, variables, stack); // Find all instruction offsets,... codeAttribute.accept(clazz, method, branchTargetFinder); @@ -292,6 +249,12 @@ implements AttributeVisitor, if (isTraced(offset)) { + int variableIndex = initializedVariable(offset); + if (variableIndex >= 0) + { + System.out.println(" is initializing variable v"+variableIndex); + } + int initializationOffset = branchTargetFinder.initializationOffset(offset); if (initializationOffset != NONE) { @@ -516,6 +479,16 @@ implements AttributeVisitor, } + /** + * Returns the variable that is initialized at the given instruction offset, + * or <code>NONE</code> if no variable was initialized. + */ + public int initializedVariable(int instructionOffset) + { + return initializedVariables[instructionOffset]; + } + + // Utility methods to evaluate instruction blocks. /** @@ -729,6 +702,9 @@ implements AttributeVisitor, // Reset the trace value. InstructionOffsetValue traceValue = InstructionOffsetValue.EMPTY_VALUE; + // Reset the initialization flag. + variables.resetInitialization(); + // Note that the instruction is only volatile. Instruction instruction = InstructionFactory.create(code, instructionOffset); @@ -767,6 +743,9 @@ implements AttributeVisitor, throw ex; } + // Collect the offsets of the instructions whose results were used. + initializedVariables[instructionOffset] = variables.getInitializationIndex(); + // Collect the branch targets from the branch unit. InstructionOffsetValue branchTargets = branchUnit.getTraceBranchTargets(); int branchTargetCount = branchTargets.instructionOffsetCount(); @@ -917,7 +896,11 @@ implements AttributeVisitor, subroutinePartialEvaluator = new PartialEvaluator(this); - subroutinePartialEvaluator.initializeArrays(codeAttribute); + subroutinePartialEvaluator.initializeVariables(clazz, + method, + codeAttribute, + variables, + stack); } // Evaluate the subroutine. @@ -969,12 +952,13 @@ implements AttributeVisitor, if (evaluationCounts[offset] == 0) { - variablesBefore[offset] = other.variablesBefore[offset]; - stacksBefore[offset] = other.stacksBefore[offset]; - variablesAfter[offset] = other.variablesAfter[offset]; - stacksAfter[offset] = other.stacksAfter[offset]; - generalizedContexts[offset] = other.generalizedContexts[offset]; - evaluationCounts[offset] = other.evaluationCounts[offset]; + variablesBefore[offset] = other.variablesBefore[offset]; + stacksBefore[offset] = other.stacksBefore[offset]; + variablesAfter[offset] = other.variablesAfter[offset]; + stacksAfter[offset] = other.stacksAfter[offset]; + generalizedContexts[offset] = other.generalizedContexts[offset]; + evaluationCounts[offset] = other.evaluationCounts[offset]; + initializedVariables[offset] = other.initializedVariables[offset]; } else { @@ -984,6 +968,7 @@ implements AttributeVisitor, stacksAfter[offset] .generalize(other.stacksAfter[offset]); //generalizedContexts[offset] evaluationCounts[offset] += other.evaluationCounts[offset]; + //initializedVariables[offset] } } } @@ -1109,7 +1094,11 @@ implements AttributeVisitor, /** * Initializes the data structures for the variables, stack, etc. */ - private void initializeArrays(CodeAttribute codeAttribute) + private void initializeVariables(Clazz clazz, + Method method, + CodeAttribute codeAttribute, + TracedVariables variables, + TracedStack stack) { int codeLength = codeAttribute.u4codeLength; @@ -1117,25 +1106,33 @@ implements AttributeVisitor, if (variablesAfter.length < codeLength) { // Create new arrays. - branchOriginValues = new InstructionOffsetValue[codeLength]; - branchTargetValues = new InstructionOffsetValue[codeLength]; - variablesBefore = new TracedVariables[codeLength]; - stacksBefore = new TracedStack[codeLength]; - variablesAfter = new TracedVariables[codeLength]; - stacksAfter = new TracedStack[codeLength]; - generalizedContexts = new boolean[codeLength]; - evaluationCounts = new int[codeLength]; + branchOriginValues = new InstructionOffsetValue[codeLength]; + branchTargetValues = new InstructionOffsetValue[codeLength]; + variablesBefore = new TracedVariables[codeLength]; + stacksBefore = new TracedStack[codeLength]; + variablesAfter = new TracedVariables[codeLength]; + stacksAfter = new TracedStack[codeLength]; + generalizedContexts = new boolean[codeLength]; + evaluationCounts = new int[codeLength]; + initializedVariables = new int[codeLength]; + + // Reset the arrays. + for (int index = 0; index < codeLength; index++) + { + initializedVariables[index] = NONE; + } } else { // Reset the arrays. - Arrays.fill(branchOriginValues, null); - Arrays.fill(branchTargetValues, null); - Arrays.fill(generalizedContexts, false); - Arrays.fill(evaluationCounts, 0); - for (int index = 0; index < codeLength; index++) { + branchOriginValues[index] = null; + branchTargetValues[index] = null; + generalizedContexts[index] = false; + evaluationCounts[index] = 0; + initializedVariables[index] = NONE; + if (variablesBefore[index] != null) { variablesBefore[index].reset(codeAttribute.u2maxLocals); @@ -1157,17 +1154,7 @@ implements AttributeVisitor, } } } - } - - /** - * Initializes the data structures for the variables, stack, etc. - */ - private void initializeParameters(Clazz clazz, - Method method, - CodeAttribute codeAttribute, - TracedVariables variables) - { // Create the method parameters. TracedVariables parameters = new TracedVariables(codeAttribute.u2maxLocals); |