001: /*
002: * @(#)JDKClass.java 1.12 06/10/10
003: *
004: * Copyright 1990-2006 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:
028: package vm;
029:
030: /*
031: * JDK-VM-specific internal representation of
032: * a class. Target-machine independent.
033: * There is a references from each instance of components.ClassInfo to
034: * one of these, and a reference back as well.
035: *
036: * See also JDKVM for VM-specific info not associated directly with a class.
037: */
038: import components.*;
039: import util.*;
040: import consts.Const;
041: import Util;
042: import Str2ID;
043: import java.util.Enumeration;
044: import java.util.Vector;
045: import java.util.Hashtable;
046: import java.util.StringTokenizer;
047:
048: public class JDKClass extends ClassClass {
049: protected int typeCode = 0;
050: public JDKMethodInfo methods[];
051:
052: public JDKClass(ClassInfo c) {
053: ci = c;
054: c.vmClass = this ;
055:
056: if (c.methods != null) {
057: // per-method, JDK-specific info.
058: methods = new JDKMethodInfo[c.methods.length];
059: for (int i = 0; i < methods.length; i++) {
060: components.MethodInfo m = c.methods[i];
061: methods[i] = new JDKMethodInfo(m);
062: if (!hasStaticInitializer && m.isStaticMember()
063: && m.name.string.equals(/*NOI18N*/"<clinit>")) {
064: hasStaticInitializer = true;
065: }
066: }
067: }
068: }
069:
070: /*
071: * In JDK1.1, the implementation of reflection expects
072: * certain typecodes to be stuffed in the cbTypeCode field
073: * of certain classes. In un-modified JDK, the reflection
074: * implementation stuffs this code there itself. But this
075: * requires writing in the classClass data structure, which
076: * we'd like to make read-only! Thus we do the equivalent
077: * job here, during image building.
078: *
079: */
080: public int typecode() {
081: return typeCode;
082: }
083:
084: public boolean adjustSymbolicConstants(Hashtable missingClasses) {
085: ConstantObject consts[] = ci.constants;
086: if (!isPartiallyResolved(consts)) {
087: return true;
088: }
089: //
090: // we have work to do. This is unfortunate.
091: // we use a LocalConstantPool to manage the pool we're re-building.
092: // Because order matters, we collect the new entries to add at end.
093: //
094: ci.constants = makeClassResolvable(consts, missingClasses)
095: .getConstants();
096: impureConstants = true;
097: return false;
098: }
099:
100: static ConstantPool makeResolvable(ConstantObject[] consts,
101: Hashtable missingClasses) {
102:
103: LocalConstantPool newPool = new LocalConstantPool();
104: Vector newEntries = new Vector();
105: int nconst = consts.length;
106: for (int i = 1; i < nconst; i += consts[i].nSlots) {
107: ConstantObject o;
108: o = consts[i];
109: newPool.append(o);
110: if (!o.isResolved())
111: newEntries.addElement(o);
112: }
113: Enumeration newlist = newEntries.elements();
114: while (newlist.hasMoreElements()) {
115: ConstantObject o = (ConstantObject) newlist.nextElement();
116: String className;
117: switch (o.tag) {
118: case Const.CONSTANT_CLASS:
119: ClassConstant co = (ClassConstant) o;
120: System.err.println(Localizer.getString(
121: "classclass.class", co.name.string));
122: co.name = (UnicodeConstant) newPool.add(co.name);
123: className = co.name.string;
124: missingClasses.put(className, className);
125: continue;
126: case Const.CONSTANT_FIELD:
127: case Const.CONSTANT_METHOD:
128: case Const.CONSTANT_INTERFACEMETHOD:
129: FMIrefConstant fo = (FMIrefConstant) o;
130: if (fo.clas.isResolved()) {
131: // This is a missing member of a resolved class.
132: // Print this out
133: // To print all the references to a totally missing
134: // class would be redundant and noisy.
135: if (fo.tag == Const.CONSTANT_FIELD) {
136: System.err.print(Localizer
137: .getString("classclass.field"));
138: } else {
139: System.err.print(Localizer
140: .getString("classclass.method"));
141: }
142: System.err.println(Localizer.getString(
143: "classclass.of_class", fo.sig.name.string,
144: fo.sig.type.string, fo.clas.name.string));
145: }
146: // as NameAndTypeConstant entries are always "resolved",
147: // the strings they nominally point to need not be present:
148: // they will get written out as a hash ID.
149: fo.sig = (NameAndTypeConstant) newPool.add(fo.sig);
150: fo.clas.name = (UnicodeConstant) newPool
151: .add(fo.clas.name);
152: fo.clas = (ClassConstant) newPool.add(fo.clas);
153: className = fo.clas.name.string;
154: missingClasses.put(className, className);
155: continue;
156: }
157: }
158: newPool.impureConstants = true;
159: return newPool;
160: }
161:
162: /* Inline all the methods in this code object */
163: public void getInlining() {
164: for (int i = 0; i < methods.length; i++) {
165: methods[i].getInlining();
166: }
167: }
168: }
169:
170: /*
171: * Like a constant pool, but with simpler semantics.
172: * Perhaps this and components.ConstantPool should be related.
173: * The important difference is in "add", which never shares
174: * and which always clones if it must insert!
175: * Also append, which is even simpler, as it assumes that we're
176: * loading up this constant pool from an already-existing list.
177: */
178: final class LocalConstantPool extends components.ConstantPool {
179:
180: public LocalConstantPool() {
181: super ();
182: }
183:
184: /**
185: * Return the ConstantObject in constant table corresponding to
186: * the given ConstantObject s.
187: * Duplicates and inserts s if it is not already there.
188: * The index member of the returned value (which
189: * will not be the object s!) will be set to its index in our
190: * table. There will be no element of index 0.
191: */
192: public ConstantObject add(ConstantObject s) {
193: ConstantObject r = (ConstantObject) h.get(s);
194: if (r == null) {
195: r = (ConstantObject) s.clone();
196: r.index = n;
197: n += r.nSlots;
198: h.put(r, r);
199: t.addElement(r);
200: for (int i = r.nSlots; i > 1; i--)
201: t.addElement(null); // place holder.
202: }
203: r.references += 1;
204: return r;
205: }
206:
207: public void append(ConstantObject s) {
208: if (h.get(s) != null) {
209: throw new Error(Localizer.getString(
210: "classclass.append.error_already_in_pool", s));
211: }
212: if (s.index != n) {
213: throw new Error(Localizer.getString(
214: "classclass.append.error_out_of_order", s));
215: }
216: h.put(s, s);
217: t.addElement(s);
218: s.references += 1;
219: for (int i = s.nSlots; i > 1; i--)
220: t.addElement(null); // place holder.
221: n += s.nSlots;
222: }
223: }
|