1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59f606f95f03a75961498803e24bee6799a7c0885Ying Wang * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.evaluation; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.evaluation.value.Value; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This Variables class saves additional information with variables, to keep 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * track of their origins. 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p> 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * The Variables class stores a given producer Value along with each Value it 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * stores. It then generalizes a given collected Value with the producer Value 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of each Value it loads. The producer Value and the initial collected Value 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * can be set; the generalized collected Value can be retrieved. 339f606f95f03a75961498803e24bee6799a7c0885Ying Wang * <p> 349f606f95f03a75961498803e24bee6799a7c0885Ying Wang * In addition, an initialization index can be reset and retrieved, pointing 359f606f95f03a75961498803e24bee6799a7c0885Ying Wang * to the most recent variable that has been initialized by a store operation. 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class TracedVariables extends Variables 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public static final int NONE = -1; 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Value producerValue; 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private Variables producerVariables; 469f606f95f03a75961498803e24bee6799a7c0885Ying Wang private int initializationIndex; 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new TracedVariables with a given size. 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public TracedVariables(int size) 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato super(size); 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables = new Variables(size); 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new TracedVariables that is a copy of the given TracedVariables. 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public TracedVariables(TracedVariables tracedVariables) 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato super(tracedVariables); 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables = new Variables(tracedVariables.producerVariables); 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the Value that will be stored along with all store instructions. 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void setProducerValue(Value producerValue) 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.producerValue = producerValue; 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 819f606f95f03a75961498803e24bee6799a7c0885Ying Wang * Resets the initialization index. 829f606f95f03a75961498803e24bee6799a7c0885Ying Wang */ 839f606f95f03a75961498803e24bee6799a7c0885Ying Wang public void resetInitialization() 849f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 859f606f95f03a75961498803e24bee6799a7c0885Ying Wang initializationIndex = NONE; 869f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 879f606f95f03a75961498803e24bee6799a7c0885Ying Wang 889f606f95f03a75961498803e24bee6799a7c0885Ying Wang 899f606f95f03a75961498803e24bee6799a7c0885Ying Wang /** 909f606f95f03a75961498803e24bee6799a7c0885Ying Wang * Returns the most recent initialization index since it has been reset. 919f606f95f03a75961498803e24bee6799a7c0885Ying Wang */ 929f606f95f03a75961498803e24bee6799a7c0885Ying Wang public int getInitializationIndex() 939f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 949f606f95f03a75961498803e24bee6799a7c0885Ying Wang return initializationIndex; 959f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 969f606f95f03a75961498803e24bee6799a7c0885Ying Wang 979f606f95f03a75961498803e24bee6799a7c0885Ying Wang 989f606f95f03a75961498803e24bee6799a7c0885Ying Wang /** 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Gets the producer Value for the specified variable, without disturbing it. 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param index the variable index. 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the producer value of the given variable. 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Value getProducerValue(int index) 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return producerVariables.getValue(index); 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Sets the given producer Value for the specified variable, without 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * disturbing it. 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param index the variable index. 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param value the producer value to set. 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void setProducerValue(int index, Value value) 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.store(index, value); 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for Variables. 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void reset(int size) 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato super.reset(size); 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.reset(size); 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void initialize(TracedVariables other) 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato super.initialize(other); 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.initialize(other.producerVariables); 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public boolean generalize(TracedVariables other, 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean clearConflictingOtherVariables) 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean variablesChanged = super.generalize(other, clearConflictingOtherVariables); 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean producersChanged = producerVariables.generalize(other.producerVariables, clearConflictingOtherVariables); 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /* consumerVariables.generalize(other.consumerVariables)*/ 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Clear any traces if a variable has become null. 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (variablesChanged) 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < size; index++) 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (values[index] == null) 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.values[index] = null; 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (clearConflictingOtherVariables) 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato other.producerVariables.values[index] = null; 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return variablesChanged || producersChanged; 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void store(int index, Value value) 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 1679f606f95f03a75961498803e24bee6799a7c0885Ying Wang // Is this store operation an initialization of the variable? 1689f606f95f03a75961498803e24bee6799a7c0885Ying Wang Value previousValue = super.load(index); 1699f606f95f03a75961498803e24bee6799a7c0885Ying Wang if (previousValue == null || 1709f606f95f03a75961498803e24bee6799a7c0885Ying Wang previousValue.computationalType() != value.computationalType()) 1719f606f95f03a75961498803e24bee6799a7c0885Ying Wang { 1729f606f95f03a75961498803e24bee6799a7c0885Ying Wang initializationIndex = index; 1739f606f95f03a75961498803e24bee6799a7c0885Ying Wang } 1749f606f95f03a75961498803e24bee6799a7c0885Ying Wang 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Store the value itself in the variable. 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato super.store(index, value); 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Store the producer value in its producer variable. 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.store(index, producerValue); 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Account for the extra space required by Category 2 values. 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (value.isCategory2()) 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.store(index+1, producerValue); 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for Object. 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public boolean equals(Object object) 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (object == null || 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.getClass() != object.getClass()) 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return false; 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato TracedVariables other = (TracedVariables)object; 200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return super.equals(object) && 202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.producerVariables.equals(other.producerVariables); 203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public int hashCode() 207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return super.hashCode() ^ 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato producerVariables.hashCode(); 210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public String toString() 214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato StringBuffer buffer = new StringBuffer(); 216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < this.size(); index++) 218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value value = this.values[index]; 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Value producerValue = producerVariables.getValue(index); 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato buffer = buffer.append('[') 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato .append(producerValue == null ? "empty:" : producerValue.toString()) 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato .append(value == null ? "empty" : value.toString()) 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato .append(']'); 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return buffer.toString(); 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 230