Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
41161 views
1
/*
2
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
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
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
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
import sun.jvm.hotspot.utilities.Observable;
34
import sun.jvm.hotspot.utilities.Observer;
35
36
// A ConstantPool is an oop containing class constants
37
// as described in the class file
38
39
public class ConstantPool extends Metadata implements ClassConstants {
40
private class CPSlot {
41
private Address ptr;
42
43
CPSlot(Address ptr) {
44
this.ptr = ptr;
45
}
46
47
public Symbol getSymbol() {
48
// (Lowest bit == 1) -> this is an pseudo string.
49
return Symbol.create(ptr.andWithMask(~1));
50
}
51
}
52
private class CPKlassSlot {
53
private int name_index;
54
private int resolved_klass_index;
55
private static final int temp_resolved_klass_index = 0xffff;
56
57
public CPKlassSlot(int n, int rk) {
58
name_index = n;
59
resolved_klass_index = rk;
60
}
61
public int getNameIndex() {
62
return name_index;
63
}
64
public int getResolvedKlassIndex() {
65
if (Assert.ASSERTS_ENABLED) {
66
Assert.that(resolved_klass_index != temp_resolved_klass_index, "constant pool merging was incomplete");
67
}
68
return resolved_klass_index;
69
}
70
}
71
72
// Used for debugging this code
73
private static final boolean DEBUG = false;
74
75
protected void debugMessage(String message) {
76
System.out.println(message);
77
}
78
79
static {
80
VM.registerVMInitializedObserver(new Observer() {
81
public void update(Observable o, Object data) {
82
initialize(VM.getVM().getTypeDataBase());
83
}
84
});
85
}
86
87
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
88
Type type = db.lookupType("ConstantPool");
89
tags = type.getAddressField("_tags");
90
operands = type.getAddressField("_operands");
91
cache = type.getAddressField("_cache");
92
poolHolder = new MetadataField(type.getAddressField("_pool_holder"), 0);
93
length = new CIntField(type.getCIntegerField("_length"), 0);
94
resolved_klasses = type.getAddressField("_resolved_klasses");
95
majorVersion = new CIntField(type.getCIntegerField("_major_version"), 0);
96
minorVersion = new CIntField(type.getCIntegerField("_minor_version"), 0);
97
sourceFileNameIndex = new CIntField(type.getCIntegerField("_source_file_name_index"), 0);
98
genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
99
headerSize = type.getSize();
100
elementSize = 0;
101
// fetch constants:
102
INDY_BSM_OFFSET = db.lookupIntConstant("ConstantPool::_indy_bsm_offset").intValue();
103
INDY_ARGC_OFFSET = db.lookupIntConstant("ConstantPool::_indy_argc_offset").intValue();
104
INDY_ARGV_OFFSET = db.lookupIntConstant("ConstantPool::_indy_argv_offset").intValue();
105
}
106
107
public ConstantPool(Address addr) {
108
super(addr);
109
}
110
111
public boolean isConstantPool() { return true; }
112
113
private static AddressField tags;
114
private static AddressField operands;
115
private static AddressField cache;
116
private static AddressField resolved_klasses;
117
private static MetadataField poolHolder;
118
private static CIntField length; // number of elements in oop
119
private static CIntField majorVersion;
120
private static CIntField minorVersion;
121
private static CIntField genericSignatureIndex;
122
private static CIntField sourceFileNameIndex;
123
124
private static long headerSize;
125
private static long elementSize;
126
127
private static int INDY_BSM_OFFSET;
128
private static int INDY_ARGC_OFFSET;
129
private static int INDY_ARGV_OFFSET;
130
131
public U1Array getTags() { return new U1Array(tags.getValue(getAddress())); }
132
public U2Array getOperands() { return new U2Array(operands.getValue(getAddress())); }
133
public ConstantPoolCache getCache() {
134
Address addr = cache.getValue(getAddress());
135
return (ConstantPoolCache) VMObjectFactory.newObject(ConstantPoolCache.class, addr);
136
}
137
public InstanceKlass getPoolHolder() { return (InstanceKlass)poolHolder.getValue(this); }
138
public int getLength() { return (int)length.getValue(getAddress()); }
139
public Oop getResolvedReferences() {
140
return getCache().getResolvedReferences();
141
}
142
public long majorVersion() { return majorVersion.getValue(this); }
143
public long minorVersion() { return minorVersion.getValue(this); }
144
145
public Symbol getGenericSignature() {
146
long index = genericSignatureIndex.getValue(this);
147
if (index != 0) {
148
return getSymbolAt(index);
149
} else {
150
return null;
151
}
152
}
153
154
public Symbol getSourceFileName() { return getSymbolAt(sourceFileNameIndex.getValue(this)); }
155
156
public KlassArray getResolvedKlasses() {
157
return new KlassArray(resolved_klasses.getValue(getAddress()));
158
}
159
160
public U2Array referenceMap() {
161
return getCache().referenceMap();
162
}
163
164
public int objectToCPIndex(int index) {
165
return referenceMap().at(index);
166
}
167
168
private long getElementSize() {
169
if (elementSize !=0 ) {
170
return elementSize;
171
} else {
172
elementSize = VM.getVM().getOopSize();
173
}
174
return elementSize;
175
}
176
177
private long indexOffset(long index) {
178
if (Assert.ASSERTS_ENABLED) {
179
Assert.that(index >= 0 && index < getLength(), "invalid cp index " + index + " " + getLength());
180
}
181
return (index * getElementSize()) + headerSize;
182
}
183
184
public ConstantTag getTagAt(long index) {
185
return new ConstantTag((byte)getTags().at((int) index));
186
}
187
188
public CPSlot getSlotAt(long index) {
189
return new CPSlot(getAddressAtRaw(index));
190
}
191
192
public CPKlassSlot getKlassSlotAt(long index) {
193
if (Assert.ASSERTS_ENABLED) {
194
Assert.that(getTagAt(index).isUnresolvedKlass() || getTagAt(index).isKlass(), "Corrupted constant pool");
195
}
196
int value = getIntAt(index);
197
int name_index = extractHighShortFromInt(value);
198
int resolved_klass_index = extractLowShortFromInt(value);
199
return new CPKlassSlot(name_index, resolved_klass_index);
200
}
201
202
public Address getAddressAtRaw(long index) {
203
return getAddress().getAddressAt(indexOffset(index));
204
}
205
206
public Symbol getSymbolAt(long index) {
207
return Symbol.create(getAddressAtRaw(index));
208
}
209
210
public int getIntAt(long index){
211
return getAddress().getJIntAt(indexOffset(index));
212
}
213
214
public float getFloatAt(long index){
215
return getAddress().getJFloatAt(indexOffset(index));
216
}
217
218
public long getLongAt(long index) {
219
int oneHalf = getAddress().getJIntAt(indexOffset(index + 1));
220
int otherHalf = getAddress().getJIntAt(indexOffset(index));
221
// buildLongFromIntsPD accepts higher address value, lower address value
222
// in that order.
223
return VM.getVM().buildLongFromIntsPD(oneHalf, otherHalf);
224
}
225
226
public double getDoubleAt(long index) {
227
return Double.longBitsToDouble(getLongAt(index));
228
}
229
230
public int getFieldOrMethodAt(int which) {
231
if (DEBUG) {
232
System.err.print("ConstantPool.getFieldOrMethodAt(" + which + "): new index = ");
233
}
234
int i = -1;
235
ConstantPoolCache cache = getCache();
236
if (cache == null) {
237
i = which;
238
} else {
239
// change byte-ordering and go via cache
240
i = cache.getEntryAt(0xFFFF & which).getConstantPoolIndex();
241
}
242
if (Assert.ASSERTS_ENABLED) {
243
Assert.that(getTagAt(i).isFieldOrMethod(), "Corrupted constant pool");
244
}
245
if (DEBUG) {
246
System.err.println(i);
247
}
248
int res = getIntAt(i);
249
if (DEBUG) {
250
System.err.println("ConstantPool.getFieldOrMethodAt(" + i + "): result = " + res);
251
}
252
return res;
253
}
254
255
public int[] getNameAndTypeAt(int which) {
256
if (Assert.ASSERTS_ENABLED) {
257
Assert.that(getTagAt(which).isNameAndType(), "Corrupted constant pool: " + which + " " + getTagAt(which));
258
}
259
int i = getIntAt(which);
260
if (DEBUG) {
261
System.err.println("ConstantPool.getNameAndTypeAt(" + which + "): result = " + i);
262
}
263
return new int[] { extractLowShortFromInt(i), extractHighShortFromInt(i) };
264
}
265
266
public Symbol getNameRefAt(int which) {
267
return implGetNameRefAt(which, false);
268
}
269
270
public Symbol uncachedGetNameRefAt(int which) {
271
return implGetNameRefAt(which, true);
272
}
273
274
private Symbol implGetNameRefAt(int which, boolean uncached) {
275
int signatureIndex = getNameRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
276
return getSymbolAt(signatureIndex);
277
}
278
279
public Symbol getSignatureRefAt(int which) {
280
return implGetSignatureRefAt(which, false);
281
}
282
283
public Symbol uncachedGetSignatureRefAt(int which) {
284
return implGetSignatureRefAt(which, true);
285
}
286
287
private Symbol implGetSignatureRefAt(int which, boolean uncached) {
288
int signatureIndex = getSignatureRefIndexAt(implNameAndTypeRefIndexAt(which, uncached));
289
return getSymbolAt(signatureIndex);
290
}
291
292
public static boolean isInvokedynamicIndex(int i) { return (i < 0); }
293
294
public static int decodeInvokedynamicIndex(int i) { Assert.that(isInvokedynamicIndex(i), ""); return ~i; }
295
296
// The invokedynamic points at a CP cache entry. This entry points back
297
// at the original CP entry (CONSTANT_InvokeDynamic) and also (via f2) at an entry
298
// in the resolved_references array (which provides the appendix argument).
299
public int invokedynamicCPCacheIndex(int index) {
300
Assert.that(isInvokedynamicIndex(index), "should be a invokedynamic index");
301
return decodeInvokedynamicIndex(index);
302
}
303
304
ConstantPoolCacheEntry invokedynamicCPCacheEntryAt(int index) {
305
// decode index that invokedynamic points to.
306
int cpCacheIndex = invokedynamicCPCacheIndex(index);
307
return getCache().getEntryAt(cpCacheIndex);
308
}
309
310
private int implNameAndTypeRefIndexAt(int which, boolean uncached) {
311
int i = which;
312
if (!uncached && getCache() != null) {
313
if (isInvokedynamicIndex(which)) {
314
// Invokedynamic index is index into resolved_references
315
int poolIndex = invokedynamicCPCacheEntryAt(which).getConstantPoolIndex();
316
poolIndex = invokeDynamicNameAndTypeRefIndexAt(poolIndex);
317
Assert.that(getTagAt(poolIndex).isNameAndType(), "");
318
return poolIndex;
319
}
320
// change byte-ordering and go via cache
321
i = remapInstructionOperandFromCache(which);
322
} else {
323
if (getTagAt(which).isInvokeDynamic() || getTagAt(which).isDynamicConstant()) {
324
int poolIndex = invokeDynamicNameAndTypeRefIndexAt(which);
325
Assert.that(getTagAt(poolIndex).isNameAndType(), "");
326
return poolIndex;
327
}
328
}
329
// assert(tag_at(i).is_field_or_method(), "Corrupted constant pool");
330
// assert(!tag_at(i).is_invoke_dynamic(), "Must be handled above");
331
int refIndex = getIntAt(i);
332
return extractHighShortFromInt(refIndex);
333
}
334
335
private int remapInstructionOperandFromCache(int operand) {
336
int cpc_index = operand;
337
// DEBUG_ONLY(cpc_index -= CPCACHE_INDEX_TAG);
338
// assert((int)(u2)cpc_index == cpc_index, "clean u2");
339
int member_index = getCache().getEntryAt(cpc_index).getConstantPoolIndex();
340
return member_index;
341
}
342
343
public int invokeDynamicNameAndTypeRefIndexAt(int which) {
344
// assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool");
345
return extractHighShortFromInt(getIntAt(which));
346
}
347
348
// returns null, if not resolved.
349
public Klass getKlassAt(int which) {
350
if( ! getTagAt(which).isKlass()) return null;
351
int resolved_klass_index = getKlassSlotAt(which).getResolvedKlassIndex();
352
KlassArray resolved_klasses = getResolvedKlasses();
353
return resolved_klasses.getAt(resolved_klass_index);
354
}
355
356
public Symbol getKlassNameAt(int which) {
357
int name_index = getKlassSlotAt(which).getNameIndex();
358
return getSymbolAt(name_index);
359
}
360
361
public Symbol getUnresolvedStringAt(int which) {
362
return getSlotAt(which).getSymbol();
363
}
364
365
// returns null, if not resolved.
366
public Klass getFieldOrMethodKlassRefAt(int which) {
367
int refIndex = getFieldOrMethodAt(which);
368
int klassIndex = extractLowShortFromInt(refIndex);
369
return getKlassAt(klassIndex);
370
}
371
372
// returns null, if not resolved.
373
public Method getMethodRefAt(int which) {
374
Klass klass = getFieldOrMethodKlassRefAt(which);
375
if (klass == null) return null;
376
Symbol name = getNameRefAt(which);
377
Symbol sig = getSignatureRefAt(which);
378
// Consider the super class for arrays. (java.lang.Object)
379
if (klass.isArrayKlass()) {
380
klass = klass.getJavaSuper();
381
}
382
return ((InstanceKlass)klass).findMethod(name.asString(), sig.asString());
383
}
384
385
// returns null, if not resolved.
386
public Field getFieldRefAt(int which) {
387
InstanceKlass klass = (InstanceKlass)getFieldOrMethodKlassRefAt(which);
388
if (klass == null) return null;
389
Symbol name = getNameRefAt(which);
390
Symbol sig = getSignatureRefAt(which);
391
return klass.findField(name.asString(), sig.asString());
392
}
393
394
public int getNameAndTypeRefIndexAt(int index) {
395
return implNameAndTypeRefIndexAt(index, false);
396
}
397
398
/** Lookup for entries consisting of (name_index, signature_index) */
399
public int getNameRefIndexAt(int index) {
400
int[] refIndex = getNameAndTypeAt(index);
401
if (DEBUG) {
402
System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]);
403
}
404
int i = refIndex[0];
405
if (DEBUG) {
406
System.err.println("ConstantPool.getNameRefIndexAt(" + index + "): result = " + i);
407
}
408
return i;
409
}
410
411
/** Lookup for entries consisting of (name_index, signature_index) */
412
public int getSignatureRefIndexAt(int index) {
413
int[] refIndex = getNameAndTypeAt(index);
414
if (DEBUG) {
415
System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): refIndex = " + refIndex[0]+"/"+refIndex[1]);
416
}
417
int i = refIndex[1];
418
if (DEBUG) {
419
System.err.println("ConstantPool.getSignatureRefIndexAt(" + index + "): result = " + i);
420
}
421
return i;
422
}
423
424
/** Lookup for MethodHandle entries. */
425
public int getMethodHandleIndexAt(int i) {
426
if (Assert.ASSERTS_ENABLED) {
427
Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool");
428
}
429
int res = extractHighShortFromInt(getIntAt(i));
430
if (DEBUG) {
431
System.err.println("ConstantPool.getMethodHandleIndexAt(" + i + "): result = " + res);
432
}
433
return res;
434
}
435
436
/** Lookup for MethodHandle entries. */
437
public int getMethodHandleRefKindAt(int i) {
438
if (Assert.ASSERTS_ENABLED) {
439
Assert.that(getTagAt(i).isMethodHandle(), "Corrupted constant pool");
440
}
441
int res = extractLowShortFromInt(getIntAt(i));
442
if (DEBUG) {
443
System.err.println("ConstantPool.getMethodHandleRefKindAt(" + i + "): result = " + res);
444
}
445
return res;
446
}
447
448
/** Lookup for MethodType entries. */
449
public int getMethodTypeIndexAt(int i) {
450
if (Assert.ASSERTS_ENABLED) {
451
Assert.that(getTagAt(i).isMethodType(), "Corrupted constant pool");
452
}
453
int res = getIntAt(i);
454
if (DEBUG) {
455
System.err.println("ConstantPool.getMethodHandleTypeAt(" + i + "): result = " + res);
456
}
457
return res;
458
}
459
460
/** Lookup for multi-operand (InvokeDynamic, Dynamic) entries. */
461
public short[] getBootstrapSpecifierAt(int i) {
462
if (Assert.ASSERTS_ENABLED) {
463
Assert.that(getTagAt(i).isInvokeDynamic() || getTagAt(i).isDynamicConstant(), "Corrupted constant pool");
464
}
465
int bsmSpec = extractLowShortFromInt(this.getIntAt(i));
466
U2Array operands = getOperands();
467
if (operands == null) return null; // safety first
468
int basePos = VM.getVM().buildIntFromShorts(operands.at(bsmSpec * 2 + 0),
469
operands.at(bsmSpec * 2 + 1));
470
int argv = basePos + INDY_ARGV_OFFSET;
471
int argc = operands.at(basePos + INDY_ARGC_OFFSET);
472
int endPos = argv + argc;
473
short[] values = new short[endPos - basePos];
474
for (int j = 0; j < values.length; j++) {
475
values[j] = operands.at(basePos+j);
476
}
477
return values;
478
}
479
480
final private static String[] nameForTag = new String[] {
481
};
482
483
private String nameForTag(int tag) {
484
switch (tag) {
485
case JVM_CONSTANT_Utf8: return "JVM_CONSTANT_Utf8";
486
case JVM_CONSTANT_Unicode: return "JVM_CONSTANT_Unicode";
487
case JVM_CONSTANT_Integer: return "JVM_CONSTANT_Integer";
488
case JVM_CONSTANT_Float: return "JVM_CONSTANT_Float";
489
case JVM_CONSTANT_Long: return "JVM_CONSTANT_Long";
490
case JVM_CONSTANT_Double: return "JVM_CONSTANT_Double";
491
case JVM_CONSTANT_Class: return "JVM_CONSTANT_Class";
492
case JVM_CONSTANT_String: return "JVM_CONSTANT_String";
493
case JVM_CONSTANT_Fieldref: return "JVM_CONSTANT_Fieldref";
494
case JVM_CONSTANT_Methodref: return "JVM_CONSTANT_Methodref";
495
case JVM_CONSTANT_InterfaceMethodref: return "JVM_CONSTANT_InterfaceMethodref";
496
case JVM_CONSTANT_NameAndType: return "JVM_CONSTANT_NameAndType";
497
case JVM_CONSTANT_MethodHandle: return "JVM_CONSTANT_MethodHandle";
498
case JVM_CONSTANT_MethodType: return "JVM_CONSTANT_MethodType";
499
case JVM_CONSTANT_Dynamic: return "JVM_CONSTANT_Dynamic";
500
case JVM_CONSTANT_InvokeDynamic: return "JVM_CONSTANT_InvokeDynamic";
501
case JVM_CONSTANT_Invalid: return "JVM_CONSTANT_Invalid";
502
case JVM_CONSTANT_UnresolvedClass: return "JVM_CONSTANT_UnresolvedClass";
503
case JVM_CONSTANT_ClassIndex: return "JVM_CONSTANT_ClassIndex";
504
case JVM_CONSTANT_StringIndex: return "JVM_CONSTANT_StringIndex";
505
case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError";
506
case JVM_CONSTANT_MethodHandleInError:return "JVM_CONSTANT_MethodHandleInError";
507
case JVM_CONSTANT_MethodTypeInError: return "JVM_CONSTANT_MethodTypeInError";
508
}
509
throw new InternalError("Unknown tag: " + tag);
510
}
511
512
public void iterateFields(MetadataVisitor visitor) {
513
super.iterateFields(visitor);
514
visitor.doMetadata(poolHolder, true);
515
516
final int length = (int) getLength();
517
// zero'th pool entry is always invalid. ignore it.
518
for (int index = 1; index < length; index++) {
519
int ctag = (int) getTags().at((int) index);
520
switch (ctag) {
521
case JVM_CONSTANT_ClassIndex:
522
case JVM_CONSTANT_StringIndex:
523
case JVM_CONSTANT_Integer:
524
visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
525
break;
526
527
case JVM_CONSTANT_Float:
528
visitor.doFloat(new FloatField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
529
break;
530
531
case JVM_CONSTANT_Long:
532
visitor.doLong(new LongField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
533
// long entries occupy two slots
534
index++;
535
break;
536
537
case JVM_CONSTANT_Double:
538
visitor.doDouble(new DoubleField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
539
// double entries occupy two slots
540
index++;
541
break;
542
543
case JVM_CONSTANT_UnresolvedClassInError:
544
case JVM_CONSTANT_UnresolvedClass:
545
case JVM_CONSTANT_Class:
546
case JVM_CONSTANT_Utf8:
547
visitor.doOop(new OopField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
548
break;
549
550
case JVM_CONSTANT_Fieldref:
551
case JVM_CONSTANT_Methodref:
552
case JVM_CONSTANT_InterfaceMethodref:
553
case JVM_CONSTANT_NameAndType:
554
case JVM_CONSTANT_MethodHandle:
555
case JVM_CONSTANT_MethodType:
556
case JVM_CONSTANT_Dynamic:
557
case JVM_CONSTANT_InvokeDynamic:
558
visitor.doInt(new IntField(new NamedFieldIdentifier(nameForTag(ctag)), indexOffset(index), true), true);
559
break;
560
}
561
}
562
}
563
564
public void writeBytes(OutputStream os) throws IOException {
565
// Map between any modified UTF-8 and it's constant pool index.
566
Map<String, Short> utf8ToIndex = new HashMap<>();
567
DataOutputStream dos = new DataOutputStream(os);
568
U1Array tags = getTags();
569
int len = (int)getLength();
570
int ci = 0; // constant pool index
571
572
// collect all modified UTF-8 Strings from Constant Pool
573
574
for (ci = 1; ci < len; ci++) {
575
int cpConstType = tags.at(ci);
576
if(cpConstType == JVM_CONSTANT_Utf8) {
577
Symbol sym = getSymbolAt(ci);
578
utf8ToIndex.put(sym.asString(), (short) ci);
579
}
580
else if(cpConstType == JVM_CONSTANT_Long ||
581
cpConstType == JVM_CONSTANT_Double) {
582
ci++;
583
}
584
}
585
586
587
for(ci = 1; ci < len; ci++) {
588
int cpConstType = tags.at(ci);
589
// write cp_info
590
// write constant type
591
switch(cpConstType) {
592
case JVM_CONSTANT_Utf8: {
593
dos.writeByte(cpConstType);
594
Symbol sym = getSymbolAt(ci);
595
dos.writeShort((short)sym.getLength());
596
dos.write(sym.asByteArray());
597
if (DEBUG) debugMessage("CP[" + ci + "] = modified UTF-8 " + sym.asString());
598
break;
599
}
600
601
case JVM_CONSTANT_Unicode:
602
throw new IllegalArgumentException("Unicode constant!");
603
604
case JVM_CONSTANT_Integer:
605
dos.writeByte(cpConstType);
606
dos.writeInt(getIntAt(ci));
607
if (DEBUG) debugMessage("CP[" + ci + "] = int " + getIntAt(ci));
608
break;
609
610
case JVM_CONSTANT_Float:
611
dos.writeByte(cpConstType);
612
dos.writeFloat(getFloatAt(ci));
613
if (DEBUG) debugMessage("CP[" + ci + "] = float " + getFloatAt(ci));
614
break;
615
616
case JVM_CONSTANT_Long: {
617
dos.writeByte(cpConstType);
618
long l = getLongAt(ci);
619
// long entries occupy two pool entries
620
ci++;
621
dos.writeLong(l);
622
break;
623
}
624
625
case JVM_CONSTANT_Double:
626
dos.writeByte(cpConstType);
627
dos.writeDouble(getDoubleAt(ci));
628
// double entries occupy two pool entries
629
ci++;
630
break;
631
632
case JVM_CONSTANT_Class: {
633
dos.writeByte(cpConstType);
634
// Klass already resolved. ConstantPool constains Klass*.
635
Klass refKls = (Klass)Metadata.instantiateWrapperFor(getAddressAtRaw(ci));
636
String klassName = refKls.getName().asString();
637
Short s = (Short) utf8ToIndex.get(klassName);
638
dos.writeShort(s.shortValue());
639
if (DEBUG) debugMessage("CP[" + ci + "] = class " + s);
640
break;
641
}
642
643
// case JVM_CONSTANT_ClassIndex:
644
case JVM_CONSTANT_UnresolvedClassInError:
645
case JVM_CONSTANT_UnresolvedClass: {
646
dos.writeByte(JVM_CONSTANT_Class);
647
String klassName = getSymbolAt(ci).asString();
648
Short s = (Short) utf8ToIndex.get(klassName);
649
dos.writeShort(s.shortValue());
650
if (DEBUG) debugMessage("CP[" + ci + "] = class " + s);
651
break;
652
}
653
654
case JVM_CONSTANT_String: {
655
dos.writeByte(cpConstType);
656
String str = getUnresolvedStringAt(ci).asString();
657
Short s = (Short) utf8ToIndex.get(str);
658
dos.writeShort(s.shortValue());
659
if (DEBUG) debugMessage("CP[" + ci + "] = string " + s);
660
break;
661
}
662
663
// all external, internal method/field references
664
case JVM_CONSTANT_Fieldref:
665
case JVM_CONSTANT_Methodref:
666
case JVM_CONSTANT_InterfaceMethodref: {
667
dos.writeByte(cpConstType);
668
int value = getIntAt(ci);
669
short klassIndex = (short) extractLowShortFromInt(value);
670
short nameAndTypeIndex = (short) extractHighShortFromInt(value);
671
dos.writeShort(klassIndex);
672
dos.writeShort(nameAndTypeIndex);
673
if (DEBUG) debugMessage("CP[" + ci + "] = ref klass = " +
674
klassIndex + ", N&T = " + nameAndTypeIndex);
675
break;
676
}
677
678
case JVM_CONSTANT_NameAndType: {
679
dos.writeByte(cpConstType);
680
int value = getIntAt(ci);
681
short nameIndex = (short) extractLowShortFromInt(value);
682
short signatureIndex = (short) extractHighShortFromInt(value);
683
dos.writeShort(nameIndex);
684
dos.writeShort(signatureIndex);
685
if (DEBUG) debugMessage("CP[" + ci + "] = N&T name = " + nameIndex
686
+ ", type = " + signatureIndex);
687
break;
688
}
689
690
case JVM_CONSTANT_MethodHandle: {
691
dos.writeByte(cpConstType);
692
int value = getIntAt(ci);
693
byte refKind = (byte) extractLowShortFromInt(value);
694
short memberIndex = (short) extractHighShortFromInt(value);
695
dos.writeByte(refKind);
696
dos.writeShort(memberIndex);
697
if (DEBUG) debugMessage("CP[" + ci + "] = MH kind = " +
698
refKind + ", mem = " + memberIndex);
699
break;
700
}
701
702
case JVM_CONSTANT_MethodType: {
703
dos.writeByte(cpConstType);
704
int value = getIntAt(ci);
705
short refIndex = (short) value;
706
dos.writeShort(refIndex);
707
if (DEBUG) debugMessage("CP[" + ci + "] = MT index = " + refIndex);
708
break;
709
}
710
711
case JVM_CONSTANT_InvokeDynamic: {
712
dos.writeByte(cpConstType);
713
int value = getIntAt(ci);
714
short bsmIndex = (short) extractLowShortFromInt(value);
715
short nameAndTypeIndex = (short) extractHighShortFromInt(value);
716
dos.writeShort(bsmIndex);
717
dos.writeShort(nameAndTypeIndex);
718
if (DEBUG) debugMessage("CP[" + ci + "] = INDY bsm = " +
719
bsmIndex + ", N&T = " + nameAndTypeIndex);
720
break;
721
}
722
723
default:
724
throw new InternalError("Unknown tag: " + cpConstType);
725
} // switch
726
}
727
dos.flush();
728
return;
729
}
730
731
public void printValueOn(PrintStream tty) {
732
tty.print("ConstantPool for " + getPoolHolder().getName().asString());
733
}
734
735
public long getSize() {
736
return alignSize(headerSize + getLength());
737
}
738
739
//----------------------------------------------------------------------
740
// Internals only below this point
741
//
742
743
private static int extractHighShortFromInt(int val) {
744
// must stay in sync with ConstantPool::name_and_type_at_put, method_at_put, etc.
745
return (val >> 16) & 0xFFFF;
746
}
747
748
private static int extractLowShortFromInt(int val) {
749
// must stay in sync with ConstantPool::name_and_type_at_put, method_at_put, etc.
750
return val & 0xFFFF;
751
}
752
}
753
754