@@ -109,11 +109,16 @@ public class ClassReader {
109
109
private final int [] cpInfoOffsets ;
110
110
111
111
/**
112
- * The value of each cp_info entry of the ClassFile's constant_pool array, <i>for Constant_Utf8
113
- * and Constant_Dynamic constants only</i>. The value of constant pool entry i is given by
114
- * cpInfoValues[i]. This cache avoids multiple parsing of those constant pool items.
112
+ * The String objects corresponding to the CONSTANT_Utf8 constant pool items. This cache avoids
113
+ * multiple parsing of a given CONSTANT_Utf8 constant pool item.
115
114
*/
116
- private final Object [] cpInfoValues ;
115
+ private final String [] constantUtf8Values ;
116
+
117
+ /**
118
+ * The ConstantDynamic objects corresponding to the CONSTANT_Dynamic constant pool items. This
119
+ * cache avoids multiple parsing of a given CONSTANT_Dynamic constant pool item.
120
+ */
121
+ private final ConstantDynamic [] constantDynamicValues ;
117
122
118
123
/**
119
124
* The start offsets in {@link #b} of each element of the bootstrap_methods array (in the
@@ -168,7 +173,7 @@ public ClassReader(
168
173
*/
169
174
ClassReader (
170
175
final byte [] classFileBuffer , final int classFileOffset , final boolean checkClassVersion ) {
171
- this . b = classFileBuffer ;
176
+ b = classFileBuffer ;
172
177
// Check the class' major_version. This field is after the magic and minor_version fields, which
173
178
// use 4 and 2 bytes respectively.
174
179
if (checkClassVersion && readShort (classFileOffset + 6 ) > Opcodes .V12 ) {
@@ -179,15 +184,16 @@ public ClassReader(
179
184
// minor_version and major_version fields, which use 4, 2 and 2 bytes respectively.
180
185
int constantPoolCount = readUnsignedShort (classFileOffset + 8 );
181
186
cpInfoOffsets = new int [constantPoolCount ];
182
- cpInfoValues = new Object [constantPoolCount ];
187
+ constantUtf8Values = new String [constantPoolCount ];
183
188
// Compute the offset of each constant pool entry, as well as a conservative estimate of the
184
189
// maximum length of the constant pool strings. The first constant pool entry is after the
185
190
// magic, minor_version, major_version and constant_pool_count fields, which use 4, 2, 2 and 2
186
191
// bytes respectively.
187
192
int currentCpInfoIndex = 1 ;
188
193
int currentCpInfoOffset = classFileOffset + 10 ;
189
194
int currentMaxStringLength = 0 ;
190
- boolean hasBootstrapMethods = false ;
195
+ boolean hasConstantDynamic = false ;
196
+ boolean hasConstantInvokeDynamic = false ;
191
197
// The offset of the other entries depend on the total size of all the previous entries.
192
198
while (currentCpInfoIndex < constantPoolCount ) {
193
199
cpInfoOffsets [currentCpInfoIndex ++] = currentCpInfoOffset + 1 ;
@@ -201,10 +207,13 @@ public ClassReader(
201
207
case Symbol .CONSTANT_NAME_AND_TYPE_TAG :
202
208
cpInfoSize = 5 ;
203
209
break ;
204
- case Symbol .CONSTANT_INVOKE_DYNAMIC_TAG :
205
210
case Symbol .CONSTANT_DYNAMIC_TAG :
206
211
cpInfoSize = 5 ;
207
- hasBootstrapMethods = true ;
212
+ hasConstantDynamic = true ;
213
+ break ;
214
+ case Symbol .CONSTANT_INVOKE_DYNAMIC_TAG :
215
+ cpInfoSize = 5 ;
216
+ hasConstantInvokeDynamic = true ;
208
217
break ;
209
218
case Symbol .CONSTANT_LONG_TAG :
210
219
case Symbol .CONSTANT_DOUBLE_TAG :
@@ -235,13 +244,18 @@ public ClassReader(
235
244
}
236
245
currentCpInfoOffset += cpInfoSize ;
237
246
}
238
- this . maxStringLength = currentMaxStringLength ;
247
+ maxStringLength = currentMaxStringLength ;
239
248
// The Classfile's access_flags field is just after the last constant pool entry.
240
- this .header = currentCpInfoOffset ;
249
+ header = currentCpInfoOffset ;
250
+
251
+ // Allocate the cache of ConstantDynamic values, if there is at least one.
252
+ constantDynamicValues = hasConstantDynamic ? new ConstantDynamic [constantPoolCount ] : null ;
241
253
242
254
// Read the BootstrapMethods attribute, if any (only get the offset of each method).
243
- this .bootstrapMethodOffsets =
244
- hasBootstrapMethods ? readBootstrapMethodsAttribute (currentMaxStringLength ) : null ;
255
+ bootstrapMethodOffsets =
256
+ (hasConstantDynamic | hasConstantInvokeDynamic )
257
+ ? readBootstrapMethodsAttribute (currentMaxStringLength )
258
+ : null ;
245
259
}
246
260
247
261
/**
@@ -3403,14 +3417,13 @@ public String readUTF8(final int offset, final char[] charBuffer) {
3403
3417
* @return the String corresponding to the specified CONSTANT_Utf8 entry.
3404
3418
*/
3405
3419
final String readUTF (final int constantPoolEntryIndex , final char [] charBuffer ) {
3406
- String value = ( String ) cpInfoValues [constantPoolEntryIndex ];
3420
+ String value = constantUtf8Values [constantPoolEntryIndex ];
3407
3421
if (value != null ) {
3408
3422
return value ;
3409
3423
}
3410
3424
int cpInfoOffset = cpInfoOffsets [constantPoolEntryIndex ];
3411
- value = readUTF (cpInfoOffset + 2 , readUnsignedShort (cpInfoOffset ), charBuffer );
3412
- cpInfoValues [constantPoolEntryIndex ] = value ;
3413
- return value ;
3425
+ return constantUtf8Values [constantPoolEntryIndex ] =
3426
+ readUTF (cpInfoOffset + 2 , readUnsignedShort (cpInfoOffset ), charBuffer );
3414
3427
}
3415
3428
3416
3429
/**
@@ -3516,7 +3529,7 @@ public String readPackage(final int offset, final char[] charBuffer) {
3516
3529
*/
3517
3530
private ConstantDynamic readConstantDynamic (
3518
3531
final int constantPoolEntryIndex , final char [] charBuffer ) {
3519
- ConstantDynamic constantDynamic = ( ConstantDynamic ) cpInfoValues [constantPoolEntryIndex ];
3532
+ ConstantDynamic constantDynamic = constantDynamicValues [constantPoolEntryIndex ];
3520
3533
if (constantDynamic != null ) {
3521
3534
return constantDynamic ;
3522
3535
}
@@ -3532,9 +3545,8 @@ private ConstantDynamic readConstantDynamic(
3532
3545
bootstrapMethodArguments [i ] = readConst (readUnsignedShort (bootstrapMethodOffset ), charBuffer );
3533
3546
bootstrapMethodOffset += 2 ;
3534
3547
}
3535
- constantDynamic = new ConstantDynamic (name , descriptor , handle , bootstrapMethodArguments );
3536
- cpInfoValues [constantPoolEntryIndex ] = constantDynamic ;
3537
- return constantDynamic ;
3548
+ return constantDynamicValues [constantPoolEntryIndex ] =
3549
+ new ConstantDynamic (name , descriptor , handle , bootstrapMethodArguments );
3538
3550
}
3539
3551
3540
3552
/**
0 commit comments