Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java @ 2177:3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
author | coleenp |
---|---|
date | Thu, 27 Jan 2011 16:11:27 -0800 |
parents | dad31fc330cd |
children | 1d1603768966 ed69575596ac |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1385
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.oops; | |
26 | |
27 import java.io.*; | |
28 import java.util.*; | |
29 import sun.jvm.hotspot.debugger.*; | |
30 import sun.jvm.hotspot.runtime.*; | |
31 import sun.jvm.hotspot.types.*; | |
32 import sun.jvm.hotspot.utilities.*; | |
33 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
34 // A ConstantPool is an oop containing class constants |
0 | 35 // as described in the class file |
36 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
37 public class ConstantPool extends Oop implements ClassConstants { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
38 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
39 public class CPSlot { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
40 private Address ptr; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
41 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
42 CPSlot(Address ptr) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
43 this.ptr = ptr; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
44 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
45 CPSlot(Symbol sym) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
46 this.ptr = sym.getAddress().orWithMask(1); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
47 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
48 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
49 public boolean isOop() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
50 return (ptr.minus(null) & 1) == 0; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
51 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
52 public boolean isMetaData() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
53 return (ptr.minus(null) & 1) == 1; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
54 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
55 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
56 public Symbol getSymbol() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
57 if (isMetaData()) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
58 return Symbol.create(ptr.xorWithMask(1)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
59 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
60 throw new InternalError("not a symbol"); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
61 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
62 public Oop getOop() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
63 if (isOop()) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
64 return VM.getVM().getObjectHeap().newOop(ptr.addOffsetToAsOopHandle(0)); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
65 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
66 throw new InternalError("not an oop"); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
67 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
68 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
69 |
0 | 70 // Used for debugging this code |
71 private static final boolean DEBUG = false; | |
72 | |
73 protected void debugMessage(String message) { | |
74 System.out.println(message); | |
75 } | |
76 | |
77 static { | |
78 VM.registerVMInitializedObserver(new Observer() { | |
79 public void update(Observable o, Object data) { | |
80 initialize(VM.getVM().getTypeDataBase()); | |
81 } | |
82 }); | |
83 } | |
84 | |
85 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { | |
86 Type type = db.lookupType("constantPoolOopDesc"); | |
87 tags = new OopField(type.getOopField("_tags"), 0); | |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
88 operands = new OopField(type.getOopField("_operands"), 0); |
0 | 89 cache = new OopField(type.getOopField("_cache"), 0); |
90 poolHolder = new OopField(type.getOopField("_pool_holder"), 0); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
91 length = new CIntField(type.getCIntegerField("_length"), 0); |
0 | 92 headerSize = type.getSize(); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
93 elementSize = 0; |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
94 // fetch constants: |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
95 INDY_BSM_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_bsm_offset").intValue(); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
96 INDY_ARGC_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argc_offset").intValue(); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
97 INDY_ARGV_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argv_offset").intValue(); |
0 | 98 } |
99 | |
100 ConstantPool(OopHandle handle, ObjectHeap heap) { | |
101 super(handle, heap); | |
102 } | |
103 | |
104 public boolean isConstantPool() { return true; } | |
105 | |
106 private static OopField tags; | |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
107 private static OopField operands; |
0 | 108 private static OopField cache; |
109 private static OopField poolHolder; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
110 private static CIntField length; // number of elements in oop |
0 | 111 |
112 private static long headerSize; | |
113 private static long elementSize; | |
114 | |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
115 private static int INDY_BSM_OFFSET; |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
116 private static int INDY_ARGC_OFFSET; |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
117 private static int INDY_ARGV_OFFSET; |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
118 |
0 | 119 public TypeArray getTags() { return (TypeArray) tags.getValue(this); } |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
120 public TypeArray getOperands() { return (TypeArray) operands.getValue(this); } |
0 | 121 public ConstantPoolCache getCache() { return (ConstantPoolCache) cache.getValue(this); } |
122 public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
123 public int getLength() { return (int)length.getValue(this); } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
124 |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
125 private long getElementSize() { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
126 if (elementSize !=0 ) { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
127 return elementSize; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
128 } else { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
129 elementSize = VM.getVM().getOopSize(); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
130 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
131 return elementSize; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
132 } |
0 | 133 |
134 private long indexOffset(long index) { | |
135 if (Assert.ASSERTS_ENABLED) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
136 Assert.that(index > 0 && index < getLength(), "invalid cp index " + index + " " + getLength()); |
0 | 137 } |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
138 return (index * getElementSize()) + headerSize; |
0 | 139 } |
140 | |
141 public ConstantTag getTagAt(long index) { | |
142 return new ConstantTag(getTags().getByteAt((int) index)); | |
143 } | |
144 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
145 public CPSlot getSlotAt(long index) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
146 return new CPSlot(getHandle().getAddressAt(indexOffset(index))); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
147 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
148 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
149 public Oop getObjAtRaw(long index){ |
0 | 150 return getHeap().newOop(getHandle().getOopHandleAt(indexOffset(index))); |
151 } | |
152 | |
153 public Symbol getSymbolAt(long index) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
154 CPSlot slot = getSlotAt(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
155 return slot.getSymbol(); |
0 | 156 } |
157 | |
158 public int getIntAt(long index){ | |
159 return getHandle().getJIntAt(indexOffset(index)); | |
160 } | |
161 | |
162 public float getFloatAt(long index){ | |
163 return getHandle().getJFloatAt(indexOffset(index)); | |
164 } | |
165 | |
166 public long getLongAt(long index) { | |
167 int oneHalf = getHandle().getJIntAt(indexOffset(index + 1)); | |
168 int otherHalf = getHandle().getJIntAt(indexOffset(index)); | |
169 // buildLongFromIntsPD accepts higher address value, lower address value | |
170 // in that order. | |
171 return VM.getVM().buildLongFromIntsPD(oneHalf, otherHalf); | |
172 } | |
173 | |
174 public double getDoubleAt(long index) { | |
175 return Double.longBitsToDouble(getLongAt(index)); | |
176 } | |
177 | |
178 public int getFieldOrMethodAt(int which) { | |
179 if (DEBUG) { | |
180 System.err.print("ConstantPool.getFieldOrMethodAt(" + which + "): new index = "); | |
181 } | |
182 int i = -1; | |
183 ConstantPoolCache cache = getCache(); | |
184 if (cache == null) { | |
185 i = which; | |
186 } else { | |
187 // change byte-ordering and go via cache | |
188 i = cache.getEntryAt(0xFFFF & VM.getVM().getBytes().swapShort((short) which)).getConstantPoolIndex(); | |
189 } | |
190 if (Assert.ASSERTS_ENABLED) { | |
191 Assert.that(getTagAt(i).isFieldOrMethod(), "Corrupted constant pool"); | |
192 } | |
193 if (DEBUG) { | |
194 System.err.println(i); | |
195 } | |
196 int res = getIntAt(i); | |
197 if (DEBUG) { | |
198 System.err.println("ConstantPool.getFieldOrMethodAt(" + i + "): result = " + res); | |
199 } | |
200 return res; | |
201 } | |
202 | |
1602 | 203 public int[] getNameAndTypeAt(int which) { |
0 | 204 if (Assert.ASSERTS_ENABLED) { |
205 Assert.that(getTagAt(which).isNameAndType(), "Corrupted constant pool"); | |
206 } | |
207 int i = getIntAt(which); | |
208 if (DEBUG) { | |
209 System.err.println("ConstantPool.getNameAndTypeAt(" + which + "): result = " + i); | |
210 } | |
1602 | 211 return new int[] { extractLowShortFromInt(i), extractHighShortFromInt(i) }; |
0 | 212 } |
213 | |
214 public Symbol getNameRefAt(int which) { | |
1602 | 215 int nameIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[0]; |
0 | 216 return getSymbolAt(nameIndex); |
217 } | |
218 | |
219 public Symbol getSignatureRefAt(int which) { | |
1602 | 220 int sigIndex = getNameAndTypeAt(getNameAndTypeRefIndexAt(which))[1]; |
0 | 221 return getSymbolAt(sigIndex); |
222 } | |
223 | |
224 // returns null, if not resolved. | |
225 public Klass getKlassRefAt(int which) { | |
226 if( ! getTagAt(which).isKlass()) return null; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
227 return (Klass) getObjAtRaw(which); |
0 | 228 } |
229 | |
230 // returns null, if not resolved. | |
231 public InstanceKlass getFieldOrMethodKlassRefAt(int which) { | |
232 int refIndex = getFieldOrMethodAt(which); | |
233 int klassIndex = extractLowShortFromInt(refIndex); | |
234 return (InstanceKlass) getKlassRefAt(klassIndex); | |
235 } | |
236 | |
237 // returns null, if not resolved. | |
238 public Method getMethodRefAt(int which) { | |
239 InstanceKlass klass = getFieldOrMethodKlassRefAt(which); | |
240 if (klass == null) return null; | |
241 Symbol name = getNameRefAt(which); | |
242 Symbol sig = getSignatureRefAt(which); | |
243 return klass.findMethod(name, sig); | |
244 } | |
245 | |
246 // returns null, if not resolved. | |
247 public Field getFieldRefAt(int which) { | |
248 InstanceKlass klass = getFieldOrMethodKlassRefAt(which); | |
249 if (klass == null) return null; | |
250 Symbol name = getNameRefAt(which); | |
251 Symbol sig = getSignatureRefAt(which); | |
252 return klass.findField(name, sig); | |
253 } | |
254 | |
255 public int getNameAndTypeRefIndexAt(int index) { | |
256 int refIndex = getFieldOrMethodAt(index); | |
257 if (DEBUG) { | |
258 System.err.println("ConstantPool.getNameAndTypeRefIndexAt(" + index + "): refIndex = " + refIndex); | |
259 } | |
260 int i = extractHighShortFromInt(refIndex); | |
261 if (DEBUG) { | |
262 System.err.println("ConstantPool.getNameAndTypeRefIndexAt(" + index + "): result = " + i); | |
263 } | |
264 return i; | |
265 } | |
266 | |
267 /** Lookup for entries consisting of (name_index, signature_index) */ | |
268 public int getNameRefIndexAt(int index) { | |
1602 | 269 int[] refIndex = getNameAndTypeAt(index); |
0 | 270 if (DEBUG) { |
1602 | 271 System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]); |
0 | 272 } |
1602 | 273 int i = refIndex[0]; |
0 | 274 if (DEBUG) { |
275 System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): result = " + i); | |
276 } | |
277 return i; | |
278 } | |
279 | |
280 /** Lookup for entries consisting of (name_index, signature_index) */ | |
281 public int getSignatureRefIndexAt(int index) { | |
1602 | 282 int[] refIndex = getNameAndTypeAt(index); |
0 | 283 if (DEBUG) { |
1602 | 284 System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]); |
0 | 285 } |
1602 | 286 int i = refIndex[1]; |
0 | 287 if (DEBUG) { |
288 System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): result = " + i); | |
289 } | |
290 return i; | |
291 } | |
292 | |
1602 | 293 /** Lookup for MethodHandle entries. */ |
294 public int getMethodHandleIndexAt(int i) { | |
295 if (Assert.ASSERTS_ENABLED) { | |
296 Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool"); | |
297 } | |
298 int res = extractHighShortFromInt(getIntAt(i)); | |
299 if (DEBUG) { | |
300 System.err.println("ConstantPool.getMethodHandleIndexAt(" + i + "): result = " + res); | |
301 } | |
302 return res; | |
303 } | |
304 | |
305 /** Lookup for MethodHandle entries. */ | |
306 public int getMethodHandleRefKindAt(int i) { | |
307 if (Assert.ASSERTS_ENABLED) { | |
308 Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool"); | |
309 } | |
310 int res = extractLowShortFromInt(getIntAt(i)); | |
311 if (DEBUG) { | |
312 System.err.println("ConstantPool.getMethodHandleRefKindAt(" + i + "): result = " + res); | |
313 } | |
314 return res; | |
315 } | |
316 | |
317 /** Lookup for MethodType entries. */ | |
318 public int getMethodTypeIndexAt(int i) { | |
319 if (Assert.ASSERTS_ENABLED) { | |
320 Assert.that(getTagAt(i).isMethodType(), "Corrupted constant pool"); | |
321 } | |
322 int res = getIntAt(i); | |
323 if (DEBUG) { | |
324 System.err.println("ConstantPool.getMethodHandleTypeAt(" + i + "): result = " + res); | |
325 } | |
326 return res; | |
327 } | |
328 | |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
329 /** Lookup for multi-operand (InvokeDynamic) entries. */ |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
330 public short[] getBootstrapSpecifierAt(int i) { |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
331 if (Assert.ASSERTS_ENABLED) { |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
332 Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool"); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
333 } |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
334 if (getTagAt(i).value() == JVM_CONSTANT_InvokeDynamicTrans) |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
335 return null; |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
336 int bsmSpec = extractLowShortFromInt(this.getIntAt(i)); |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
337 TypeArray operands = getOperands(); |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
338 if (operands == null) return null; // safety first |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
339 int basePos = VM.getVM().buildIntFromShorts(operands.getShortAt(bsmSpec * 2 + 0), |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
340 operands.getShortAt(bsmSpec * 2 + 1)); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
341 int argv = basePos + INDY_ARGV_OFFSET; |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
342 int argc = operands.getShortAt(basePos + INDY_ARGC_OFFSET); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
343 int endPos = argv + argc; |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
344 short[] values = new short[endPos - basePos]; |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
345 for (int j = 0; j < values.length; j++) { |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
346 values[j] = operands.getShortAt(basePos+j); |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
347 } |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
348 return values; |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
349 } |
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
350 |
0 | 351 final private static String[] nameForTag = new String[] { |
352 }; | |
353 | |
354 private String nameForTag(int tag) { | |
355 switch (tag) { | |
356 case JVM_CONSTANT_Utf8: return "JVM_CONSTANT_Utf8"; | |
357 case JVM_CONSTANT_Unicode: return "JVM_CONSTANT_Unicode"; | |
358 case JVM_CONSTANT_Integer: return "JVM_CONSTANT_Integer"; | |
359 case JVM_CONSTANT_Float: return "JVM_CONSTANT_Float"; | |
360 case JVM_CONSTANT_Long: return "JVM_CONSTANT_Long"; | |
361 case JVM_CONSTANT_Double: return "JVM_CONSTANT_Double"; | |
362 case JVM_CONSTANT_Class: return "JVM_CONSTANT_Class"; | |
363 case JVM_CONSTANT_String: return "JVM_CONSTANT_String"; | |
364 case JVM_CONSTANT_Fieldref: return "JVM_CONSTANT_Fieldref"; | |
365 case JVM_CONSTANT_Methodref: return "JVM_CONSTANT_Methodref"; | |
366 case JVM_CONSTANT_InterfaceMethodref: return "JVM_CONSTANT_InterfaceMethodref"; | |
367 case JVM_CONSTANT_NameAndType: return "JVM_CONSTANT_NameAndType"; | |
1602 | 368 case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle"; |
369 case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType"; | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
370 case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic"; |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
371 case JVM_CONSTANT_InvokeDynamicTrans: return "JVM_CONSTANT_InvokeDynamic/transitional"; |
0 | 372 case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid"; |
373 case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass"; | |
1385 | 374 case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError"; |
0 | 375 case JVM_CONSTANT_ClassIndex: return "JVM_CONSTANT_ClassIndex"; |
376 case JVM_CONSTANT_UnresolvedString: return "JVM_CONSTANT_UnresolvedString"; | |
377 case JVM_CONSTANT_StringIndex: return "JVM_CONSTANT_StringIndex"; | |
378 } | |
1385 | 379 throw new InternalError("Unknown tag: " + tag); |
0 | 380 } |
381 | |
382 public void iterateFields(OopVisitor visitor, boolean doVMFields) { | |
383 super.iterateFields(visitor, doVMFields); | |
384 if (doVMFields) { | |
385 visitor.doOop(tags, true); | |
386 visitor.doOop(cache, true); | |
387 visitor.doOop(poolHolder, true); | |
388 | |
389 final int length = (int) getLength(); | |
390 // zero'th pool entry is always invalid. ignore it. | |
391 for (int index = 1; index < length; index++) { | |
392 int ctag = (int) getTags().getByteAt((int) index); | |
393 switch (ctag) { | |
394 case JVM_CONSTANT_ClassIndex: | |
395 case JVM_CONSTANT_StringIndex: | |
396 case JVM_CONSTANT_Integer: | |
397 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); | |
398 break; | |
399 | |
400 case JVM_CONSTANT_Float: | |
401 visitor.doFloat(new FloatField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); | |
402 break; | |
403 | |
404 case JVM_CONSTANT_Long: | |
405 visitor.doLong(new LongField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); | |
406 // long entries occupy two slots | |
407 index++; | |
408 break; | |
409 | |
410 case JVM_CONSTANT_Double: | |
411 visitor.doDouble(new DoubleField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); | |
412 // double entries occupy two slots | |
413 index++; | |
414 break; | |
415 | |
1385 | 416 case JVM_CONSTANT_UnresolvedClassInError: |
0 | 417 case JVM_CONSTANT_UnresolvedClass: |
418 case JVM_CONSTANT_Class: | |
419 case JVM_CONSTANT_UnresolvedString: | |
420 case JVM_CONSTANT_Utf8: | |
421 visitor.doOop(new OopField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); | |
422 break; | |
423 | |
424 case JVM_CONSTANT_Fieldref: | |
425 case JVM_CONSTANT_Methodref: | |
426 case JVM_CONSTANT_InterfaceMethodref: | |
427 case JVM_CONSTANT_NameAndType: | |
1602 | 428 case JVM_CONSTANT_MethodHandle: |
429 case JVM_CONSTANT_MethodType: | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
430 case JVM_CONSTANT_InvokeDynamic: |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
431 case JVM_CONSTANT_InvokeDynamicTrans: |
0 | 432 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); |
433 break; | |
434 } | |
435 } | |
436 } | |
437 /* | |
438 int length = getLength(); | |
439 for (int index = 0; index < length; index++) { | |
440 long offset = baseOffset + (index + typeDataBase.getOopSize()); | |
441 visitor.doOop(new IndexableField(index, offset, false), getObjAt(index)); | |
442 } | |
443 */ | |
444 } | |
445 | |
446 public void writeBytes(OutputStream os) throws IOException { | |
447 // Map between any modified UTF-8 and it's constant pool index. | |
448 Map utf8ToIndex = new HashMap(); | |
449 DataOutputStream dos = new DataOutputStream(os); | |
450 TypeArray tags = getTags(); | |
451 int len = (int)getLength(); | |
452 int ci = 0; // constant pool index | |
453 | |
454 // collect all modified UTF-8 Strings from Constant Pool | |
455 | |
456 for (ci = 1; ci < len; ci++) { | |
457 byte cpConstType = tags.getByteAt(ci); | |
458 if(cpConstType == JVM_CONSTANT_Utf8) { | |
459 Symbol sym = getSymbolAt(ci); | |
460 utf8ToIndex.put(sym.asString(), new Short((short) ci)); | |
461 } | |
462 else if(cpConstType == JVM_CONSTANT_Long || | |
463 cpConstType == JVM_CONSTANT_Double) { | |
464 ci++; | |
465 } | |
466 } | |
467 | |
468 | |
469 for(ci = 1; ci < len; ci++) { | |
470 int cpConstType = (int)tags.getByteAt(ci); | |
471 // write cp_info | |
472 // write constant type | |
473 switch(cpConstType) { | |
474 case JVM_CONSTANT_Utf8: { | |
475 dos.writeByte(cpConstType); | |
476 Symbol sym = getSymbolAt(ci); | |
477 dos.writeShort((short)sym.getLength()); | |
478 dos.write(sym.asByteArray()); | |
479 if (DEBUG) debugMessage("CP[" + ci + "] = modified UTF-8 " + sym.asString()); | |
480 break; | |
481 } | |
482 | |
483 case JVM_CONSTANT_Unicode: | |
484 throw new IllegalArgumentException("Unicode constant!"); | |
485 | |
486 case JVM_CONSTANT_Integer: | |
487 dos.writeByte(cpConstType); | |
488 dos.writeInt(getIntAt(ci)); | |
489 if (DEBUG) debugMessage("CP[" + ci + "] = int " + getIntAt(ci)); | |
490 break; | |
491 | |
492 case JVM_CONSTANT_Float: | |
493 dos.writeByte(cpConstType); | |
494 dos.writeFloat(getFloatAt(ci)); | |
495 if (DEBUG) debugMessage("CP[" + ci + "] = float " + getFloatAt(ci)); | |
496 break; | |
497 | |
498 case JVM_CONSTANT_Long: { | |
499 dos.writeByte(cpConstType); | |
500 long l = getLongAt(ci); | |
501 // long entries occupy two pool entries | |
502 ci++; | |
503 dos.writeLong(l); | |
504 break; | |
505 } | |
506 | |
507 case JVM_CONSTANT_Double: | |
508 dos.writeByte(cpConstType); | |
509 dos.writeDouble(getDoubleAt(ci)); | |
510 // double entries occupy two pool entries | |
511 ci++; | |
512 break; | |
513 | |
514 case JVM_CONSTANT_Class: { | |
515 dos.writeByte(cpConstType); | |
516 // Klass already resolved. ConstantPool constains klassOop. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
517 Klass refKls = (Klass) getObjAtRaw(ci); |
0 | 518 String klassName = refKls.getName().asString(); |
519 Short s = (Short) utf8ToIndex.get(klassName); | |
520 dos.writeShort(s.shortValue()); | |
521 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s); | |
522 break; | |
523 } | |
524 | |
525 // case JVM_CONSTANT_ClassIndex: | |
1385 | 526 case JVM_CONSTANT_UnresolvedClassInError: |
0 | 527 case JVM_CONSTANT_UnresolvedClass: { |
528 dos.writeByte(JVM_CONSTANT_Class); | |
529 String klassName = getSymbolAt(ci).asString(); | |
530 Short s = (Short) utf8ToIndex.get(klassName); | |
531 dos.writeShort(s.shortValue()); | |
532 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s); | |
533 break; | |
534 } | |
535 | |
536 case JVM_CONSTANT_String: { | |
537 dos.writeByte(cpConstType); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2011
diff
changeset
|
538 String str = OopUtilities.stringOopToString(getObjAtRaw(ci)); |
0 | 539 Short s = (Short) utf8ToIndex.get(str); |
540 dos.writeShort(s.shortValue()); | |
541 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); | |
542 break; | |
543 } | |
544 | |
545 // case JVM_CONSTANT_StringIndex: | |
546 case JVM_CONSTANT_UnresolvedString: { | |
547 dos.writeByte(JVM_CONSTANT_String); | |
548 String val = getSymbolAt(ci).asString(); | |
549 | |
550 Short s = (Short) utf8ToIndex.get(val); | |
551 dos.writeShort(s.shortValue()); | |
552 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); | |
553 break; | |
554 } | |
555 | |
556 // all external, internal method/field references | |
557 case JVM_CONSTANT_Fieldref: | |
558 case JVM_CONSTANT_Methodref: | |
559 case JVM_CONSTANT_InterfaceMethodref: { | |
560 dos.writeByte(cpConstType); | |
561 int value = getIntAt(ci); | |
562 short klassIndex = (short) extractLowShortFromInt(value); | |
563 short nameAndTypeIndex = (short) extractHighShortFromInt(value); | |
564 dos.writeShort(klassIndex); | |
565 dos.writeShort(nameAndTypeIndex); | |
566 if (DEBUG) debugMessage("CP[" + ci + "] = ref klass = " + | |
567 klassIndex + ", N&T = " + nameAndTypeIndex); | |
568 break; | |
569 } | |
570 | |
571 case JVM_CONSTANT_NameAndType: { | |
572 dos.writeByte(cpConstType); | |
573 int value = getIntAt(ci); | |
574 short nameIndex = (short) extractLowShortFromInt(value); | |
575 short signatureIndex = (short) extractHighShortFromInt(value); | |
576 dos.writeShort(nameIndex); | |
577 dos.writeShort(signatureIndex); | |
578 if (DEBUG) debugMessage("CP[" + ci + "] = N&T name = " + nameIndex | |
579 + ", type = " + signatureIndex); | |
580 break; | |
581 } | |
1602 | 582 |
583 case JVM_CONSTANT_MethodHandle: { | |
584 dos.writeByte(cpConstType); | |
585 int value = getIntAt(ci); | |
586 short nameIndex = (short) extractLowShortFromInt(value); | |
587 short signatureIndex = (short) extractHighShortFromInt(value); | |
588 dos.writeShort(nameIndex); | |
589 dos.writeShort(signatureIndex); | |
590 if (DEBUG) debugMessage("CP[" + ci + "] = N&T name = " + nameIndex | |
591 + ", type = " + signatureIndex); | |
592 break; | |
593 } | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
594 |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
595 case JVM_CONSTANT_InvokeDynamicTrans: |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
596 case JVM_CONSTANT_InvokeDynamic: { |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
597 dos.writeByte(cpConstType); |
2011
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
598 int value = getIntAt(ci); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
599 short bsmIndex = (short) extractLowShortFromInt(value); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
600 short nameAndTypeIndex = (short) extractHighShortFromInt(value); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
601 dos.writeShort(bsmIndex); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
602 dos.writeShort(nameAndTypeIndex); |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
603 if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bsmIndex |
dad31fc330cd
7001379: bootstrap method data needs to be moved from constant pool to a classfile attribute
jrose
parents:
1913
diff
changeset
|
604 + ", N&T = " + nameAndTypeIndex); |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
605 break; |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1602
diff
changeset
|
606 } |
1913
3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
jrose
parents:
1660
diff
changeset
|
607 |
1385 | 608 default: |
609 throw new InternalError("unknown tag: " + cpConstType); | |
0 | 610 } // switch |
611 } | |
612 dos.flush(); | |
613 return; | |
614 } | |
615 | |
616 public void printValueOn(PrintStream tty) { | |
617 tty.print("ConstantPool for " + getPoolHolder().getName().asString()); | |
618 } | |
619 | |
620 public long getObjectSize() { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
621 return alignObjectSize(headerSize + (getLength() * getElementSize())); |
0 | 622 } |
623 | |
624 //---------------------------------------------------------------------- | |
625 // Internals only below this point | |
626 // | |
627 | |
628 private static int extractHighShortFromInt(int val) { | |
1602 | 629 // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. |
0 | 630 return (val >> 16) & 0xFFFF; |
631 } | |
632 | |
633 private static int extractLowShortFromInt(int val) { | |
1602 | 634 // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. |
0 | 635 return val & 0xFFFF; |
636 } | |
637 } |