comparison agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 38fd165da001
children 18fb7da42534
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
32 import sun.jvm.hotspot.utilities.*; 32 import sun.jvm.hotspot.utilities.*;
33 33
34 // A ConstantPool is an oop containing class constants 34 // A ConstantPool is an oop containing class constants
35 // as described in the class file 35 // as described in the class file
36 36
37 public class ConstantPool extends Oop implements ClassConstants { 37 public class ConstantPool extends Metadata implements ClassConstants {
38
39 public class CPSlot { 38 public class CPSlot {
40 private Address ptr; 39 private Address ptr;
41 40
42 CPSlot(Address ptr) { 41 CPSlot(Address ptr) {
43 this.ptr = ptr; 42 this.ptr = ptr;
44 } 43 }
45 CPSlot(Symbol sym) { 44 CPSlot(Symbol sym) {
46 this.ptr = sym.getAddress().orWithMask(1); 45 this.ptr = sym.getAddress().orWithMask(1);
47 } 46 }
48 47
49 public boolean isOop() { 48 public boolean isResolved() {
50 return (ptr.minus(null) & 1) == 0; 49 return (ptr.minus(null) & 1) == 0;
51 } 50 }
52 public boolean isMetaData() { 51 public boolean isUnresolved() {
53 return (ptr.minus(null) & 1) == 1; 52 return (ptr.minus(null) & 1) == 1;
54 } 53 }
55 54
56 public Symbol getSymbol() { 55 public Symbol getSymbol() {
57 if (isMetaData()) { 56 if (!isUnresolved()) throw new InternalError("not a symbol");
58 return Symbol.create(ptr.xorWithMask(1)); 57 return Symbol.create(ptr.xorWithMask(1));
59 } 58 }
60 throw new InternalError("not a symbol"); 59 public Klass getKlass() {
61 } 60 if (!isResolved()) throw new InternalError("not klass");
62 public Oop getOop() { 61 return (Klass)Metadata.instantiateWrapperFor(ptr);
63 if (isOop()) {
64 return VM.getVM().getObjectHeap().newOop(ptr.addOffsetToAsOopHandle(0));
65 }
66 throw new InternalError("not an oop");
67 } 62 }
68 } 63 }
69 64
70 // Used for debugging this code 65 // Used for debugging this code
71 private static final boolean DEBUG = false; 66 private static final boolean DEBUG = false;
81 } 76 }
82 }); 77 });
83 } 78 }
84 79
85 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { 80 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
86 Type type = db.lookupType("constantPoolOopDesc"); 81 Type type = db.lookupType("ConstantPool");
87 tags = new OopField(type.getOopField("_tags"), 0); 82 tags = type.getAddressField("_tags");
88 operands = new OopField(type.getOopField("_operands"), 0); 83 operands = type.getAddressField("_operands");
89 cache = new OopField(type.getOopField("_cache"), 0); 84 cache = type.getAddressField("_cache");
90 poolHolder = new OopField(type.getOopField("_pool_holder"), 0); 85 poolHolder = new MetadataField(type.getAddressField("_pool_holder"), 0);
91 length = new CIntField(type.getCIntegerField("_length"), 0); 86 length = new CIntField(type.getCIntegerField("_length"), 0);
87 resolvedReferences = type.getAddressField("_resolved_references");
88 referenceMap = type.getAddressField("_reference_map");
92 headerSize = type.getSize(); 89 headerSize = type.getSize();
93 elementSize = 0; 90 elementSize = 0;
94 // fetch constants: 91 // fetch constants:
95 INDY_BSM_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_bsm_offset").intValue(); 92 INDY_BSM_OFFSET = db.lookupIntConstant("ConstantPool::_indy_bsm_offset").intValue();
96 INDY_ARGC_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argc_offset").intValue(); 93 INDY_ARGC_OFFSET = db.lookupIntConstant("ConstantPool::_indy_argc_offset").intValue();
97 INDY_ARGV_OFFSET = db.lookupIntConstant("constantPoolOopDesc::_indy_argv_offset").intValue(); 94 INDY_ARGV_OFFSET = db.lookupIntConstant("ConstantPool::_indy_argv_offset").intValue();
98 } 95 }
99 96
100 ConstantPool(OopHandle handle, ObjectHeap heap) { 97 public ConstantPool(Address addr) {
101 super(handle, heap); 98 super(addr);
102 } 99 }
103 100
104 public boolean isConstantPool() { return true; } 101 public boolean isConstantPool() { return true; }
105 102
106 private static OopField tags; 103 private static AddressField tags;
107 private static OopField operands; 104 private static AddressField operands;
108 private static OopField cache; 105 private static AddressField cache;
109 private static OopField poolHolder; 106 private static MetadataField poolHolder;
110 private static CIntField length; // number of elements in oop 107 private static CIntField length; // number of elements in oop
108 private static AddressField resolvedReferences;
109 private static AddressField referenceMap;
111 110
112 private static long headerSize; 111 private static long headerSize;
113 private static long elementSize; 112 private static long elementSize;
114 113
115 private static int INDY_BSM_OFFSET; 114 private static int INDY_BSM_OFFSET;
116 private static int INDY_ARGC_OFFSET; 115 private static int INDY_ARGC_OFFSET;
117 private static int INDY_ARGV_OFFSET; 116 private static int INDY_ARGV_OFFSET;
118 117
119 public TypeArray getTags() { return (TypeArray) tags.getValue(this); } 118 public U1Array getTags() { return new U1Array(tags.getValue(getAddress())); }
120 public TypeArray getOperands() { return (TypeArray) operands.getValue(this); } 119 public U2Array getOperands() { return new U2Array(operands.getValue(getAddress())); }
121 public ConstantPoolCache getCache() { return (ConstantPoolCache) cache.getValue(this); } 120 public ConstantPoolCache getCache() {
121 Address addr = cache.getValue(getAddress());
122 return (ConstantPoolCache) VMObjectFactory.newObject(ConstantPoolCache.class, addr);
123 }
122 public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); } 124 public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); }
123 public int getLength() { return (int)length.getValue(this); } 125 public int getLength() { return (int)length.getValue(getAddress()); }
126 public Oop getResolvedReferences() {
127 Address handle = resolvedReferences.getValue(getAddress());
128 if (handle != null) {
129 // Load through the handle
130 OopHandle refs = handle.getOopHandleAt(0);
131 return VM.getVM().getObjectHeap().newOop(refs);
132 }
133 return null;
134 }
135
136 public U2Array referenceMap() {
137 return new U2Array(referenceMap.getValue(getAddress()));
138 }
139
140 public int objectToCPIndex(int index) {
141 return referenceMap().at(index);
142 }
124 143
125 private long getElementSize() { 144 private long getElementSize() {
126 if (elementSize !=0 ) { 145 if (elementSize !=0 ) {
127 return elementSize; 146 return elementSize;
128 } else { 147 } else {
137 } 156 }
138 return (index * getElementSize()) + headerSize; 157 return (index * getElementSize()) + headerSize;
139 } 158 }
140 159
141 public ConstantTag getTagAt(long index) { 160 public ConstantTag getTagAt(long index) {
142 return new ConstantTag(getTags().getByteAt((int) index)); 161 return new ConstantTag((byte)getTags().at((int) index));
143 } 162 }
144 163
145 public CPSlot getSlotAt(long index) { 164 public CPSlot getSlotAt(long index) {
146 return new CPSlot(getHandle().getAddressAt(indexOffset(index))); 165 return new CPSlot(getAddressAtRaw(index));
147 } 166 }
148 167
149 public Oop getObjAtRaw(long index){ 168 public Address getAddressAtRaw(long index) {
150 return getHeap().newOop(getHandle().getOopHandleAt(indexOffset(index))); 169 return getAddress().getAddressAt(indexOffset(index));
151 } 170 }
152 171
153 public Symbol getSymbolAt(long index) { 172 public Symbol getSymbolAt(long index) {
154 CPSlot slot = getSlotAt(index); 173 return Symbol.create(getAddressAtRaw(index));
155 return slot.getSymbol();
156 } 174 }
157 175
158 public int getIntAt(long index){ 176 public int getIntAt(long index){
159 return getHandle().getJIntAt(indexOffset(index)); 177 return getAddress().getJIntAt(indexOffset(index));
160 } 178 }
161 179
162 public float getFloatAt(long index){ 180 public float getFloatAt(long index){
163 return getHandle().getJFloatAt(indexOffset(index)); 181 return getAddress().getJFloatAt(indexOffset(index));
164 } 182 }
165 183
166 public long getLongAt(long index) { 184 public long getLongAt(long index) {
167 int oneHalf = getHandle().getJIntAt(indexOffset(index + 1)); 185 int oneHalf = getAddress().getJIntAt(indexOffset(index + 1));
168 int otherHalf = getHandle().getJIntAt(indexOffset(index)); 186 int otherHalf = getAddress().getJIntAt(indexOffset(index));
169 // buildLongFromIntsPD accepts higher address value, lower address value 187 // buildLongFromIntsPD accepts higher address value, lower address value
170 // in that order. 188 // in that order.
171 return VM.getVM().buildLongFromIntsPD(oneHalf, otherHalf); 189 return VM.getVM().buildLongFromIntsPD(oneHalf, otherHalf);
172 } 190 }
173 191
183 ConstantPoolCache cache = getCache(); 201 ConstantPoolCache cache = getCache();
184 if (cache == null) { 202 if (cache == null) {
185 i = which; 203 i = which;
186 } else { 204 } else {
187 // change byte-ordering and go via cache 205 // change byte-ordering and go via cache
188 i = cache.getEntryAt(0xFFFF & VM.getVM().getBytes().swapShort((short) which)).getConstantPoolIndex(); 206 i = cache.getEntryAt(0xFFFF & which).getConstantPoolIndex();
189 } 207 }
190 if (Assert.ASSERTS_ENABLED) { 208 if (Assert.ASSERTS_ENABLED) {
191 Assert.that(getTagAt(i).isFieldOrMethod(), "Corrupted constant pool"); 209 Assert.that(getTagAt(i).isFieldOrMethod(), "Corrupted constant pool");
192 } 210 }
193 if (DEBUG) { 211 if (DEBUG) {
200 return res; 218 return res;
201 } 219 }
202 220
203 public int[] getNameAndTypeAt(int which) { 221 public int[] getNameAndTypeAt(int which) {
204 if (Assert.ASSERTS_ENABLED) { 222 if (Assert.ASSERTS_ENABLED) {
205 Assert.that(getTagAt(which).isNameAndType(), "Corrupted constant pool"); 223 Assert.that(getTagAt(which).isNameAndType(), "Corrupted constant pool: " + which + " " + getTagAt(which));
206 } 224 }
207 int i = getIntAt(which); 225 int i = getIntAt(which);
208 if (DEBUG) { 226 if (DEBUG) {
209 System.err.println("ConstantPool.getNameAndTypeAt(" + which + "): result = " + i); 227 System.err.println("ConstantPool.getNameAndTypeAt(" + which + "): result = " + i);
210 } 228 }
211 return new int[] { extractLowShortFromInt(i), extractHighShortFromInt(i) }; 229 return new int[] { extractLowShortFromInt(i), extractHighShortFromInt(i) };
212 } 230 }
213 231
214 public Symbol getNameRefAt(int which) { 232 public Symbol getNameRefAt(int which) {
215 return implGetNameRefAt(which, false); 233 return implGetNameRefAt(which, false);
234 }
235
236 public Symbol uncachedGetNameRefAt(int which) {
237 return implGetNameRefAt(which, true);
216 } 238 }
217 239
218 private Symbol implGetNameRefAt(int which, boolean uncached) { 240 private Symbol implGetNameRefAt(int which, boolean uncached) {
219 int signatureIndex = getNameRefIndexAt(implNameAndTypeRefIndexAt(which, uncached)); 241 int signatureIndex = getNameRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
220 return getSymbolAt(signatureIndex); 242 return getSymbolAt(signatureIndex);
222 244
223 public Symbol getSignatureRefAt(int which) { 245 public Symbol getSignatureRefAt(int which) {
224 return implGetSignatureRefAt(which, false); 246 return implGetSignatureRefAt(which, false);
225 } 247 }
226 248
249 public Symbol uncachedGetSignatureRefAt(int which) {
250 return implGetSignatureRefAt(which, true);
251 }
252
227 private Symbol implGetSignatureRefAt(int which, boolean uncached) { 253 private Symbol implGetSignatureRefAt(int which, boolean uncached) {
228 int signatureIndex = getSignatureRefIndexAt(implNameAndTypeRefIndexAt(which, uncached)); 254 int signatureIndex = getSignatureRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
229 return getSymbolAt(signatureIndex); 255 return getSymbolAt(signatureIndex);
230 } 256 }
231 257
258 public static boolean isInvokedynamicIndex(int i) { return (i < 0); }
259
260 public static int decodeInvokedynamicIndex(int i) { Assert.that(isInvokedynamicIndex(i), ""); return ~i; }
261
262 // The invokedynamic points at the object index. The object map points at
263 // the cpCache index and the cpCache entry points at the original constant
264 // pool index.
265 public int invokedynamicCPCacheIndex(int index) {
266 Assert.that(isInvokedynamicIndex(index), "should be a invokedynamic index");
267 int rawIndex = decodeInvokedynamicIndex(index);
268 return referenceMap().at(rawIndex);
269 }
270
271 ConstantPoolCacheEntry invokedynamicCPCacheEntryAt(int index) {
272 // decode index that invokedynamic points to.
273 int cpCacheIndex = invokedynamicCPCacheIndex(index);
274 return getCache().getEntryAt(cpCacheIndex);
275 }
232 276
233 private int implNameAndTypeRefIndexAt(int which, boolean uncached) { 277 private int implNameAndTypeRefIndexAt(int which, boolean uncached) {
234 int i = which; 278 int i = which;
235 if (!uncached && getCache() != null) { 279 if (!uncached && getCache() != null) {
236 if (ConstantPoolCache.isSecondaryIndex(which)) { 280 if (isInvokedynamicIndex(which)) {
237 // Invokedynamic index. 281 // Invokedynamic index is index into resolved_references
238 int pool_index = getCache().getMainEntryAt(which).getConstantPoolIndex(); 282 int poolIndex = invokedynamicCPCacheEntryAt(which).getConstantPoolIndex();
239 pool_index = invokeDynamicNameAndTypeRefIndexAt(pool_index); 283 poolIndex = invokeDynamicNameAndTypeRefIndexAt(poolIndex);
240 // assert(tagAt(pool_index).isNameAndType(), ""); 284 Assert.that(getTagAt(poolIndex).isNameAndType(), "");
241 return pool_index; 285 return poolIndex;
242 } 286 }
243 // change byte-ordering and go via cache 287 // change byte-ordering and go via cache
244 i = remapInstructionOperandFromCache(which); 288 i = remapInstructionOperandFromCache(which);
245 } else { 289 } else {
246 if (getTagAt(which).isInvokeDynamic()) { 290 if (getTagAt(which).isInvokeDynamic()) {
247 int pool_index = invokeDynamicNameAndTypeRefIndexAt(which); 291 int poolIndex = invokeDynamicNameAndTypeRefIndexAt(which);
248 // assert(tag_at(pool_index).is_name_and_type(), ""); 292 Assert.that(getTagAt(poolIndex).isNameAndType(), "");
249 return pool_index; 293 return poolIndex;
250 } 294 }
251 } 295 }
252 // assert(tag_at(i).is_field_or_method(), "Corrupted constant pool"); 296 // assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
253 // assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above"); 297 // assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above");
254 int ref_index = getIntAt(i); 298 int refIndex = getIntAt(i);
255 return extractHighShortFromInt(ref_index); 299 return extractHighShortFromInt(refIndex);
256 } 300 }
257 301
258 private int remapInstructionOperandFromCache(int operand) { 302 private int remapInstructionOperandFromCache(int operand) {
259 int cpc_index = operand; 303 int cpc_index = operand;
260 // DEBUG_ONLY(cpc_index -= CPCACHE_INDEX_TAG); 304 // DEBUG_ONLY(cpc_index -= CPCACHE_INDEX_TAG);
267 // assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); 311 // assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
268 return extractHighShortFromInt(getIntAt(which)); 312 return extractHighShortFromInt(getIntAt(which));
269 } 313 }
270 314
271 // returns null, if not resolved. 315 // returns null, if not resolved.
272 public Klass getKlassRefAt(int which) { 316 public Klass getKlassAt(int which) {
273 if( ! getTagAt(which).isKlass()) return null; 317 if( ! getTagAt(which).isKlass()) return null;
274 return (Klass) getObjAtRaw(which); 318 return (Klass)Metadata.instantiateWrapperFor(getAddressAtRaw(which));
319 }
320
321 public Symbol getKlassNameAt(int which) {
322 CPSlot entry = getSlotAt(which);
323 if (entry.isResolved()) {
324 return entry.getKlass().getName();
325 } else {
326 return entry.getSymbol();
327 }
328 }
329
330 public Symbol getUnresolvedStringAt(int which) {
331 return getSymbolAt(which);
275 } 332 }
276 333
277 // returns null, if not resolved. 334 // returns null, if not resolved.
278 public InstanceKlass getFieldOrMethodKlassRefAt(int which) { 335 public InstanceKlass getFieldOrMethodKlassRefAt(int which) {
279 int refIndex = getFieldOrMethodAt(which); 336 int refIndex = getFieldOrMethodAt(which);
280 int klassIndex = extractLowShortFromInt(refIndex); 337 int klassIndex = extractLowShortFromInt(refIndex);
281 return (InstanceKlass) getKlassRefAt(klassIndex); 338 return (InstanceKlass) getKlassAt(klassIndex);
282 } 339 }
283 340
284 // returns null, if not resolved. 341 // returns null, if not resolved.
285 public Method getMethodRefAt(int which) { 342 public Method getMethodRefAt(int which) {
286 InstanceKlass klass = getFieldOrMethodKlassRefAt(which); 343 InstanceKlass klass = getFieldOrMethodKlassRefAt(which);
369 public short[] getBootstrapSpecifierAt(int i) { 426 public short[] getBootstrapSpecifierAt(int i) {
370 if (Assert.ASSERTS_ENABLED) { 427 if (Assert.ASSERTS_ENABLED) {
371 Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool"); 428 Assert.that(getTagAt(i).isInvokeDynamic(), "Corrupted constant pool");
372 } 429 }
373 int bsmSpec = extractLowShortFromInt(this.getIntAt(i)); 430 int bsmSpec = extractLowShortFromInt(this.getIntAt(i));
374 TypeArray operands = getOperands(); 431 U2Array operands = getOperands();
375 if (operands == null) return null; // safety first 432 if (operands == null) return null; // safety first
376 int basePos = VM.getVM().buildIntFromShorts(operands.getShortAt(bsmSpec * 2 + 0), 433 int basePos = VM.getVM().buildIntFromShorts(operands.at(bsmSpec * 2 + 0),
377 operands.getShortAt(bsmSpec * 2 + 1)); 434 operands.at(bsmSpec * 2 + 1));
378 int argv = basePos + INDY_ARGV_OFFSET; 435 int argv = basePos + INDY_ARGV_OFFSET;
379 int argc = operands.getShortAt(basePos + INDY_ARGC_OFFSET); 436 int argc = operands.at(basePos + INDY_ARGC_OFFSET);
380 int endPos = argv + argc; 437 int endPos = argv + argc;
381 short[] values = new short[endPos - basePos]; 438 short[] values = new short[endPos - basePos];
382 for (int j = 0; j < values.length; j++) { 439 for (int j = 0; j < values.length; j++) {
383 values[j] = operands.getShortAt(basePos+j); 440 values[j] = operands.at(basePos+j);
384 } 441 }
385 return values; 442 return values;
386 } 443 }
387 444
388 final private static String[] nameForTag = new String[] { 445 final private static String[] nameForTag = new String[] {
405 case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle"; 462 case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle";
406 case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType"; 463 case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType";
407 case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic"; 464 case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic";
408 case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid"; 465 case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid";
409 case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass"; 466 case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass";
467 case JVM_CONSTANT_ClassIndex: return "JVM_CONSTANT_ClassIndex";
468 case JVM_CONSTANT_StringIndex: return "JVM_CONSTANT_StringIndex";
410 case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError"; 469 case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError";
411 case JVM_CONSTANT_ClassIndex: return "JVM_CONSTANT_ClassIndex"; 470 case JVM_CONSTANT_MethodHandleInError:return "JVM_CONSTANT_MethodHandleInError";
412 case JVM_CONSTANT_UnresolvedString: return "JVM_CONSTANT_UnresolvedString"; 471 case JVM_CONSTANT_MethodTypeInError: return "JVM_CONSTANT_MethodTypeInError";
413 case JVM_CONSTANT_StringIndex: return "JVM_CONSTANT_StringIndex"; 472 case JVM_CONSTANT_Object: return "JVM_CONSTANT_Object";
414 } 473 }
415 throw new InternalError("Unknown tag: " + tag); 474 throw new InternalError("Unknown tag: " + tag);
416 } 475 }
417 476
418 public void iterateFields(OopVisitor visitor, boolean doVMFields) { 477 public void iterateFields(MetadataVisitor visitor) {
419 super.iterateFields(visitor, doVMFields); 478 super.iterateFields(visitor);
420 if (doVMFields) { 479 visitor.doMetadata(poolHolder, true);
421 visitor.doOop(tags, true);
422 visitor.doOop(cache, true);
423 visitor.doOop(poolHolder, true);
424 480
425 final int length = (int) getLength(); 481 final int length = (int) getLength();
426 // zero'th pool entry is always invalid. ignore it. 482 // zero'th pool entry is always invalid. ignore it.
427 for (int index = 1; index < length; index++) { 483 for (int index = 1; index < length; index++) {
428 int ctag = (int) getTags().getByteAt((int) index); 484 int ctag = (int) getTags().at((int) index);
429 switch (ctag) { 485 switch (ctag) {
430 case JVM_CONSTANT_ClassIndex: 486 case JVM_CONSTANT_ClassIndex:
431 case JVM_CONSTANT_StringIndex: 487 case JVM_CONSTANT_StringIndex:
432 case JVM_CONSTANT_Integer: 488 case JVM_CONSTANT_Integer:
433 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); 489 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
450 break; 506 break;
451 507
452 case JVM_CONSTANT_UnresolvedClassInError: 508 case JVM_CONSTANT_UnresolvedClassInError:
453 case JVM_CONSTANT_UnresolvedClass: 509 case JVM_CONSTANT_UnresolvedClass:
454 case JVM_CONSTANT_Class: 510 case JVM_CONSTANT_Class:
455 case JVM_CONSTANT_UnresolvedString:
456 case JVM_CONSTANT_Utf8: 511 case JVM_CONSTANT_Utf8:
457 visitor.doOop(new OopField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); 512 visitor.doOop(new OopField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
458 break; 513 break;
459 514
460 case JVM_CONSTANT_Fieldref: 515 case JVM_CONSTANT_Fieldref:
467 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true); 522 visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
468 break; 523 break;
469 } 524 }
470 } 525 }
471 } 526 }
472 /*
473 int length = getLength();
474 for (int index = 0; index < length; index++) {
475 long offset = baseOffset + (index + typeDataBase.getOopSize());
476 visitor.doOop(new IndexableField(index, offset, false), getObjAt(index));
477 }
478 */
479 }
480 527
481 public void writeBytes(OutputStream os) throws IOException { 528 public void writeBytes(OutputStream os) throws IOException {
482 // Map between any modified UTF-8 and it's constant pool index. 529 // Map between any modified UTF-8 and it's constant pool index.
483 Map utf8ToIndex = new HashMap(); 530 Map utf8ToIndex = new HashMap();
484 DataOutputStream dos = new DataOutputStream(os); 531 DataOutputStream dos = new DataOutputStream(os);
485 TypeArray tags = getTags(); 532 U1Array tags = getTags();
486 int len = (int)getLength(); 533 int len = (int)getLength();
487 int ci = 0; // constant pool index 534 int ci = 0; // constant pool index
488 535
489 // collect all modified UTF-8 Strings from Constant Pool 536 // collect all modified UTF-8 Strings from Constant Pool
490 537
491 for (ci = 1; ci < len; ci++) { 538 for (ci = 1; ci < len; ci++) {
492 byte cpConstType = tags.getByteAt(ci); 539 int cpConstType = tags.at(ci);
493 if(cpConstType == JVM_CONSTANT_Utf8) { 540 if(cpConstType == JVM_CONSTANT_Utf8) {
494 Symbol sym = getSymbolAt(ci); 541 Symbol sym = getSymbolAt(ci);
495 utf8ToIndex.put(sym.asString(), new Short((short) ci)); 542 utf8ToIndex.put(sym.asString(), new Short((short) ci));
496 } 543 }
497 else if(cpConstType == JVM_CONSTANT_Long || 544 else if(cpConstType == JVM_CONSTANT_Long ||
500 } 547 }
501 } 548 }
502 549
503 550
504 for(ci = 1; ci < len; ci++) { 551 for(ci = 1; ci < len; ci++) {
505 int cpConstType = (int)tags.getByteAt(ci); 552 int cpConstType = tags.at(ci);
506 // write cp_info 553 // write cp_info
507 // write constant type 554 // write constant type
508 switch(cpConstType) { 555 switch(cpConstType) {
509 case JVM_CONSTANT_Utf8: { 556 case JVM_CONSTANT_Utf8: {
510 dos.writeByte(cpConstType); 557 dos.writeByte(cpConstType);
546 ci++; 593 ci++;
547 break; 594 break;
548 595
549 case JVM_CONSTANT_Class: { 596 case JVM_CONSTANT_Class: {
550 dos.writeByte(cpConstType); 597 dos.writeByte(cpConstType);
551 // Klass already resolved. ConstantPool constains klassOop. 598 // Klass already resolved. ConstantPool constains Klass*.
552 Klass refKls = (Klass) getObjAtRaw(ci); 599 Klass refKls = (Klass)Metadata.instantiateWrapperFor(getAddressAtRaw(ci));
553 String klassName = refKls.getName().asString(); 600 String klassName = refKls.getName().asString();
554 Short s = (Short) utf8ToIndex.get(klassName); 601 Short s = (Short) utf8ToIndex.get(klassName);
555 dos.writeShort(s.shortValue()); 602 dos.writeShort(s.shortValue());
556 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s); 603 if (DEBUG) debugMessage("CP[" + ci + "] = class " + s);
557 break; 604 break;
568 break; 615 break;
569 } 616 }
570 617
571 case JVM_CONSTANT_String: { 618 case JVM_CONSTANT_String: {
572 dos.writeByte(cpConstType); 619 dos.writeByte(cpConstType);
573 String str = OopUtilities.stringOopToString(getObjAtRaw(ci)); 620 String str = getUnresolvedStringAt(ci).asString();
574 Short s = (Short) utf8ToIndex.get(str); 621 Short s = (Short) utf8ToIndex.get(str);
575 dos.writeShort(s.shortValue());
576 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
577 break;
578 }
579
580 // case JVM_CONSTANT_StringIndex:
581 case JVM_CONSTANT_UnresolvedString: {
582 dos.writeByte(JVM_CONSTANT_String);
583 String val = getSymbolAt(ci).asString();
584
585 Short s = (Short) utf8ToIndex.get(val);
586 dos.writeShort(s.shortValue()); 622 dos.writeShort(s.shortValue());
587 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s); 623 if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
588 break; 624 break;
589 } 625 }
590 626
616 } 652 }
617 653
618 case JVM_CONSTANT_MethodHandle: { 654 case JVM_CONSTANT_MethodHandle: {
619 dos.writeByte(cpConstType); 655 dos.writeByte(cpConstType);
620 int value = getIntAt(ci); 656 int value = getIntAt(ci);
621 short nameIndex = (short) extractLowShortFromInt(value); 657 byte refKind = (byte) extractLowShortFromInt(value);
622 short signatureIndex = (short) extractHighShortFromInt(value); 658 short memberIndex = (short) extractHighShortFromInt(value);
623 dos.writeShort(nameIndex); 659 dos.writeByte(refKind);
624 dos.writeShort(signatureIndex); 660 dos.writeShort(memberIndex);
625 if (DEBUG) debugMessage("CP[" + ci + "] = N&T name = " + nameIndex 661 if (DEBUG) debugMessage("CP[" + ci + "] = MH kind = " +
626 + ", type = " + signatureIndex); 662 refKind + ", mem = " + memberIndex);
663 break;
664 }
665
666 case JVM_CONSTANT_MethodType: {
667 dos.writeByte(cpConstType);
668 int value = getIntAt(ci);
669 short refIndex = (short) value;
670 dos.writeShort(refIndex);
671 if (DEBUG) debugMessage("CP[" + ci + "] = MT index = " + refIndex);
627 break; 672 break;
628 } 673 }
629 674
630 case JVM_CONSTANT_InvokeDynamic: { 675 case JVM_CONSTANT_InvokeDynamic: {
631 dos.writeByte(cpConstType); 676 dos.writeByte(cpConstType);
632 int value = getIntAt(ci); 677 int value = getIntAt(ci);
633 short bsmIndex = (short) extractLowShortFromInt(value); 678 short bsmIndex = (short) extractLowShortFromInt(value);
634 short nameAndTypeIndex = (short) extractHighShortFromInt(value); 679 short nameAndTypeIndex = (short) extractHighShortFromInt(value);
635 dos.writeShort(bsmIndex); 680 dos.writeShort(bsmIndex);
636 dos.writeShort(nameAndTypeIndex); 681 dos.writeShort(nameAndTypeIndex);
637 if (DEBUG) debugMessage("CP[" + ci + "] = indy BSM = " + bsmIndex 682 if (DEBUG) debugMessage("CP[" + ci + "] = INDY bsm = " +
638 + ", N&T = " + nameAndTypeIndex); 683 bsmIndex + ", N&T = " + nameAndTypeIndex);
639 break; 684 break;
640 } 685 }
641 686
642 default: 687 default:
643 throw new InternalError("unknown tag: " + cpConstType); 688 throw new InternalError("Unknown tag: " + cpConstType);
644 } // switch 689 } // switch
645 } 690 }
646 dos.flush(); 691 dos.flush();
647 return; 692 return;
648 } 693 }
649 694
650 public void printValueOn(PrintStream tty) { 695 public void printValueOn(PrintStream tty) {
651 Oop holder = poolHolder.getValue(this); 696 tty.print("ConstantPool for " + getPoolHolder().getName().asString());
652 if (holder instanceof Klass) { 697 }
653 tty.print("ConstantPool for " + ((Klass)holder).getName().asString()); 698
654 } else { 699 public long getSize() {
655 tty.print("ConstantPool for partially loaded class"); 700 return Oop.alignObjectSize(headerSize + getLength());
656 }
657 }
658
659 public long getObjectSize() {
660 return alignObjectSize(headerSize + (getLength() * getElementSize()));
661 } 701 }
662 702
663 //---------------------------------------------------------------------- 703 //----------------------------------------------------------------------
664 // Internals only below this point 704 // Internals only below this point
665 // 705 //
666 706
667 private static int extractHighShortFromInt(int val) { 707 private static int extractHighShortFromInt(int val) {
668 // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. 708 // must stay in sync with ConstantPool::name_and_type_at_put, method_at_put, etc.
669 return (val >> 16) & 0xFFFF; 709 return (val >> 16) & 0xFFFF;
670 } 710 }
671 711
672 private static int extractLowShortFromInt(int val) { 712 private static int extractLowShortFromInt(int val) {
673 // must stay in sync with constantPoolOopDesc::name_and_type_at_put, method_at_put, etc. 713 // must stay in sync with ConstantPool::name_and_type_at_put, method_at_put, etc.
674 return val & 0xFFFF; 714 return val & 0xFFFF;
675 } 715 }
676 } 716 }