KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > evaluation > TracedVariables


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.evaluation;
22
23 import proguard.evaluation.value.Value;
24
25 /**
26  * This Variables class saves additional information with variables, to keep track
27  * of their origins.
28  * <p>
29  * The Variables class stores a given producer Value along with each Value it
30  * stores. It then generalizes a given collected Value with the producer Value
31  * of each Value it loads. The producer Value and the initial collected Value
32  * can be set; the generalized collected Value can be retrieved.
33  * <p>
34  * In addition, an initialization index can be reset and retrieved, pointing
35  * to the most recent variable that has been initialized by a store operation.
36  *
37  * @author Eric Lafortune
38  */

39 public class TracedVariables extends Variables
40 {
41     public static final int NONE = -1;
42
43
44     private Value producerValue;
45     private Value collectedProducerValue;
46     private Variables producerVariables;
47     private Variables consumerVariables;
48     private int initializationIndex;
49
50
51     public TracedVariables(int size)
52     {
53         super(size);
54
55         producerVariables = new Variables(size);
56         consumerVariables = new Variables(size);
57     }
58
59
60     public TracedVariables(TracedVariables tracedVariables)
61     {
62         super(tracedVariables);
63
64         producerVariables = new Variables(tracedVariables.producerVariables);
65         consumerVariables = new Variables(tracedVariables.consumerVariables);
66     }
67
68
69     /**
70      * Sets the Value that will be stored along with all store instructions.
71      */

72     public void setProducerValue(Value producerValue)
73     {
74         this.producerValue = producerValue;
75     }
76
77
78     /**
79      * Sets the initial Value with which all values stored along with load
80      * instructions will be generalized.
81      */

82     public void setCollectedProducerValue(Value collectedProducerValue)
83     {
84         this.collectedProducerValue = collectedProducerValue;
85     }
86
87     public Value getCollectedProducerValue()
88     {
89         return collectedProducerValue;
90     }
91
92
93     /**
94      * Resets the initialization index.
95      */

96     public void resetInitialization()
97     {
98         initializationIndex = NONE;
99     }
100
101     public int getInitializationIndex()
102     {
103         return initializationIndex;
104     }
105
106
107     /**
108      * Gets the producer Value for the specified variable, without disturbing it.
109      * @param index the variable index.
110      * @return the producer value of the given variable.
111      */

112     public Value getProducerValue(int index)
113     {
114         return producerVariables.getValue(index);
115     }
116
117
118     /**
119      * Sets the given producer Value for the specified variable, without
120      * disturbing it.
121      * @param index the variable index.
122      * @param value the producer value to set.
123      */

124     public void setProducerValue(int index, Value value)
125     {
126         producerVariables.store(index, value);
127     }
128
129
130     /**
131      * Gets the consumer Value for the specified variable, without disturbing it.
132      * @param index the variable index.
133      * @return the producer value of the given variable.
134      */

135     public Value getConsumerValue(int index)
136     {
137         return ((MutableValue)consumerVariables.getValue(index)).getContainedValue();
138     }
139
140
141     /**
142      * Sets the specified consumer Value for the given variable, without
143      * disturbing it.
144      * @param index the variable index.
145      * @param value the consumer value to set.
146      */

147     public void setConsumerValue(int index, Value value)
148     {
149         ((MutableValue)consumerVariables.getValue(index)).setContainedValue(value);
150         consumerVariables.store(index, new MutableValue());
151     }
152
153
154     // Implementations for Variables.
155

156     public void reset(int size)
157     {
158         super.reset(size);
159
160         producerVariables.reset(size);
161         consumerVariables.reset(size);
162     }
163
164     public void initialize(TracedVariables other)
165     {
166         super.initialize(other);
167
168         producerVariables.initialize(other.producerVariables);
169         consumerVariables.initialize(other.consumerVariables);
170     }
171
172     public boolean generalize(TracedVariables other,
173                               boolean clearConflictingOtherVariables)
174     {
175         boolean variablesChanged = super.generalize(other, clearConflictingOtherVariables);
176         boolean producersChanged = producerVariables.generalize(other.producerVariables, clearConflictingOtherVariables);
177         /* consumerVariables.generalize(other.consumerVariables)*/
178
179         // Clear any traces if a variable has become null.
180
if (variablesChanged)
181         {
182             for (int index = 0; index < size; index++)
183             {
184                 if (values[index] == null)
185                 {
186                     producerVariables.values[index] = null;
187                     consumerVariables.values[index] = null;
188
189                     if (clearConflictingOtherVariables)
190                     {
191                         other.producerVariables.values[index] = null;
192                         other.consumerVariables.values[index] = null;
193                     }
194                 }
195             }
196         }
197
198         return variablesChanged || producersChanged;
199     }
200
201
202     public void store(int index, Value value)
203     {
204         // Is this store operation an initialization of the variable?
205
Value previousValue = super.load(index);
206         if (previousValue == null ||
207             previousValue.computationalType() != value.computationalType())
208         {
209             initializationIndex = index;
210         }
211
212         // Store the value itself in the variable.
213
super.store(index, value);
214
215         // Store the producer value in its producer variable.
216
producerVariables.store(index, producerValue);
217
218         // Reserve a space for the consumer value.
219
MutableValue mutableValue = new MutableValue();
220         consumerVariables.store(index, mutableValue);
221
222         // Account for the extra space required by Category 2 values.
223
if (value.isCategory2())
224         {
225             producerVariables.store(index+1, producerValue);
226             consumerVariables.store(index+1, mutableValue);
227         }
228     }
229
230     public Value load(int index)
231     {
232         // Load and accumulate the producer value of the variable.
233
if (collectedProducerValue != null)
234         {
235             collectedProducerValue = collectedProducerValue.generalize(producerVariables.load(index));
236         }
237
238         // Generalize the consumer value of the variable.
239
((MutableValue)consumerVariables.load(index)).generalizeContainedValue(producerValue);
240
241         // Return the value itself.
242
return super.load(index);
243     }
244
245
246     // Implementations for Object.
247

248     public boolean equals(Object JavaDoc object)
249     {
250         if (object == null ||
251             this.getClass() != object.getClass())
252         {
253             return false;
254         }
255
256         TracedVariables other = (TracedVariables)object;
257
258         return super.equals(object) &&
259                this.producerVariables.equals(other.producerVariables) /*&&
260                this.consumerVariables.equals(other.consumerVariables)*/
;
261     }
262
263
264     public int hashCode()
265     {
266         return super.hashCode() ^
267                producerVariables.hashCode() /*^
268                consumerVariables.hashCode()*/
;
269     }
270
271
272     public String JavaDoc toString()
273     {
274         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
275
276         for (int index = 0; index < this.size(); index++)
277         {
278             Value value = this.values[index];
279             Value producerValue = producerVariables.getValue(index);
280             Value consumerValue = consumerVariables.getValue(index);
281             buffer = buffer.append('[')
282                            .append(producerValue == null ? "empty" : producerValue.toString())
283                            .append('>')
284                            .append(value == null ? "empty" : value.toString())
285                            .append('>')
286                            .append(consumerValue == null ? "empty" : consumerValue.toString())
287                            .append(']');
288         }
289
290         return buffer.toString();
291     }
292 }
293
Popular Tags