001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package components;
028:
029: import java.io.DataOutput;
030: import java.io.DataInput;
031: import java.util.Hashtable;
032: import java.util.Vector;
033: import java.util.Enumeration;
034: import java.io.IOException;
035: import java.io.PrintStream;
036: import sun.misc.Compare;
037:
038: public class ConstantPool implements Compare {
039:
040: protected Hashtable h; // for "quick" lookup
041: protected Vector t; // for enumeration in order
042: protected int n;
043: protected ConstantObject constants[] = null;
044: protected boolean locked = false;
045: public boolean impureConstants = false;
046:
047: public ConstantPool() {
048: h = new Hashtable(500, 0.7f);
049: t = new Vector();
050: t.addElement(null); // 0th element is string of length 0.
051: n = 1;
052: }
053:
054: /**
055: * doCompare
056: *
057: * @param obj1 first object to compare.
058: * @param obj2 second object to compare.
059: * @return -1 if obj1 > obj2, 0 if obj1 == obj2, 1 if obj1 < obj2.
060: */
061: public int doCompare(java.lang.Object o1, java.lang.Object o2) {
062: ConstantObject obj1 = (ConstantObject) o1;
063: ConstantObject obj2 = (ConstantObject) o2;
064:
065: if (obj1.ldcReferences < obj2.ldcReferences) {
066: return 1;
067: } else if (obj1.ldcReferences == obj2.ldcReferences)
068: return 0;
069: return -1;
070: }
071:
072: public void doSort() {
073: int count = 0;
074: int nNew = 1;
075:
076: // Retrieve the ConstantObject array from the hashtable.
077: Enumeration e = h.elements();
078: ConstantObject arr[] = new ConstantObject[h.size()];
079: while (e.hasMoreElements()) {
080: arr[count] = (ConstantObject) e.nextElement();
081: count++;
082: }
083:
084: // Sorting the ConstantObject with descending reference
085: // count.
086: sun.misc.Sort.quicksort(arr, this );
087:
088: t.removeAllElements();
089: t.addElement(null);
090: for (int i = 0; i < arr.length; i++) {
091: arr[i].index = nNew;
092: nNew += arr[i].nSlots;
093: t.addElement(arr[i]);
094: for (int j = arr[i].nSlots; j > 1; j--)
095: t.addElement(null); // place holder
096: }
097: constants = null;
098: }
099:
100: /**
101: * Return the ConstantObject in constant table corresponding to
102: * the given ConstantObject s.
103: * Inserts s if it is not already there.
104: * The index member of the returned value (which
105: * may be the object s!) will be set to its index in our
106: * table. There will be no element of index 0.
107: */
108: public ConstantObject add(ConstantObject s) {
109: if (s.shared && s.containingPool == this )
110: return s; // this is already it!
111: ConstantObject r = (ConstantObject) h.get(s);
112: if (r == null) {
113: if (locked) {
114: throw new Error("add on locked ConstantPool");
115: }
116: if (s.shared) {
117: // already in another constant pool!
118: // this copy is not deep enough!!!
119: r = (ConstantObject) s.clone();
120: } else {
121: r = s;
122: }
123: r.externalize(this ); // Deeper copy, as required.
124: r.index = n;
125: n += r.nSlots;
126: r.shared = true;
127: r.containingPool = this ;
128: h.put(r, r);
129: t.addElement(r);
130: for (int i = r.nSlots; i > 1; i--)
131: t.addElement(null); // place holder.
132: constants = null; // mark any "constants" as obsolete!
133: }
134: return r;
135: }
136:
137: /*
138: * Like add() above, but with less management: still
139: * to ensure that there's only one entry like this in the pool,
140: * but doesn't externalize/share.
141: */
142:
143: public ConstantObject appendElement(ConstantObject s) {
144: ConstantObject r = (ConstantObject) h.get(s);
145: if (r == null) {
146: if (locked) {
147: throw new Error("add on locked ConstantPool");
148: }
149: r = s;
150: r.index = n;
151: n += r.nSlots;
152: h.put(r, r);
153: t.addElement(r);
154: for (int i = r.nSlots; i > 1; i--)
155: t.addElement(null); // place holder.
156: constants = null; // mark any "constants" as obsolete!
157: } else {
158: r.ldcReferences += s.ldcReferences;
159: r.references += s.references;
160: }
161: return r;
162: }
163:
164: public ConstantObject dup(ConstantObject s) {
165: if (s.shared && s.containingPool == this )
166: return s;
167: return this .add((ConstantObject) s.clone());
168: }
169:
170: public ConstantObject[] getConstants() {
171: if (constants != null)
172: return constants;
173: constants = new ConstantObject[t.size()];
174: t.copyInto(constants);
175: return constants;
176: }
177:
178: public Enumeration getEnumeration() {
179: return t.elements();
180: }
181:
182: public void lock() {
183: locked = true;
184: }
185:
186: public void unlock() {
187: locked = false;
188: }
189:
190: public int read(DataInput in) throws IOException {
191: int n = in.readUnsignedShort();
192: ConstantObject c[] = new ConstantObject[n];
193: for (int i = 1; i < n; i += c[i].nSlots) {
194: c[i] = ConstantObject.readObject(in);
195: }
196: //System.err.println("DEBUG CONSTANTPOOL DUMP" );
197: //for (int i = 1; i < n; i+=c[i].nSlots ){
198: // System.err.println("\t#"+i+"\t"+c[i].toString() );
199: //}
200: for (int i = 1; i < n; i += c[i].nSlots) {
201: c[i].resolve(c);
202: }
203: for (int i = 1; i < n; i += c[i].nSlots) {
204: add(c[i]);
205: }
206: constants = c; // IMPL_NOTE: consider whether this should be fixed
207: return n;
208: }
209:
210: public void clearAllReferences() {
211: ConstantObject c;
212: for (int i = 1; i < n; i += c.nSlots) {
213: c = (ConstantObject) t.elementAt(i);
214: c.clearReference();
215: }
216: }
217:
218: /*
219: * If we are not loading entire classes, then there is
220: * some chance that unreferenced constants have sneaked into
221: * this pool. They can be deleted and the table made smaller.
222: * This is a waste of time when partial class loading is not done.
223: *
224: * Naturally, we preserve the null entries.
225: *
226: */
227: public void smashConstantPool() {
228: int nNew = 1;
229: ConstantObject o;
230: // first, count and index.
231: for (int i = 1; i < n; i += o.nSlots) {
232: o = (ConstantObject) t.elementAt(i);
233: if (o.references == 0) {
234: o.index = -1;
235: h.remove(o);
236: } else {
237: // we're keeping it.
238: o.index = nNew;
239: nNew += o.nSlots;
240: }
241: }
242: if (nNew == n)
243: return; // all done!
244:
245: // copy live ones from old vector to new.
246: Vector newConstants = new Vector(nNew);
247: newConstants.addElement(null);
248: for (int i = 1; i < n; i += o.nSlots) {
249: o = (ConstantObject) t.elementAt(i);
250: if (o.references != 0) {
251: // we're keeping it.
252: newConstants.addElement(o);
253: for (int j = o.nSlots; j > 1; j--)
254: newConstants.addElement(null); // place holder.
255: }
256: }
257: t = newConstants;
258: n = nNew;
259: constants = null; // mark as obsolete
260: }
261:
262: /**
263: * Write out the number of constants to write.
264: * Then write out the constants, in order.
265: * Returns total number of constants written.
266: */
267: public int write(DataOutput o) throws IOException {
268: o.writeShort(n);
269: ConstantObject ob;
270: for (int i = 1; i < n; i += ob.nSlots) {
271: ob = (ConstantObject) t.elementAt(i);
272: if (ob != null)
273: ob.write(o);
274: }
275: return n;
276: }
277:
278: public void dump(PrintStream o) {
279: ConstantObject c;
280: for (int i = 1; i < n; i += c.nSlots) {
281: c = (ConstantObject) t.elementAt(i);
282: o.println("\t[" + c.index + "]\t" + c.references + "\t"
283: + c.toString());
284: }
285: }
286: }
|