001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.optimize.info;
022:
023: import proguard.classfile.*;
024: import proguard.classfile.util.*;
025: import proguard.evaluation.value.Value;
026:
027: /**
028: * This class stores some optimization information that can be attached to
029: * a method.
030: *
031: * @author Eric Lafortune
032: */
033: public class MethodOptimizationInfo {
034: private boolean hasNoSideEffects = false;
035: private boolean hasSideEffects = false;
036: private boolean canBeMadePrivate = true;
037: private boolean catchesExceptions = false;
038: private boolean branchesBackward = false;
039: private boolean invokesSuperMethods = false;
040: private boolean accessesPrivateCode = false;
041: private boolean accessesPackageCode = false;
042: private boolean accessesProtectedCode = false;
043: private int invocationCount = 0;
044: private int parameterSize = 0;
045: private long usedParameters = 0L;
046: private Value[] parameters;
047: private Value returnValue;
048:
049: /**
050: * Creates a new MethodOptimizationInfo for the given method.
051: */
052: public MethodOptimizationInfo(Clazz clazz, Method method) {
053: // Set up an array of the right size for storing information about the
054: // passed parameters.
055: int parameterCount = ClassUtil
056: .internalMethodParameterCount(method
057: .getDescriptor(clazz));
058:
059: if ((method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) == 0) {
060: parameterCount++;
061: }
062:
063: if (parameterCount > 0) {
064: parameters = new Value[parameterCount];
065: }
066: }
067:
068: public void setNoSideEffects() {
069: hasNoSideEffects = true;
070: }
071:
072: public boolean hasNoSideEffects() {
073: return hasNoSideEffects;
074: }
075:
076: public void setSideEffects() {
077: hasSideEffects = true;
078: }
079:
080: public boolean hasSideEffects() {
081: return hasSideEffects;
082: }
083:
084: public void setCanNotBeMadePrivate() {
085: canBeMadePrivate = false;
086: }
087:
088: public boolean canBeMadePrivate() {
089: return canBeMadePrivate;
090: }
091:
092: public void setCatchesExceptions() {
093: catchesExceptions = true;
094: }
095:
096: public boolean catchesExceptions() {
097: return catchesExceptions;
098: }
099:
100: public void setBranchesBackward() {
101: branchesBackward = true;
102: }
103:
104: public boolean branchesBackward() {
105: return branchesBackward;
106: }
107:
108: public void setInvokesSuperMethods() {
109: invokesSuperMethods = true;
110: }
111:
112: public boolean invokesSuperMethods() {
113: return invokesSuperMethods;
114: }
115:
116: public void setAccessesPrivateCode() {
117: accessesPrivateCode = true;
118: }
119:
120: public boolean accessesPrivateCode() {
121: return accessesPrivateCode;
122: }
123:
124: public void setAccessesPackageCode() {
125: accessesPackageCode = true;
126: }
127:
128: public boolean accessesPackageCode() {
129: return accessesPackageCode;
130: }
131:
132: public void setAccessesProtectedCode() {
133: accessesProtectedCode = true;
134: }
135:
136: public boolean accessesProtectedCode() {
137: return accessesProtectedCode;
138: }
139:
140: public void incrementInvocationCount() {
141: invocationCount++;
142: }
143:
144: public int getInvocationCount() {
145: return invocationCount;
146: }
147:
148: public void setParameterSize(int parameterSize) {
149: this .parameterSize = parameterSize;
150: }
151:
152: public int getParameterSize() {
153: return parameterSize;
154: }
155:
156: public void setParameterUsed(int parameterIndex) {
157: usedParameters |= 1 << parameterIndex;
158: }
159:
160: public void setUsedParameters(long usedParameters) {
161: this .usedParameters = usedParameters;
162: }
163:
164: public boolean isParameterUsed(int parameterIndex) {
165: return parameterIndex >= 64
166: || (usedParameters & (1 << parameterIndex)) != 0;
167: }
168:
169: public long getUsedParameters() {
170: return usedParameters;
171: }
172:
173: public void generalizeParameter(int parameterIndex, Value parameter) {
174: parameters[parameterIndex] = parameters[parameterIndex] != null ? parameters[parameterIndex]
175: .generalize(parameter)
176: : parameter;
177: }
178:
179: public Value getParameter(int parameterIndex) {
180: return parameters != null ? parameters[parameterIndex] : null;
181: }
182:
183: public void generalizeReturnValue(Value returnValue) {
184: this .returnValue = this .returnValue != null ? this .returnValue
185: .generalize(returnValue) : returnValue;
186: }
187:
188: public Value getReturnValue() {
189: return returnValue;
190: }
191:
192: public static void setMethodOptimizationInfo(Clazz clazz,
193: Method method) {
194: MethodLinker.lastMember(method).setVisitorInfo(
195: new MethodOptimizationInfo(clazz, method));
196: }
197:
198: public static MethodOptimizationInfo getMethodOptimizationInfo(
199: Method method) {
200: Object visitorInfo = MethodLinker.lastMember(method)
201: .getVisitorInfo();
202:
203: return visitorInfo instanceof MethodOptimizationInfo ? (MethodOptimizationInfo) visitorInfo
204: : null;
205: }
206: }
|