aboutsummaryrefslogtreecommitdiffstats
path: root/src/proguard/optimize/evaluation/EvaluationShrinker.java
diff options
context:
space:
mode:
authorYing Wang <wangying@google.com>2012-02-27 18:34:24 -0800
committerYing Wang <wangying@google.com>2012-02-27 18:34:24 -0800
commit9f606f95f03a75961498803e24bee6799a7c0885 (patch)
treea45f4d74feda9b76277a0c9ced55ad15d82248a1 /src/proguard/optimize/evaluation/EvaluationShrinker.java
parentcfead78069f3dc32998dc118ee08cab3867acea2 (diff)
downloadandroid_external_proguard-jellybean.tar.gz
android_external_proguard-jellybean.tar.bz2
android_external_proguard-jellybean.zip
This reverts commit cfead78069f3dc32998dc118ee08cab3867acea2. Bug: 6079915
Diffstat (limited to 'src/proguard/optimize/evaluation/EvaluationShrinker.java')
-rw-r--r--src/proguard/optimize/evaluation/EvaluationShrinker.java290
1 files changed, 60 insertions, 230 deletions
diff --git a/src/proguard/optimize/evaluation/EvaluationShrinker.java b/src/proguard/optimize/evaluation/EvaluationShrinker.java
index bc5f658..1463feb 100644
--- a/src/proguard/optimize/evaluation/EvaluationShrinker.java
+++ b/src/proguard/optimize/evaluation/EvaluationShrinker.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
@@ -34,8 +34,6 @@ import proguard.evaluation.*;
import proguard.evaluation.value.*;
import proguard.optimize.info.*;
-import java.util.Arrays;
-
/**
* This AttributeVisitor simplifies the code attributes that it visits, based
* on partial evaluation.
@@ -57,14 +55,13 @@ implements AttributeVisitor
private final InstructionVisitor extraDeletedInstructionVisitor;
private final InstructionVisitor extraAddedInstructionVisitor;
- private final PartialEvaluator partialEvaluator;
- private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator();
- private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true);
- private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier();
- private final MyProducerMarker producerMarker = new MyProducerMarker();
- private final MyVariableInitializationMarker variableInitializationMarker = new MyVariableInitializationMarker();
- private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer();
- private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
+ private final PartialEvaluator partialEvaluator;
+ private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator();
+ private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true);
+ private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier();
+ private final MyProducerMarker producerMarker = new MyProducerMarker();
+ private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer();
+ private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
private boolean[][] variablesNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_VARIABLES_SIZE];
private boolean[][] stacksNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_STACK_SIZE];
@@ -279,10 +276,18 @@ implements AttributeVisitor
if (partialEvaluator.isTraced(offset) &&
!isInstructionNecessary(offset))
{
- Instruction instruction = InstructionFactory.create(codeAttribute.code,
- offset);
-
- instruction.accept(clazz, method, codeAttribute, offset, variableInitializationMarker);
+ // Is the corresponding variable necessary anywhere in the code,
+ // accoriding to a simple partial evaluation?
+ int variableIndex = partialEvaluator.initializedVariable(offset);
+ if (variableIndex >= 0 &&
+ isVariableInitializationNecessary(clazz,
+ method,
+ codeAttribute,
+ offset,
+ variableIndex))
+ {
+ markInstruction(offset);
+ }
}
}
if (DEBUG) System.out.println();
@@ -462,9 +467,7 @@ implements AttributeVisitor
*/
private class MyUnusedParameterSimplifier
extends SimplifiedVisitor
- implements InstructionVisitor,
- ConstantVisitor,
- MemberVisitor
+ implements InstructionVisitor, ConstantVisitor, MemberVisitor
{
private int invocationOffset;
private ConstantInstruction invocationInstruction;
@@ -654,40 +657,6 @@ implements AttributeVisitor
/**
- * This InstructionVisitor marks variable initializations that are
- * necessary to appease the JVM.
- */
- private class MyVariableInitializationMarker
- extends SimplifiedVisitor
- implements InstructionVisitor
- {
- // Implementations for InstructionVisitor.
-
- public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
-
-
- public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
- {
- if (!variableInstruction.isLoad())
- {
- int variableIndex = variableInstruction.variableIndex;
-
- if (isVariableInitialization(offset,
- variableIndex) &&
- isVariableInitializationNecessary(clazz,
- method,
- codeAttribute,
- offset,
- variableIndex))
- {
- markInstruction(offset);
- }
- }
- }
- }
-
-
- /**
* This InstructionVisitor fixes instructions locally, popping any unused
* produced stack entries after marked instructions, and popping produced
* stack entries and pushing missing stack entries instead of unmarked
@@ -718,23 +687,12 @@ implements AttributeVisitor
int requiredPushCount = 0;
for (int stackIndex = 0; stackIndex < popCount; stackIndex++)
{
- InstructionOffsetValue producerOffsets =
- tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue();
-
- if (!isStackSimplifiedBefore(offset, top - stackIndex))
+ // Is the stack entry required by other consumers?
+ if (!isStackSimplifiedBefore(offset, top - stackIndex) &&
+ !isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex))
{
- // Is the stack entry pushed by any producer,
- // because it is required by other consumers?
- if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex))
- {
- // Make sure it is pushed after all producers.
- markStackEntriesAfter(producerOffsets, top - stackIndex);
- }
- else
- {
- // Remember to push it.
- requiredPushCount++;
- }
+ // Remember to push it.
+ requiredPushCount++;
}
}
@@ -799,16 +757,9 @@ implements AttributeVisitor
int expectedPopCount = 0;
for (int stackIndex = 0; stackIndex < popCount; stackIndex++)
{
- InstructionOffsetValue producerOffsets =
- tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue();
-
- // Is the stack entry pushed by any producer,
- // because it is required by other consumers?
- if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex))
+ // Is the stack entry required by other consumers?
+ if (isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex))
{
- // Make sure it is pushed after all producers.
- markStackEntriesAfter(producerOffsets, top - stackIndex);
-
// Remember to pop it.
expectedPopCount++;
}
@@ -1101,7 +1052,6 @@ implements AttributeVisitor
byte oldOpcode = instruction.opcode;
byte newOpcode = 0;
- byte addOpcode = 0;
// Simplify the popping instruction if possible.
switch (oldOpcode)
@@ -1282,20 +1232,9 @@ implements AttributeVisitor
stackEntryPresent1)
{
// Will both elements be present?
- if (!stackEntryPresent1)
- {
- // Pop the original top element (later bottom element).
- newOpcode = InstructionConstants.OP_POP;
- }
- else if (!stackEntryPresent0)
- {
- // Swap both elements and pop the top one.
- newOpcode = InstructionConstants.OP_SWAP;
- addOpcode = InstructionConstants.OP_POP;
- }
- else
+ if (stackEntryPresent0 &&
+ stackEntryPresent1)
{
- // Just swap both elements.
newOpcode = InstructionConstants.OP_SWAP;
}
}
@@ -1303,7 +1242,6 @@ implements AttributeVisitor
}
}
- // Is there a replacement opcode?
if (newOpcode == 0)
{
// Delete the instruction.
@@ -1332,21 +1270,6 @@ implements AttributeVisitor
if (DEBUG) System.out.println(" Replacing instruction "+instruction.toString(dupOffset)+" by "+replacementInstruction.toString());
}
-
- // Is there an additional opcode?
- if (addOpcode != 0)
- {
- // Add the instruction.
- Instruction additionalInstruction = new SimpleInstruction(addOpcode);
- codeAttributeEditor.insertAfterInstruction(dupOffset, additionalInstruction);
-
- if (extraAddedInstructionVisitor != null)
- {
- extraAddedInstructionVisitor.visitSimpleInstruction(null, null, null, dupOffset, null);
- }
-
- if (DEBUG) System.out.println(" Adding instruction "+additionalInstruction.toString(dupOffset));
- }
}
@@ -1673,7 +1596,10 @@ implements AttributeVisitor
{
for (int offset = 0; offset < codeLength; offset++)
{
- Arrays.fill(variablesNecessaryAfter[offset], 0, maxLocals, false);
+ for (int index = 0; index < maxLocals; index++)
+ {
+ variablesNecessaryAfter[offset][index] = false;
+ }
}
}
@@ -1686,7 +1612,10 @@ implements AttributeVisitor
{
for (int offset = 0; offset < codeLength; offset++)
{
- Arrays.fill(stacksNecessaryAfter[offset], 0, maxStack, false);
+ for (int index = 0; index < maxStack; index++)
+ {
+ stacksNecessaryAfter[offset][index] = false;
+ }
}
}
@@ -1699,7 +1628,10 @@ implements AttributeVisitor
{
for (int offset = 0; offset < codeLength; offset++)
{
- Arrays.fill(stacksSimplifiedBefore[offset], 0, maxStack, false);
+ for (int index = 0; index < maxStack; index++)
+ {
+ stacksSimplifiedBefore[offset][index] = false;
+ }
}
}
@@ -1709,7 +1641,10 @@ implements AttributeVisitor
}
else
{
- Arrays.fill(instructionsNecessary, 0, codeLength, false);
+ for (int index = 0; index < codeLength; index++)
+ {
+ instructionsNecessary[index] = false;
+ }
}
}
@@ -1735,34 +1670,6 @@ implements AttributeVisitor
/**
- * Returns whether the specified variable is initialized at the specified
- * offset.
- */
- private boolean isVariableInitialization(int instructionOffset,
- int variableIndex)
- {
- // Wasn't the variable set yet?
- Value valueBefore = partialEvaluator.getVariablesBefore(instructionOffset).getValue(variableIndex);
- if (valueBefore == null)
- {
- return true;
- }
-
- // Is the computational type different now?
- Value valueAfter = partialEvaluator.getVariablesAfter(instructionOffset).getValue(variableIndex);
- if (valueAfter.computationalType() != valueBefore.computationalType())
- {
- return true;
- }
-
- // Was the producer an argument (which may be removed)?
- Value producersBefore = partialEvaluator.getVariablesBefore(instructionOffset).getProducerValue(variableIndex);
- return producersBefore.instructionOffsetValue().instructionOffsetCount() == 1 &&
- producersBefore.instructionOffsetValue().instructionOffset(0) == PartialEvaluator.AT_METHOD_ENTRY;
- }
-
-
- /**
* Returns whether the specified variable must be initialized at the
* specified offset, according to the verifier of the JVM.
*/
@@ -1779,8 +1686,8 @@ implements AttributeVisitor
{
if (DEBUG) System.out.println("Simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]");
- // Lazily perform simple partial evaluation, the way the JVM
- // verifier would do it.
+ // Lazily compute perform simple partial evaluation, the way the
+ // JVM preverifier would do it.
simplePartialEvaluator.visitCodeAttribute(clazz, method, codeAttribute);
if (DEBUG) System.out.println("End of simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]");
@@ -1788,7 +1695,7 @@ implements AttributeVisitor
// Check if the variable is necessary elsewhere.
for (int offset = 0; offset < codeLength; offset++)
{
- if (partialEvaluator.isTraced(offset))
+ if (isInstructionNecessary(offset))
{
Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(variableIndex);
if (producer != null)
@@ -1801,22 +1708,16 @@ implements AttributeVisitor
InstructionOffsetValue simpleProducerOffsets =
simpleProducer.instructionOffsetValue();
- if (DEBUG)
+ // Does the sophisticated partial evaluation have fewer
+ // producers than the simple one?
+ // And does the simple partial evaluation point to an
+ // initialization of the variable?
+ if (producerOffsets.instructionOffsetCount() <
+ simpleProducerOffsets.instructionOffsetCount() &&
+ isVariableNecessaryAfterAny(producerOffsets, variableIndex) &&
+ simpleProducerOffsets.contains(initializationOffset))
{
- System.out.println(" ["+offset+"] producers ["+producerOffsets+"], simple producers ["+simpleProducerOffsets+"]");
- }
-
- // Is the variable being used without all of its
- // immediate simple producers being marked?
- if (isVariableNecessaryAfterAny(producerOffsets, variableIndex) &&
- !isVariableNecessaryAfterAll(simpleProducerOffsets, variableIndex))
- {
- if (DEBUG)
- {
- System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] necessary");
- }
-
- // Then the initialization may be necessary.
+ // Then the initialization is necessary.
return true;
}
}
@@ -1825,11 +1726,6 @@ implements AttributeVisitor
}
}
- if (DEBUG)
- {
- System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] not necessary");
- }
-
return false;
}
@@ -1853,7 +1749,7 @@ implements AttributeVisitor
/**
* Returns whether the specified variable is ever necessary after any
- * instructions in the specified block.
+ * instruction in the specified block.
*/
private boolean isVariableNecessaryAfterAny(int startOffset,
int endOffset,
@@ -1873,7 +1769,7 @@ implements AttributeVisitor
/**
* Returns whether the specified variable is ever necessary after any
- * instructions in the specified set of instructions offsets.
+ * instruction in the specified set of instructions offsets.
*/
private boolean isVariableNecessaryAfterAny(InstructionOffsetValue instructionOffsetValue,
int variableIndex)
@@ -1893,28 +1789,6 @@ implements AttributeVisitor
}
- /**
- * Returns whether the specified variable is ever necessary after all
- * instructions in the specified set of instructions offsets.
- */
- private boolean isVariableNecessaryAfterAll(InstructionOffsetValue instructionOffsetValue,
- int variableIndex)
- {
- int count = instructionOffsetValue.instructionOffsetCount();
-
- for (int index = 0; index < count; index++)
- {
- if (!isVariableNecessaryAfter(instructionOffsetValue.instructionOffset(index),
- variableIndex))
- {
- return false;
- }
- }
-
- return true;
- }
-
-
private boolean isVariableNecessaryAfter(int instructionOffset,
int variableIndex)
{
@@ -1923,36 +1797,6 @@ implements AttributeVisitor
}
- /**
- * Marks the stack entries after the given offsets.
- * @param instructionOffsets the offsets of the stack entries to be marked.
- * @param stackIndex the index of the stack entries to be marked
- * (counting from the bottom).
- */
- private void markStackEntriesAfter(InstructionOffsetValue instructionOffsets,
- int stackIndex)
- {
- if (instructionOffsets != null)
- {
- int offsetCount = instructionOffsets.instructionOffsetCount();
- for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
- {
- // Make sure the stack entry and the instruction are marked
- // at the producing offset.
- int offset = instructionOffsets.instructionOffset(offsetIndex);
-
- markStackEntryAfter(offset, stackIndex);
- }
- }
- }
-
-
- /**
- * Marks the stack entry after the given offset.
- * @param instructionOffset the offset of the stack entry to be marked.
- * @param stackIndex the index of the stack entry to be marked
- * (counting from the bottom).
- */
private void markStackEntryAfter(int instructionOffset,
int stackIndex)
{
@@ -1970,13 +1814,6 @@ implements AttributeVisitor
}
- /**
- * Returns whether any of the stack entries after the given offsets are
- * necessary.
- * @param instructionOffsets the offsets of the stack entries to be checked.
- * @param stackIndex the index of the stack entries to be checked
- * (counting from the bottom).
- */
private boolean isAnyStackEntryNecessaryAfter(InstructionOffsetValue instructionOffsets,
int stackIndex)
{
@@ -1994,13 +1831,6 @@ implements AttributeVisitor
}
- /**
- * Returns whether any of the stack entries after the given offset are
- * necessary.
- * @param instructionOffset the offset of the stack entry to be checked.
- * @param stackIndex the index of the stack entry to be checked
- * (counting from the bottom).
- */
private boolean isStackEntryNecessaryAfter(int instructionOffset,
int stackIndex)
{