aboutsummaryrefslogtreecommitdiffstats
path: root/src/proguard/optimize/evaluation/PartialEvaluator.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/optimize/evaluation/PartialEvaluator.java')
-rw-r--r--src/proguard/optimize/evaluation/PartialEvaluator.java141
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);