Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/bcutil/ClassFileOracle.hpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2001, 2022 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
/*
24
* ClassFileOracle.hpp
25
*/
26
27
#ifndef CLASSFILEORACLE_HPP_
28
#define CLASSFILEORACLE_HPP_
29
30
/* @ddr_namespace: default */
31
#include "j9comp.h"
32
#include "cfr.h"
33
#include "cfreader.h"
34
#include "ut_j9bcu.h"
35
#include "bcnames.h"
36
37
#include "BuildResult.hpp"
38
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
39
#include "VMHelpers.hpp"
40
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
41
42
/*
43
* It is not guaranteed that slot1 value for constantpool index=0 entry will be zero.
44
* Therefore check the index first, if it is zero, return zero instead of returning the value in slot1.
45
*
46
* */
47
#define UTF8_INDEX_FROM_CLASS_INDEX(cp, cpIndex) ((U_16)((cpIndex == 0)? 0 : cp[cpIndex].slot1))
48
49
class BufferManager;
50
class ConstantPoolMap;
51
class ROMClassCreationContext;
52
53
class ClassFileOracle
54
{
55
public:
56
class VerificationTypeInfo;
57
class ArrayAnnotationElements;
58
class NestedAnnotation;
59
60
struct FieldInfo
61
{
62
bool isSynthetic;
63
bool hasGenericSignature;
64
U_16 genericSignatureIndex;
65
J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute;
66
J9CfrAttributeRuntimeVisibleTypeAnnotations *typeAnnotationsAttribute;
67
bool isFieldContended;
68
};
69
70
struct StackMapFrameInfo
71
{
72
U_8 frameType;
73
U_16 offsetDelta;
74
U_16 localsCount;
75
U_16 stackItemsCount;
76
U_8 *localsTypeInfo;
77
U_8 *stackItemsTypeInfo;
78
};
79
80
struct LocalVariableInfo
81
{
82
J9CfrAttributeLocalVariableTable *localVariableTableAttribute;
83
J9CfrAttributeLocalVariableTypeTable *localVariableTypeTableAttribute;
84
};
85
86
struct BytecodeFixupEntry
87
{
88
U_8 type; /* One of ConstantPoolMap::EntryUseFlags constants. */
89
U_16 cpIndex;
90
U_32 codeIndex;
91
};
92
93
struct MethodInfo
94
{
95
bool hasFrameIteratorSkipAnnotation;
96
U_32 modifiers;
97
U_32 extendedModifiers;
98
U_8 sendSlotCount;
99
U_16 exceptionsThrownCount;
100
U_16 genericSignatureIndex;
101
U_16 stackMapFramesCount;
102
U_32 lineNumbersCount;
103
U_32 lineNumbersInfoCompressedSize;
104
U_32 localVariablesCount;
105
StackMapFrameInfo *stackMapFramesInfo;
106
LocalVariableInfo *localVariablesInfo;
107
U_8 *lineNumbersInfoCompressed;
108
J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute;
109
J9CfrAttributeRuntimeVisibleParameterAnnotations *parameterAnnotationsAttribute;
110
J9CfrAttributeRuntimeVisibleTypeAnnotations *methodTypeAnnotationsAttribute;
111
J9CfrAttributeRuntimeVisibleTypeAnnotations *codeTypeAnnotationsAttribute;
112
J9CfrAttributeAnnotationDefault *defaultAnnotationAttribute;
113
U_32 byteCodeFixupCount;
114
J9CfrAttributeMethodParameters *methodParametersAttribute;
115
BytecodeFixupEntry *byteCodeFixupTable;
116
bool isByteCodeFixupDone;
117
};
118
119
struct RecordComponentInfo
120
{
121
bool hasGenericSignature;
122
U_16 nameIndex;
123
U_16 descriptorIndex;
124
U_16 genericSignatureIndex;
125
J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute;
126
J9CfrAttributeRuntimeVisibleTypeAnnotations *typeAnnotationsAttribute;
127
};
128
129
/*
130
* Interfaces.
131
*/
132
133
struct ConstantPoolIndexVisitor
134
{
135
virtual void visitConstantPoolIndex(U_16 cpIndex) = 0;
136
};
137
138
struct ExceptionHandlerVisitor
139
{
140
virtual void visitExceptionHandler(U_32 startPC, U_32 endPC, U_32 handlerPC, U_16 exceptionClassCPIndex) = 0;
141
};
142
143
struct MethodParametersVisitor
144
{
145
virtual void visitMethodParameters(U_16 cpIndex, U_16 flag) = 0;
146
};
147
148
149
struct VerificationTypeInfoVisitor
150
{
151
virtual void visitStackMapObject(U_8 slotType, U_16 classCPIndex, U_16 classNameCPIndex) = 0;
152
virtual void visitStackMapNewObject(U_8 slotType, U_16 offset) = 0;
153
virtual void visitStackMapItem(U_8 slotType) = 0;
154
};
155
156
struct StackMapFrameVisitor
157
{
158
virtual void visitStackMapFrame(U_16 localsCount, U_16 stackItemsCount, U_16 offsetDelta, U_8 frameType, VerificationTypeInfo *typeInfo) = 0;
159
};
160
161
struct AnnotationElementVisitor
162
{
163
virtual void visitConstant(U_16 elementNameIndex, U_16 cpIndex, U_8 elementType) {}
164
virtual void visitEnum(U_16 elementNameIndex, U_16 typeNameIndex, U_16 constNameIndex) {}
165
virtual void visitClass(U_16 elementNameIndex, U_16 cpIndex) {}
166
virtual void visitArray(U_16 elementNameIndex, U_16 elementCount, ArrayAnnotationElements *arrayAnnotationElements) {}
167
virtual void visitNestedAnnotation(U_16 elementNameIndex, NestedAnnotation *nestedAnnotation) {}
168
};
169
170
struct AnnotationVisitor
171
{
172
virtual void visitParameter(U_16 numberOfAnnotations) = 0;
173
virtual void visitAnnotation(U_16 typeIndex, U_16 elementValuePairCount) = 0;
174
virtual void visitTypeAnnotation(U_8 targetType, J9CfrTypeAnnotationTargetInfo *targetInfo, J9CfrTypePath *typePath) = 0;
175
};
176
177
struct AnnotationsAttributeVisitor
178
{
179
virtual void visitAnnotationsAttribute(U_16 fieldOrMethodIndex, U_32 length, U_16 numberOfAnnotations) = 0;
180
virtual void visitDefaultAnnotationAttribute(U_16 fieldOrMethodIndex, U_32 length) = 0;
181
virtual void visitParameterAnnotationsAttribute(U_16 fieldOrMethodIndex, U_32 length, U_8 numberOfParameters) = 0;
182
virtual void visitTypeAnnotationsAttribute(U_16 fieldOrMethodIndex, U_32 length, U_16 numberOfAnnotations) = 0;
183
virtual void visitMalformedAnnotationsAttribute(U_32 rawDataLength, U_8 *rawAttributeData) = 0;
184
};
185
186
struct BootstrapMethodVisitor
187
{
188
virtual void visitBootstrapMethod(U_16 cpIndex, U_16 argumentCount) = 0;
189
virtual void visitBootstrapArgument(U_16 cpIndex) = 0;
190
};
191
192
/*
193
* Iteration artifacts.
194
*/
195
196
class VerificationTypeInfo
197
{
198
public:
199
VerificationTypeInfo(StackMapFrameInfo *stackMapFrameInfo, J9CfrClassFile *classFile) :
200
_stackMapFrameInfo(stackMapFrameInfo),
201
_classFile(classFile)
202
{
203
}
204
205
void localsDo(VerificationTypeInfoVisitor *visitor) { slotsDo(_stackMapFrameInfo->localsCount, _stackMapFrameInfo->localsTypeInfo, visitor); }
206
void stackItemsDo(VerificationTypeInfoVisitor *visitor) { slotsDo(_stackMapFrameInfo->stackItemsCount, _stackMapFrameInfo->stackItemsTypeInfo, visitor); }
207
208
private:
209
U_16 getParameter(U_8 *bytes) const { return (U_16(bytes[1]) << 8) | U_16(bytes[2]); }
210
void slotsDo(U_16 count, U_8 *bytes, VerificationTypeInfoVisitor *visitor)
211
{
212
for (U_16 i = 0; i < count; ++i) {
213
U_8 slotType = bytes[0];
214
switch (slotType) {
215
case CFR_STACKMAP_TYPE_OBJECT: {
216
U_16 cpIndex = getParameter(bytes);
217
U_16 nameIndex = (U_16) _classFile->constantPool[cpIndex].slot1;
218
visitor->visitStackMapObject(slotType, cpIndex, nameIndex);
219
bytes += 3;
220
break;
221
}
222
case CFR_STACKMAP_TYPE_NEW_OBJECT:
223
visitor->visitStackMapNewObject(slotType, getParameter(bytes));
224
bytes += 3;
225
break;
226
default:
227
visitor->visitStackMapItem(slotType);
228
bytes += 1;
229
break;
230
}
231
}
232
}
233
234
StackMapFrameInfo *_stackMapFrameInfo;
235
J9CfrClassFile *_classFile;
236
};
237
238
class ArrayAnnotationElements
239
{
240
public:
241
ArrayAnnotationElements(ClassFileOracle *classFileOracle, J9CfrAnnotationElementArray *annotationElementArray) :
242
_classFileOracle(classFileOracle),
243
_annotationElementArray(annotationElementArray)
244
{
245
}
246
247
void elementsDo(AnnotationElementVisitor *annotationElementVisitor)
248
{
249
J9CfrAnnotationElement **endAnnotationElements = _annotationElementArray->values + _annotationElementArray->numberOfValues;
250
for (J9CfrAnnotationElement **annotationElement = _annotationElementArray->values; annotationElement != endAnnotationElements; ++annotationElement) {
251
_classFileOracle->annotationElementDo(annotationElementVisitor, 0, *annotationElement);
252
}
253
}
254
255
private:
256
ClassFileOracle *_classFileOracle;
257
J9CfrAnnotationElementArray *_annotationElementArray;
258
};
259
260
class NestedAnnotation
261
{
262
public:
263
NestedAnnotation(ClassFileOracle *classFileOracle, J9CfrAnnotation *annotation) :
264
_classFileOracle(classFileOracle),
265
_annotation(annotation)
266
{
267
}
268
269
void annotationDo(AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor, AnnotationElementVisitor *annotationAnnotationVisitor)
270
{
271
if (NULL != annotationVisitor) {
272
annotationVisitor->visitAnnotation(_annotation->typeIndex, _annotation->numberOfElementValuePairs);
273
}
274
if (NULL != annotationElementVisitor) {
275
_classFileOracle->annotationElementsDo(annotationElementVisitor, _annotation->elementValuePairs, _annotation->numberOfElementValuePairs);
276
}
277
if (NULL != annotationAnnotationVisitor) {
278
_classFileOracle->annotationElementsDo(annotationAnnotationVisitor, _annotation->elementValuePairs, _annotation->numberOfElementValuePairs);
279
}
280
}
281
282
private:
283
ClassFileOracle *_classFileOracle;
284
J9CfrAnnotation *_annotation;
285
};
286
287
class AnnotationAnnotationVisitor : public AnnotationElementVisitor
288
{
289
public:
290
AnnotationAnnotationVisitor(AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor) :
291
_annotationVisitor(annotationVisitor),
292
_annotationElementVisitor(annotationElementVisitor)
293
{
294
}
295
296
void visitArray(U_16 elementNameIndex, U_16 elementCount, ArrayAnnotationElements *arrayAnnotationElements)
297
{
298
arrayAnnotationElements->elementsDo(this);
299
}
300
301
void visitNestedAnnotation(U_16 elementNameIndex, NestedAnnotation *nestedAnnotation)
302
{
303
nestedAnnotation->annotationDo(_annotationVisitor, _annotationElementVisitor, this);
304
}
305
306
private:
307
AnnotationVisitor *_annotationVisitor;
308
AnnotationElementVisitor *_annotationElementVisitor;
309
};
310
311
/*
312
* Iterators.
313
*/
314
315
class FieldIterator
316
{
317
public:
318
FieldIterator(FieldInfo *fieldsInfo, J9CfrClassFile *classFile) :
319
_fieldsInfo(fieldsInfo),
320
_classFile(classFile),
321
_fields(classFile->fields),
322
_index(0)
323
{
324
}
325
326
U_16 getNameIndex() const { return _fields[_index].nameIndex; }
327
U_16 getDescriptorIndex() const { return _fields[_index].descriptorIndex; }
328
U_8 getFirstByteOfDescriptor() const { return _classFile->constantPool[getDescriptorIndex()].bytes[0]; }
329
U_16 getAccessFlags() const { return _fields[_index].accessFlags; }
330
U_16 getFieldIndex() const {return _index; }
331
332
bool isConstant() const { return (getAccessFlags() & CFR_ACC_STATIC) && (NULL != _fields[_index].constantValueAttribute); }
333
bool isConstantInteger() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Integer; }
334
bool isConstantDouble() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Double; }
335
bool isConstantFloat() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Float; }
336
bool isConstantLong() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Long; }
337
bool isConstantString() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_String; }
338
339
bool isSynthetic() const { return _fieldsInfo[_index].isSynthetic; }
340
bool hasGenericSignature() const { return _fieldsInfo[_index].hasGenericSignature; }
341
U_16 getGenericSignatureIndex() const { return _fieldsInfo[_index].genericSignatureIndex; }
342
bool hasAnnotation() const { return _fieldsInfo[_index].annotationsAttribute != NULL;}
343
bool hasTypeAnnotation() const { return _fieldsInfo[_index].typeAnnotationsAttribute != NULL;}
344
bool isFieldContended() const { return _fieldsInfo[_index].isFieldContended; }
345
346
347
U_32 getConstantValueSlot1() const { return _classFile->constantPool[getConstantValueConstantPoolIndex()].slot1; }
348
U_32 getConstantValueSlot2() const { return _classFile->constantPool[getConstantValueConstantPoolIndex()].slot2; }
349
U_16 getConstantValueConstantPoolIndex() const { return _fields[_index].constantValueAttribute->constantValueIndex; }
350
351
bool isNotDone() const { return _index < _classFile->fieldsCount; }
352
void next() { _index++; }
353
354
private:
355
U_8 getConstantValueTag() const { return _classFile->constantPool[getConstantValueConstantPoolIndex()].tag; }
356
357
FieldInfo *_fieldsInfo;
358
J9CfrClassFile *_classFile;
359
J9CfrField *_fields;
360
U_16 _index;
361
};
362
363
class LocalVariablesIterator
364
{
365
public:
366
LocalVariablesIterator(U_16 count, LocalVariableInfo *localVariablesInfo) :
367
_localVariableTableIndex(0),
368
_index(0),
369
_count(count),
370
_localVariablesInfo(localVariablesInfo),
371
_localVariableTable(NULL) // TODO why do we need this?
372
{
373
findNextValidEntry();
374
}
375
376
U_16 getNameIndex() const { return _localVariableTable[_localVariableTableIndex].nameIndex; }
377
U_16 getDescriptorIndex() const { return _localVariableTable[_localVariableTableIndex].descriptorIndex; }
378
U_16 getGenericSignatureIndex();
379
U_16 getIndex() const { return _index; } /* Equivalent to _localVariableTable[_localVariableTableIndex].index */
380
U_32 getStartPC() const { return _localVariableTable[_localVariableTableIndex].startPC; }
381
U_32 getLength() const { return _localVariableTable[_localVariableTableIndex].length; }
382
383
bool hasGenericSignature();
384
385
bool isNotDone() const { return _index < _count; }
386
void next()
387
{
388
++_localVariableTableIndex;
389
findNextValidEntry();
390
}
391
392
private:
393
void findNextValidEntry()
394
{
395
/*
396
* _localVariableTable is a cached pointer to _localVariablesInfo[_index].localVariableTableAttribute->localVariableTable.
397
* The LocalVariableInfo array is indexed by the "local variable index" (a.k.a. slot number).
398
* An entry is valid if:
399
* - there is a localVariableTable for the current slot (_index) and
400
* - the entry's index matches the current slot number (_index)
401
* The algorithm below checks if the current entry is valid; if not, the cached pointer is cleared and the search begins.
402
* When a valid entry is found, the pointer to the corresponding localVariableTable is cached to allow easy access from the
403
* getter methods above.
404
*/
405
if ((NULL == _localVariableTable) /* Is the cached pointer invalid? */
406
|| (_localVariableTableIndex >= _localVariablesInfo[_index].localVariableTableAttribute->localVariableTableLength) /* Have we walked off the end of the current localVariableTable? */
407
|| (_index != _localVariableTable[_localVariableTableIndex].index)) { /* Is the _index different from the current entry's index? */
408
_localVariableTable = NULL;
409
while ((NULL == _localVariableTable) && isNotDone()) { /* Keep looking until a valid entry is found or we run out of entries */
410
if ((NULL == _localVariablesInfo[_index].localVariableTableAttribute)
411
|| (_localVariableTableIndex >= _localVariablesInfo[_index].localVariableTableAttribute->localVariableTableLength)) {
412
/* If there is no localVariableTable or we've exhausted the entries for the current slot, advance to the next slot */
413
++_index;
414
_localVariableTableIndex = 0;
415
} else if (_index != _localVariablesInfo[_index].localVariableTableAttribute->localVariableTable[_localVariableTableIndex].index) {
416
/* If the current entry doesn't match the slot number, advance to the next entry */
417
++_localVariableTableIndex;
418
} else {
419
/* A valid entry has been found. Cache the localVariableTable pointer and exit the loop. */
420
_localVariableTable = _localVariablesInfo[_index].localVariableTableAttribute->localVariableTable;
421
}
422
}
423
}
424
}
425
426
U_16 _localVariableTableIndex;
427
U_16 _index;
428
U_16 _count;
429
LocalVariableInfo *_localVariablesInfo;
430
J9CfrLocalVariableTableEntry *_localVariableTable;
431
};
432
433
class MethodIterator
434
{
435
public:
436
MethodIterator(MethodInfo *methodsInfo, J9CfrClassFile *classFile) :
437
_methodIndex(0),
438
_methodsInfo(methodsInfo),
439
_classFile(classFile)
440
{
441
}
442
443
bool isEmpty() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccEmptyMethod); }
444
bool isForwarder() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccForwarderMethod); }
445
bool isGetter() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccGetterMethod); }
446
bool isVirtual() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodVTable); }
447
bool isSynthetic() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccSynthetic); }
448
449
bool isStatic() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_STATIC); }
450
bool isAbstract() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_ABSTRACT); }
451
bool isNative() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_NATIVE); }
452
bool isPrivate() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_PRIVATE); }
453
454
bool isByteCodeFixupDone() const { return _methodsInfo[_methodIndex].isByteCodeFixupDone; }
455
void setByteCodeFixupDone() { _methodsInfo[_methodIndex].isByteCodeFixupDone = true; }
456
457
bool hasStackMap() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasStackMap); }
458
bool hasBackwardBranches() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasBackwardBranches); }
459
bool hasGenericSignature() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasGenericSignature); }
460
bool hasFrameIteratorSkipAnnotation() const { return _methodsInfo[_methodIndex].hasFrameIteratorSkipAnnotation; }
461
bool hasAnnotationsData() const { return NULL != _methodsInfo[_methodIndex].annotationsAttribute; }
462
bool hasParameterAnnotations() const { return NULL != _methodsInfo[_methodIndex].parameterAnnotationsAttribute; }
463
bool hasMethodTypeAnnotations() const { return NULL != _methodsInfo[_methodIndex].methodTypeAnnotationsAttribute; }
464
bool hasCodeTypeAnnotations() const { return NULL != _methodsInfo[_methodIndex].codeTypeAnnotationsAttribute; }
465
bool hasDefaultAnnotation() const { return NULL != _methodsInfo[_methodIndex].defaultAnnotationAttribute; }
466
bool hasMethodParameters() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasMethodParameters); }
467
468
U_8 getMethodParametersCount() const { return (NULL == _classFile->methods[_methodIndex].methodParametersAttribute) ? 0 : _classFile->methods[_methodIndex].methodParametersAttribute->numberOfMethodParameters; }
469
U_32 getModifiers() const { return _methodsInfo[_methodIndex].modifiers; }
470
U_32 getExtendedModifiers() const { return _methodsInfo[_methodIndex].extendedModifiers; }
471
U_16 getAccessFlags() const { return _classFile->methods[_methodIndex].accessFlags; }
472
U_8 getSendSlotCount() const { return _methodsInfo[_methodIndex].sendSlotCount; }
473
U_16 getMaxLocals() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->maxLocals; }
474
U_16 getNameIndex() const { return _classFile->methods[_methodIndex].nameIndex; }
475
U_16 getDescriptorIndex() const { return _classFile->methods[_methodIndex].descriptorIndex; }
476
U_16 getIndex() const { return _methodIndex; }
477
U_16 getMaxStack() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->maxStack; }
478
U_16 getStackMapFramesCount() const { return _methodsInfo[_methodIndex].stackMapFramesCount; }
479
U_16 getExceptionHandlersCount() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->exceptionTableLength; }
480
U_16 getExceptionsThrownCount() const { return _methodsInfo[_methodIndex].exceptionsThrownCount; }
481
U_16 getGenericSignatureIndex() const { return _methodsInfo[_methodIndex].genericSignatureIndex; }
482
U_8 *getCode() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->code; }
483
U_32 getCodeLength() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->codeLength; }
484
U_32 getLineNumbersCount() const { return _methodsInfo[_methodIndex].lineNumbersCount; }
485
U_32 getLineNumbersInfoCompressedSize() const { return _methodsInfo[_methodIndex].lineNumbersInfoCompressedSize; }
486
U_8 *getLineNumbersInfoCompressed() const { return _methodsInfo[_methodIndex].lineNumbersInfoCompressed; }
487
U_32 getLocalVariablesCount() const { return _methodsInfo[_methodIndex].localVariablesCount; }
488
489
U_32 getByteCodeFixupCount() const { return _methodsInfo[_methodIndex].byteCodeFixupCount; }
490
ClassFileOracle::BytecodeFixupEntry * getByteCodeFixupTable() const { return _methodsInfo[_methodIndex].byteCodeFixupTable; }
491
492
void exceptionsThrownDo(ConstantPoolIndexVisitor *visitor)
493
{ // TODO refactor MethodInfo and MethodIterator to make this usable by ClassFileOracle::walkMethodThrownExceptions
494
J9CfrAttributeExceptions *exceptions = _classFile->methods[_methodIndex].exceptionsAttribute;
495
if (NULL != exceptions) {
496
U_16 *end = exceptions->exceptionIndexTable + exceptions->numberOfExceptions;
497
for (U_16 *exceptionIndex = exceptions->exceptionIndexTable; exceptionIndex != end; ++exceptionIndex) {
498
if (0 != *exceptionIndex) {
499
/* Each exception is a constantClass, use slot1 to get at the underlying UTF8 */
500
visitor->visitConstantPoolIndex(U_16(_classFile->constantPool[ *exceptionIndex ].slot1));
501
}
502
}
503
}
504
}
505
506
void exceptionHandlersDo(ExceptionHandlerVisitor *visitor)
507
{
508
if (NULL != _classFile->methods[_methodIndex].codeAttribute) {
509
J9CfrExceptionTableEntry* end = _classFile->methods[_methodIndex].codeAttribute->exceptionTable + getExceptionHandlersCount();
510
for (J9CfrExceptionTableEntry* entry = _classFile->methods[_methodIndex].codeAttribute->exceptionTable; entry != end; ++entry) {
511
visitor->visitExceptionHandler(entry->startPC, entry->endPC, entry->handlerPC, entry->catchType);
512
}
513
}
514
}
515
516
void methodParametersDo(MethodParametersVisitor *visitor)
517
{
518
J9CfrAttributeMethodParameters *methodParams = _classFile->methods[_methodIndex].methodParametersAttribute;
519
if (NULL != methodParams) {
520
U_8 methodParamsCount = methodParams->numberOfMethodParameters;
521
U_16 * methodParametersIndexTable = methodParams->methodParametersIndexTable;
522
for (int i = 0; i < methodParamsCount; i++) {
523
visitor->visitMethodParameters(methodParametersIndexTable[i], methodParams->flags[i]);
524
}
525
}
526
}
527
528
void stackMapFramesDo(StackMapFrameVisitor *visitor)
529
{
530
StackMapFrameInfo *end = _methodsInfo[_methodIndex].stackMapFramesInfo + _methodsInfo[_methodIndex].stackMapFramesCount;
531
for (StackMapFrameInfo *info = _methodsInfo[_methodIndex].stackMapFramesInfo; info != end; ++info) {
532
VerificationTypeInfo typeInfo(info, _classFile);
533
visitor->visitStackMapFrame(info->localsCount, info->stackItemsCount, info->offsetDelta, info->frameType, &typeInfo);
534
}
535
}
536
537
LocalVariablesIterator getLocalVariablesIterator() { return LocalVariablesIterator((NULL == _methodsInfo[_methodIndex].localVariablesInfo) ? 0 : getMaxLocals(), _methodsInfo[_methodIndex].localVariablesInfo); }
538
539
bool isNotDone() const { return _methodIndex < _classFile->methodsCount; }
540
void next() { _methodIndex++; }
541
542
private:
543
544
U_16 _methodIndex;
545
MethodInfo *_methodsInfo;
546
J9CfrClassFile *_classFile;
547
};
548
549
class UTF8Iterator
550
{
551
public:
552
UTF8Iterator(J9CfrClassFile *classFile) :
553
_classFile(classFile),
554
_cpIndex(classFile->firstUTF8CPIndex),
555
_entry(&classFile->constantPool[_cpIndex])
556
{
557
}
558
559
U_16 getCPIndex() const { return _cpIndex; }
560
U_16 getUTF8Length() const { return U_16(_entry->slot1); }
561
U_8 *getUTF8Data() const { return _entry->bytes; }
562
563
bool isNotDone() const { return 0 != _cpIndex; }
564
void next()
565
{
566
_cpIndex = _entry->nextCPIndex;
567
_entry = &_classFile->constantPool[_cpIndex];
568
}
569
570
private:
571
J9CfrClassFile *_classFile;
572
U_16 _cpIndex;
573
J9CfrConstantPoolInfo *_entry;
574
};
575
576
class NameAndTypeIterator
577
{
578
public:
579
NameAndTypeIterator(J9CfrClassFile *classFile) :
580
_classFile(classFile),
581
_cpIndex(classFile->firstNATCPIndex),
582
_entry(&classFile->constantPool[_cpIndex])
583
{
584
}
585
586
U_16 getCPIndex() const { return _cpIndex; }
587
U_16 getNameIndex() const { return U_16(_entry->slot1); }
588
U_16 getDescriptorIndex() const { return U_16(_entry->slot2); }
589
590
bool isNotDone() const { return 0 != _cpIndex; }
591
void next()
592
{
593
_cpIndex = _entry->nextCPIndex;
594
_entry = &_classFile->constantPool[_cpIndex];
595
}
596
597
private:
598
J9CfrClassFile *_classFile;
599
U_16 _cpIndex;
600
J9CfrConstantPoolInfo *_entry;
601
};
602
603
class RecordComponentIterator
604
{
605
public:
606
RecordComponentIterator(RecordComponentInfo *recordComponentsInfo, U_16 recordComponentCount) :
607
_recordComponentsInfo(recordComponentsInfo),
608
_recordComponentCount(recordComponentCount),
609
_index(0)
610
{
611
}
612
613
U_16 getNameIndex() const { return _recordComponentsInfo[_index].nameIndex; }
614
U_16 getDescriptorIndex() const { return _recordComponentsInfo[_index].descriptorIndex; }
615
U_16 getGenericSignatureIndex() const { return _recordComponentsInfo[_index].genericSignatureIndex; }
616
U_16 getRecordComponentIndex() const { return _index; }
617
618
bool hasGenericSignature() const { return _recordComponentsInfo[_index].hasGenericSignature; }
619
bool hasAnnotation() const { return _recordComponentsInfo[_index].annotationsAttribute != NULL; }
620
bool hasTypeAnnotation() const { return _recordComponentsInfo[_index].typeAnnotationsAttribute != NULL; }
621
622
bool isNotDone() const { return _index < _recordComponentCount; }
623
void next() { _index++; }
624
625
private:
626
RecordComponentInfo *_recordComponentsInfo;
627
U_16 _recordComponentCount;
628
U_16 _index;
629
};
630
631
/*
632
* Iteration functions.
633
*/
634
635
void annotationElementDo(AnnotationElementVisitor *annotationElementVisitor, U_16 elementNameIndex, J9CfrAnnotationElement *annotationElement)
636
{
637
switch (annotationElement->tag) {
638
case 'e':
639
annotationElementVisitor->visitEnum(elementNameIndex,
640
((J9CfrAnnotationElementEnum *)annotationElement)->typeNameIndex,
641
((J9CfrAnnotationElementEnum *)annotationElement)->constNameIndex);
642
break;
643
case 'c':
644
annotationElementVisitor->visitClass(elementNameIndex,
645
((J9CfrAnnotationElementClass *)annotationElement)->classInfoIndex);
646
break;
647
case '@': {
648
NestedAnnotation nestedAnnotation(this, &(((J9CfrAnnotationElementAnnotation *)annotationElement)->annotationValue));
649
annotationElementVisitor->visitNestedAnnotation(elementNameIndex,
650
&nestedAnnotation);
651
break;
652
}
653
case '[': {
654
ArrayAnnotationElements arrayAnnotationElements(this, (J9CfrAnnotationElementArray *)annotationElement);
655
annotationElementVisitor->visitArray(elementNameIndex,
656
((J9CfrAnnotationElementArray *)annotationElement)->numberOfValues,
657
&arrayAnnotationElements);
658
break;
659
}
660
default:
661
annotationElementVisitor->visitConstant(elementNameIndex, ((J9CfrAnnotationElementPrimitive *)annotationElement)->constValueIndex, annotationElement->tag);
662
break;
663
}
664
}
665
666
void annotationElementsDo(AnnotationElementVisitor *annotationElementVisitor, J9CfrAnnotationElementPair *elementValuePairs, U_16 elementValuePairCount)
667
{
668
J9CfrAnnotationElementPair *endElementValuePairs = elementValuePairs + elementValuePairCount;
669
for (J9CfrAnnotationElementPair *elementValuePair = elementValuePairs; elementValuePair != endElementValuePairs; ++elementValuePair) {
670
annotationElementDo(annotationElementVisitor, elementValuePair->elementNameIndex, elementValuePair->value);
671
}
672
}
673
674
void defaultAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationElementVisitor *annotationElementVisitor)
675
{
676
if (NULL != _methodsInfo[methodIndex].defaultAnnotationAttribute) {
677
if (NULL != annotationsAttributeVisitor) {
678
annotationsAttributeVisitor->visitDefaultAnnotationAttribute(methodIndex, _methodsInfo[methodIndex].defaultAnnotationAttribute->length);
679
}
680
if (NULL != annotationElementVisitor) {
681
annotationElementDo(annotationElementVisitor, _classFile->methods[methodIndex].nameIndex, _methodsInfo[methodIndex].defaultAnnotationAttribute->defaultValue);
682
}
683
}
684
}
685
686
VMINLINE void
687
annotationsDo(U_16 index, J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
688
{
689
if (NULL != annotationsAttribute) {
690
if ((annotationsAttribute->rawDataLength > 0) && (NULL != annotationsAttributeVisitor)) { /* Detected bad attribute: this will fail when reparsed by Java code. */
691
annotationsAttributeVisitor->visitMalformedAnnotationsAttribute(annotationsAttribute->rawDataLength, annotationsAttribute->rawAttributeData);
692
} else {
693
if (NULL != annotationsAttributeVisitor) {
694
annotationsAttributeVisitor->visitAnnotationsAttribute(index, annotationsAttribute->length, annotationsAttribute->numberOfAnnotations);
695
}
696
if ((NULL != annotationVisitor) || (NULL != annotationElementVisitor)) {
697
J9CfrAnnotation *endAnnotations = annotationsAttribute->annotations + annotationsAttribute->numberOfAnnotations;
698
for (J9CfrAnnotation *annotation = annotationsAttribute->annotations; annotation != endAnnotations; ++annotation) {
699
if (NULL != annotationVisitor) {
700
annotationVisitor->visitAnnotation(annotation->typeIndex, annotation->numberOfElementValuePairs);
701
}
702
if (NULL != annotationElementVisitor) {
703
annotationElementsDo(annotationElementVisitor, annotation->elementValuePairs, annotation->numberOfElementValuePairs);
704
}
705
}
706
}
707
}
708
}
709
}
710
void classAnnotationsDo(AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
711
{
712
annotationsDo(0, _annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
713
}
714
715
void classTypeAnnotationsDo(AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
716
{
717
typeAnnotationsDo(0, _typeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
718
}
719
720
void fieldAnnotationDo(U_16 fieldIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
721
{
722
annotationsDo(fieldIndex, _fieldsInfo[fieldIndex].annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
723
}
724
725
void fieldTypeAnnotationDo(U_16 fieldIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
726
{
727
typeAnnotationsDo(fieldIndex, _fieldsInfo[fieldIndex].typeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
728
}
729
730
void methodAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
731
{
732
annotationsDo(methodIndex, _methodsInfo[methodIndex].annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
733
}
734
735
void methodTypeAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
736
{
737
typeAnnotationsDo(methodIndex, _methodsInfo[methodIndex].methodTypeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
738
}
739
740
void methodCodeTypeAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
741
{
742
typeAnnotationsDo(methodIndex, _methodsInfo[methodIndex].codeTypeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
743
}
744
745
void recordComponentAnnotationDo(U_16 recordComponentIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor) {
746
annotationsDo(recordComponentIndex, _recordComponentsInfo[recordComponentIndex].annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
747
}
748
749
void recordComponentTypeAnnotationDo(U_16 recordComponentIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor) {
750
typeAnnotationsDo(recordComponentIndex, _recordComponentsInfo[recordComponentIndex].typeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);
751
}
752
753
void parameterAnnotationsDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
754
{
755
J9CfrAttributeRuntimeVisibleParameterAnnotations *parameterAnnotationsAttribute = _methodsInfo[methodIndex].parameterAnnotationsAttribute;
756
if (NULL != parameterAnnotationsAttribute) {
757
if (parameterAnnotationsAttribute->rawDataLength > 0) { /* Detected bad attribute: this will fail when reparsed by Java code. */
758
annotationsAttributeVisitor->visitMalformedAnnotationsAttribute(parameterAnnotationsAttribute->rawDataLength,
759
parameterAnnotationsAttribute->rawAttributeData);
760
} else {
761
if (NULL != annotationsAttributeVisitor) {
762
annotationsAttributeVisitor->visitParameterAnnotationsAttribute(methodIndex, parameterAnnotationsAttribute->length, parameterAnnotationsAttribute->numberOfParameters);
763
}
764
U_8 parameterIndex = 0;
765
J9CfrParameterAnnotations *endParameterAnnotations = parameterAnnotationsAttribute->parameterAnnotations + parameterAnnotationsAttribute->numberOfParameters;
766
for (J9CfrParameterAnnotations *parameterAnnotations = parameterAnnotationsAttribute->parameterAnnotations; parameterAnnotations != endParameterAnnotations; ++parameterAnnotations, ++parameterIndex) {
767
if (NULL != annotationVisitor) {
768
annotationVisitor->visitParameter(parameterAnnotations->numberOfAnnotations);
769
}
770
if ((NULL != annotationVisitor) || (NULL != annotationElementVisitor)) {
771
J9CfrAnnotation *endAnnotations = parameterAnnotations->annotations + parameterAnnotations->numberOfAnnotations;
772
for (J9CfrAnnotation *annotation = parameterAnnotations->annotations; annotation != endAnnotations; ++annotation) {
773
if (NULL != annotationVisitor) {
774
annotationVisitor->visitAnnotation(annotation->typeIndex, annotation->numberOfElementValuePairs);
775
}
776
if (NULL != annotationElementVisitor) {
777
annotationElementsDo(annotationElementVisitor, annotation->elementValuePairs, annotation->numberOfElementValuePairs);
778
}
779
}
780
}
781
}
782
}
783
}
784
}
785
786
void typeAnnotationsDo(U_16 index, J9CfrAttributeRuntimeVisibleTypeAnnotations *typeAnnotationsAttribute,
787
AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)
788
{
789
Trc_BCU_Assert_NotNull(typeAnnotationsAttribute);
790
if (typeAnnotationsAttribute->rawDataLength > 0) { /* Detected bad attribute: this will fail when reparsed by Java code. */
791
annotationsAttributeVisitor->visitMalformedAnnotationsAttribute(typeAnnotationsAttribute->rawDataLength,
792
typeAnnotationsAttribute->rawAttributeData);
793
} else {
794
if (NULL != annotationsAttributeVisitor) {
795
annotationsAttributeVisitor->visitTypeAnnotationsAttribute(index, typeAnnotationsAttribute->length, typeAnnotationsAttribute->numberOfAnnotations);
796
}
797
if ((NULL != annotationVisitor) || (NULL != annotationElementVisitor)) {
798
for (U_16 typeAnnotationIndex = 0; typeAnnotationIndex < typeAnnotationsAttribute->numberOfAnnotations; ++typeAnnotationIndex) {
799
J9CfrTypeAnnotation *typeAnnotation = &(typeAnnotationsAttribute->typeAnnotations[typeAnnotationIndex]);
800
if (NULL != annotationVisitor) {
801
annotationVisitor->visitTypeAnnotation(typeAnnotation->targetType, &(typeAnnotation->targetInfo), &(typeAnnotation->typePath));
802
annotationVisitor->visitAnnotation(typeAnnotation->annotation.typeIndex, typeAnnotation->annotation.numberOfElementValuePairs);
803
}
804
if (NULL != annotationElementVisitor) {
805
annotationElementsDo(annotationElementVisitor, typeAnnotation->annotation.elementValuePairs, typeAnnotation->annotation.numberOfElementValuePairs);
806
}
807
808
}
809
}
810
}
811
}
812
813
/*
814
* Iterate over the constant pool indices corresponding to interface names (UTF8s).
815
* Also iterates over the injected interface names (UTF8s) in the "extra" cp slots.
816
* numOfInjectedInterfaces represents the number of extra slots containing the UTF8s.
817
*/
818
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
819
void interfacesDo(ConstantPoolIndexVisitor *visitor, U_16 numOfInjectedInterfaces)
820
#else /* J9VM_OPT_VALHALLA_VALUE_TYPES */
821
void interfacesDo(ConstantPoolIndexVisitor *visitor)
822
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
823
{
824
U_16 *end = _classFile->interfaces + getInterfacesCount();
825
for (U_16 *interface = _classFile->interfaces; interface != end; ++interface) {
826
/* Each interface is a constantClass, use slot1 to get at the underlying UTF8 */
827
visitor->visitConstantPoolIndex(U_16(_classFile->constantPool[ *interface ].slot1));
828
}
829
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
830
for (int i = 0; i < numOfInjectedInterfaces; i++) {
831
visitor->visitConstantPoolIndex(getConstantPoolCount() + i);
832
}
833
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
834
}
835
836
/*
837
* Iterate over the constant pool indices corresponding to inner class names (UTF8s).
838
*/
839
void innerClassesDo(ConstantPoolIndexVisitor *visitor)
840
{
841
if (NULL != _innerClasses) {
842
J9CfrClassesEntry *end = _innerClasses->classes + _innerClasses->numberOfClasses;
843
U_16 thisClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, _classFile->thisClass);
844
for (J9CfrClassesEntry *entry = _innerClasses->classes; entry != end; ++entry) {
845
U_16 outerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->outerClassInfoIndex);
846
/* In some cases, there might be two entries for the same class.
847
* But the UTF8 classname entry will be only one.
848
* Therefore comparing the UTF8 will find the matches, while comparing the class entries will not
849
*/
850
if (thisClassUTF8 == outerClassUTF8) {
851
/* Member class - use slot1 to get at the underlying UTF8. */
852
U_16 innerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->innerClassInfoIndex);
853
visitor->visitConstantPoolIndex(innerClassUTF8);
854
}
855
}
856
}
857
}
858
859
/*
860
* Iterate over the constant pool indices corresponding to enclosed inner class names (UTF8s).
861
*/
862
void enclosedInnerClassesDo(ConstantPoolIndexVisitor *visitor)
863
{
864
if (NULL != _innerClasses) {
865
J9CfrClassesEntry *end = _innerClasses->classes + _innerClasses->numberOfClasses;
866
U_16 thisClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, _classFile->thisClass);
867
for (J9CfrClassesEntry *entry = _innerClasses->classes; entry != end; ++entry) {
868
U_16 outerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->outerClassInfoIndex);
869
U_16 innerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->innerClassInfoIndex);
870
/* Count all remaining entries in the InnerClass attribute (except the entries covered by innerClassesDo())
871
* so as to check the InnerClass attribute between the inner classes and the enclosing class.
872
* See getDeclaringClass() for details.
873
*/
874
if ((thisClassUTF8 != outerClassUTF8) && (thisClassUTF8 != innerClassUTF8)) {
875
visitor->visitConstantPoolIndex(innerClassUTF8);
876
}
877
}
878
}
879
}
880
881
#if JAVA_SPEC_VERSION >= 11
882
void nestMembersDo(ConstantPoolIndexVisitor *visitor)
883
{
884
if (NULL != _nestMembers) {
885
U_16 nestMembersCount = getNestMembersCount();
886
for (U_16 i = 0; i < nestMembersCount; i++) {
887
U_16 nestMemberUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, _nestMembers->classes[i]);
888
visitor->visitConstantPoolIndex(nestMemberUTF8);
889
}
890
}
891
}
892
#endif /* JAVA_SPEC_VERSION >= 11 */
893
894
/*
895
* Iterate over the bootstrap methods and their arguments.
896
*/
897
void bootstrapMethodsDo(BootstrapMethodVisitor *visitor)
898
{
899
if (NULL != _bootstrapMethodsAttribute) {
900
J9CfrBootstrapMethod *end = _bootstrapMethodsAttribute->bootstrapMethods + _bootstrapMethodsAttribute->numberOfBootstrapMethods;
901
for (J9CfrBootstrapMethod *bsm = _bootstrapMethodsAttribute->bootstrapMethods; bsm != end; ++bsm) {
902
U_16 *endArguments = bsm->bootstrapArguments + bsm->numberOfBootstrapArguments;
903
visitor->visitBootstrapMethod(bsm->bootstrapMethodIndex, bsm->numberOfBootstrapArguments);
904
for (U_16 *argument = bsm->bootstrapArguments; argument != endArguments; ++argument) {
905
visitor->visitBootstrapArgument(*argument);
906
}
907
}
908
}
909
}
910
911
UTF8Iterator getUTF8Iterator() const { return UTF8Iterator(_classFile); }
912
NameAndTypeIterator getNameAndTypeIterator() const { return NameAndTypeIterator(_classFile); }
913
FieldIterator getFieldIterator() { return FieldIterator(_fieldsInfo, _classFile); }
914
MethodIterator getMethodIterator() { return MethodIterator(_methodsInfo, _classFile); }
915
RecordComponentIterator getRecordComponentIterator() { return RecordComponentIterator(_recordComponentsInfo, _recordComponentCount); }
916
917
ClassFileOracle(BufferManager *bufferManager, J9CfrClassFile *classFile, ConstantPoolMap *constantPoolMap, U_8 * verifyExcludeAttribute, U_8 * romBuilderClassFileBuffer, ROMClassCreationContext *context);
918
~ClassFileOracle();
919
920
bool isOK() const { return OK == _buildResult; }
921
BuildResult getBuildResult() const { return _buildResult; }
922
923
/*
924
* Query methods.
925
*/
926
927
U_32 getClassFileSize() const { return _classFile->classFileSize; }
928
U_16 getAccessFlags() const { return _classFile->accessFlags; }
929
U_16 getSingleScalarStaticCount() const { return _singleScalarStaticCount; }
930
U_16 getInterfacesCount() const { return _classFile->interfacesCount; }
931
U_16 getMethodsCount() const { return _classFile->methodsCount; }
932
U_16 getFieldsCount() const { return _classFile->fieldsCount; }
933
U_16 getConstantPoolCount() const { return _classFile->constantPoolCount; }
934
U_16 getObjectStaticCount() const { return _objectStaticCount; }
935
U_16 getDoubleScalarStaticCount() const { return _doubleScalarStaticCount; }
936
U_16 getMemberAccessFlags() const { return _memberAccessFlags; }
937
U_16 getInnerClassCount() const { return _innerClassCount; }
938
U_16 getEnclosedInnerClassCount() const { return _enclosedInnerClassCount; }
939
#if JAVA_SPEC_VERSION >= 11
940
U_16 getNestMembersCount() const { return _nestMembersCount; }
941
U_16 getNestHostNameIndex() const { return _nestHost; }
942
#endif /* JAVA_SPEC_VERSION >= 11 */
943
U_16 getMajorVersion() const { return _classFile->majorVersion; }
944
U_16 getMinorVersion() const { return _classFile->minorVersion; }
945
U_32 getMaxBranchCount() const { return _maxBranchCount; }
946
U_16 getClassNameIndex() const { return U_16(_classFile->constantPool[_classFile->thisClass].slot1); }
947
U_16 getSuperClassNameIndex() const { return U_16(_classFile->constantPool[_classFile->superClass].slot1); }
948
U_16 getOuterClassNameIndex() const { return _outerClassNameIndex; }
949
U_16 getSimpleNameIndex() const { return _simpleNameIndex; }
950
U_16 getEnclosingMethodClassRefIndex() const { return hasEnclosingMethod() ? _enclosingMethod->classIndex : 0; }
951
U_16 getEnclosingMethodNameAndSignatureIndex() const { return hasEnclosingMethod() ? _enclosingMethod->methodIndex : 0; }
952
U_16 getGenericSignatureIndex() const { return hasGenericSignature() ? _genericSignature->signatureIndex : 0; }
953
U_16 getUTF8Length(U_16 cpIndex) const { return U_16(_classFile->constantPool[cpIndex].slot1); }
954
U_8 *getUTF8Data(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].bytes; }
955
U_16 getNameAndSignatureNameUTF8Length(U_16 cpIndex) const { return getUTF8Length(U_16(_classFile->constantPool[cpIndex].slot1)); }
956
U_8 *getNameAndSignatureNameUTF8Data(U_16 cpIndex) const { return getUTF8Data(U_16(_classFile->constantPool[cpIndex].slot1)); }
957
U_16 getNameAndSignatureSignatureUTF8Length(U_16 cpIndex) const { return getUTF8Length(U_16(_classFile->constantPool[cpIndex].slot2)); }
958
U_8 *getNameAndSignatureSignatureUTF8Data(U_16 cpIndex) const { return getUTF8Data(U_16(_classFile->constantPool[cpIndex].slot2)); }
959
U_16 getSourceFileIndex() const { return hasSourceFile() ? _sourceFile->sourceFileIndex : 0; }
960
U_32 getSourceDebugExtensionLength() const { return hasSourceDebugExtension() ? _sourceDebugExtension->length : 0; }
961
U_8 *getSourceDebugExtensionData() const { return hasSourceDebugExtension() ? _sourceDebugExtension->value : NULL; }
962
U_16 getBootstrapMethodCount() const { return hasBootstrapMethods() ? _bootstrapMethodsAttribute->numberOfBootstrapMethods : 0; }
963
964
bool hasClassAnnotations() const { return NULL != _annotationsAttribute; }
965
bool hasTypeAnnotations() const { return NULL != _typeAnnotationsAttribute; }
966
U_16 getFieldNameIndex(U_16 fieldIndex) const { return _classFile->fields[fieldIndex].nameIndex; }
967
U_16 getFieldDescriptorIndex(U_16 fieldIndex) const { return _classFile->fields[fieldIndex].descriptorIndex; }
968
U_16 getMethodNameIndex(U_16 methodIndex) const { return _classFile->methods[methodIndex].nameIndex; }
969
void sortLineNumberTable(U_16 methodIndex, J9CfrLineNumberTableEntry *lineNumbersInfo);
970
U_16 getMethodDescriptorIndex(U_16 methodIndex) const { return _classFile->methods[methodIndex].descriptorIndex; }
971
void getPrimitiveConstant(U_16 cpIndex, U_32 *slot1, U_32 *slot2) const
972
{
973
*slot1 = _classFile->constantPool[cpIndex].slot1;
974
*slot2 = _classFile->constantPool[cpIndex].slot2;
975
}
976
977
U_8 getCPTag(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].tag; }
978
U_32 getCPSlot1(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].slot1; }
979
U_32 getCPSlot2(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].slot2; }
980
981
/*
982
* Long and Double CP entries are never tagged as "referenced" because they are only reached through LDC2W instructions,
983
* so don't check the ".referenced" flag in isConstantLong() or isConstantDouble().
984
*/
985
bool isConstantLong(U_16 cpIndex) const { return CFR_CONSTANT_Long == _classFile->constantPool[cpIndex].tag; }
986
bool isConstantDouble(U_16 cpIndex) const { return CFR_CONSTANT_Double == _classFile->constantPool[cpIndex].tag; }
987
bool isConstantDynamic(U_16 cpIndex) const { return CFR_CONSTANT_Dynamic == _classFile->constantPool[cpIndex].tag;}
988
bool isConstantInteger0(U_16 cpIndex) const { return (CFR_CONSTANT_Integer == _classFile->constantPool[cpIndex].tag) && (0 == _classFile->constantPool[cpIndex].slot1); }
989
bool isConstantFloat0(U_16 cpIndex) const { return (CFR_CONSTANT_Float == _classFile->constantPool[cpIndex].tag) && (0 == _classFile->constantPool[cpIndex].slot1); }
990
bool isUTF8AtIndexEqualToString(U_16 cpIndex, const char *string, UDATA stringSize) { return (getUTF8Length(cpIndex) == (stringSize - 1)) && (0 == memcmp(getUTF8Data(cpIndex), string, stringSize - 1)); }
991
bool hasEmptyFinalizeMethod() const { return _hasEmptyFinalizeMethod; }
992
bool hasFinalFields() const { return _hasFinalFields; }
993
bool isClassContended() const { return _isClassContended; }
994
bool isClassUnmodifiable() const { return _isClassUnmodifiable; }
995
bool hasNonStaticNonAbstractMethods() const { return _hasNonStaticNonAbstractMethods; }
996
bool hasFinalizeMethod() const { return _hasFinalizeMethod; }
997
bool isCloneable() const { return _isCloneable; }
998
bool isSerializable() const { return _isSerializable; }
999
bool isSynthetic() const { return _isSynthetic; }
1000
bool hasEnclosingMethod() const { return NULL != _enclosingMethod; }
1001
bool hasGenericSignature() const { return NULL != _genericSignature; }
1002
bool hasSimpleName() const { return 0 != getSimpleNameIndex(); }
1003
bool hasVerifyExcludeAttribute() const { return _hasVerifyExcludeAttribute; }
1004
bool hasSourceFile() const { return NULL != _sourceFile; }
1005
bool hasSourceDebugExtension() const { return NULL != _sourceDebugExtension; }
1006
bool hasBootstrapMethods() const { return NULL != _bootstrapMethodsAttribute; }
1007
bool hasClinit() const { return _hasClinit; }
1008
bool annotationRefersDoubleSlotEntry() const { return _annotationRefersDoubleSlotEntry; }
1009
bool isInnerClass() const { return _isInnerClass; }
1010
bool needsStaticConstantInit() const { return _needsStaticConstantInit; }
1011
bool isRecord() const { return _isRecord; }
1012
U_16 getRecordComponentCount() const { return _recordComponentCount; }
1013
bool isSealed() const { return _isSealed; }
1014
U_16 getPermittedSubclassesClassCount() const { return _isSealed ? _permittedSubclassesAttribute->numberOfClasses : 0; }
1015
bool isValueBased() const { return _isClassValueBased; }
1016
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1017
bool needsIdentityInterface() const { return _isIdentityInterfaceNeeded; }
1018
bool hasIdentityInterface() const { return _hasIdentityInterface; }
1019
bool isValueType() const { return _isValueType; }
1020
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
1021
1022
U_16 getPermittedSubclassesClassNameAtIndex(U_16 index) const {
1023
U_16 result = 0;
1024
if (_isSealed) {
1025
U_16 classCpIndex = _permittedSubclassesAttribute->classes[index];
1026
result = _classFile->constantPool[classCpIndex].slot1;
1027
}
1028
return result;
1029
}
1030
1031
1032
U_8 constantDynamicType(U_16 cpIndex) const
1033
{
1034
J9CfrConstantPoolInfo* nas = &_classFile->constantPool[_classFile->constantPool[cpIndex].slot2];
1035
J9CfrConstantPoolInfo* signature = &_classFile->constantPool[nas->slot2];
1036
U_8 result = 0;
1037
1038
if ('D' == signature->bytes[0]) {
1039
result = JBldc2dw;
1040
} else if ('J' == signature->bytes[0]) {
1041
result = JBldc2lw;
1042
} else {
1043
Trc_BCU_Assert_ShouldNeverHappen();
1044
}
1045
1046
return result;
1047
}
1048
1049
private:
1050
class InterfaceVisitor;
1051
1052
enum {
1053
FRAMEITERATORSKIP_ANNOTATION,
1054
SUN_REFLECT_CALLERSENSITIVE_ANNOTATION,
1055
JDK_INTERNAL_REFLECT_CALLERSENSITIVE_ANNOTATION,
1056
#if JAVA_SPEC_VERSION >= 18
1057
JDK_INTERNAL_REFLECT_CALLERSENSITIVEADAPTER_ANNOTATION,
1058
#endif /* JAVA_SPEC_VERSION >= 18*/
1059
JAVA8_CONTENDED_ANNOTATION,
1060
CONTENDED_ANNOTATION,
1061
UNMODIFIABLE_ANNOTATION,
1062
VALUEBASED_ANNOTATION,
1063
#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)
1064
HIDDEN_ANNOTATION,
1065
#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */
1066
#if JAVA_SPEC_VERSION >= 16
1067
SCOPED_ANNOTATION,
1068
#endif /* JAVA_SPEC_VERSION >= 16*/
1069
KNOWN_ANNOTATION_COUNT
1070
};
1071
1072
struct KnownAnnotation
1073
{
1074
const char *name;
1075
size_t size;
1076
};
1077
1078
static KnownAnnotation _knownAnnotations[];
1079
BuildResult _buildResult;
1080
BufferManager *_bufferManager;
1081
J9CfrClassFile *_classFile;
1082
ConstantPoolMap *_constantPoolMap;
1083
U_8 *_verifyExcludeAttribute;
1084
U_8 *_romBuilderClassFileBuffer;
1085
UDATA _bctFlags;
1086
ROMClassCreationContext *_context;
1087
1088
U_16 _singleScalarStaticCount;
1089
U_16 _objectStaticCount;
1090
U_16 _doubleScalarStaticCount;
1091
U_16 _memberAccessFlags;
1092
U_16 _innerClassCount;
1093
U_16 _enclosedInnerClassCount;
1094
#if JAVA_SPEC_VERSION >= 11
1095
U_16 _nestMembersCount;
1096
U_16 _nestHost;
1097
#endif /* JAVA_SPEC_VERSION >= 11 */
1098
U_32 _maxBranchCount;
1099
U_16 _outerClassNameIndex;
1100
U_16 _simpleNameIndex;
1101
U_16 _recordComponentCount;
1102
1103
bool _hasEmptyFinalizeMethod;
1104
bool _hasFinalFields;
1105
bool _hasNonStaticNonAbstractMethods;
1106
bool _hasFinalizeMethod;
1107
bool _isCloneable;
1108
bool _isSerializable;
1109
bool _isSynthetic;
1110
bool _isClassContended;
1111
bool _isClassUnmodifiable;
1112
bool _hasVerifyExcludeAttribute;
1113
bool _hasFrameIteratorSkipAnnotation;
1114
bool _hasClinit;
1115
bool _annotationRefersDoubleSlotEntry;
1116
bool _isInnerClass;
1117
bool _needsStaticConstantInit;
1118
bool _isRecord;
1119
bool _isSealed;
1120
bool _isClassValueBased;
1121
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1122
bool _hasIdentityInterface;
1123
bool _isIdentityInterfaceNeeded;
1124
bool _isValueType;
1125
bool _hasNonStaticSynchronizedMethod;
1126
bool _hasNonStaticFields;
1127
bool _hasNonEmptyConstructor;
1128
#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */
1129
1130
FieldInfo *_fieldsInfo;
1131
MethodInfo *_methodsInfo;
1132
RecordComponentInfo *_recordComponentsInfo;
1133
1134
J9CfrAttributeSignature *_genericSignature;
1135
J9CfrAttributeEnclosingMethod *_enclosingMethod;
1136
J9CfrAttributeSourceFile *_sourceFile;
1137
J9CfrAttributeUnknown *_sourceDebugExtension;
1138
J9CfrAttributeRuntimeVisibleAnnotations *_annotationsAttribute;
1139
J9CfrAttributeRuntimeVisibleTypeAnnotations *_typeAnnotationsAttribute;
1140
J9CfrAttributeInnerClasses *_innerClasses;
1141
J9CfrAttributeBootstrapMethods *_bootstrapMethodsAttribute;
1142
J9CfrAttributePermittedSubclasses *_permittedSubclassesAttribute;
1143
#if JAVA_SPEC_VERSION >= 11
1144
J9CfrAttributeNestMembers *_nestMembers;
1145
#endif /* JAVA_SPEC_VERSION >= 11 */
1146
1147
void walkHeader();
1148
void walkFields();
1149
void walkAttributes();
1150
void checkHiddenClass();
1151
void walkInterfaces();
1152
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1153
void checkAndRecordIsIdentityInterfaceNeeded();
1154
#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */
1155
void walkMethods();
1156
void walkRecordComponents(J9CfrAttributeRecord *attrib);
1157
1158
UDATA walkAnnotations(U_16 annotationsCount, J9CfrAnnotation *annotations, UDATA knownAnnotationSet);
1159
void walkTypeAnnotations(U_16 annotationsCount, J9CfrTypeAnnotation *annotations);
1160
void walkAnnotationElement(J9CfrAnnotationElement * annotationElement);
1161
1162
void computeSendSlotCount(U_16 methodIndex);
1163
1164
void walkMethodAttributes(U_16 methodIndex);
1165
void walkMethodThrownExceptions(U_16 methodIndex);
1166
void walkMethodCodeAttribute(U_16 methodIndex);
1167
void throwGenericErrorWithCustomMsg(UDATA code, UDATA offset);
1168
void walkMethodCodeAttributeAttributes(U_16 methodIndex);
1169
void walkMethodCodeAttributeCaughtExceptions(U_16 methodIndex);
1170
void walkMethodCodeAttributeCode(U_16 methodIndex);
1171
void walkMethodMethodParametersAttribute(U_16 methodIndex);
1172
1173
U_8 * walkStackMapSlots(U_8 *framePointer, U_16 typeInfoCount);
1174
1175
bool methodIsFinalize(U_16 methodIndex, bool isForwarder);
1176
bool methodIsEmpty(U_16 methodIndex);
1177
bool methodIsForwarder(U_16 methodIndex);
1178
bool methodIsGetter(U_16 methodIndex);
1179
bool methodIsVirtual(U_16 methodIndex);
1180
bool methodIsObjectConstructor(U_16 methodIndex);
1181
bool methodIsClinit(U_16 methodIndex);
1182
bool methodIsNonStaticNonAbstract(U_16 methodIndex);
1183
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1184
bool methodIsConstructor(U_16 methodIndex);
1185
bool methodIsNonStaticSynchronized(U_16 methodIndex);
1186
#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */
1187
1188
bool shouldConvertInvokeVirtualToInvokeSpecialForMethodRef(U_16 methodRefCPIndex);
1189
UDATA shouldConvertInvokeVirtualToMethodHandleBytecodeForMethodRef(U_16 methodRefCPIndex);
1190
1191
VMINLINE bool containsKnownAnnotation(UDATA knownAnnotationSet, UDATA knownAnnotation);
1192
VMINLINE UDATA addAnnotationBit(UDATA annotationBits, UDATA knownAnnotation);
1193
1194
VMINLINE void addBytecodeFixupEntry(BytecodeFixupEntry *entry, U_32 codeIndex, U_16 cpIndex, U_8 type);
1195
1196
VMINLINE void markClassAsReferenced(U_16 classCPIndex);
1197
VMINLINE void markClassNameAsReferenced(U_16 classCPIndex);
1198
VMINLINE void markStringAsReferenced(U_16 cpIndex);
1199
VMINLINE void markNameAndDescriptorAsReferenced(U_16 nasCPIndex);
1200
VMINLINE void markFieldRefAsReferenced(U_16 cpIndex);
1201
VMINLINE void markMethodRefAsReferenced(U_16 cpIndex);
1202
VMINLINE void markMethodTypeAsReferenced(U_16 cpIndex);
1203
VMINLINE void markMethodHandleAsReferenced(U_16 cpIndex);
1204
VMINLINE void markMethodRefForMHInvocationAsReferenced(U_16 cpIndex);
1205
1206
VMINLINE void markConstantAsReferenced(U_16 cpIndex);
1207
VMINLINE void markConstantDynamicAsReferenced(U_16 cpIndex);
1208
VMINLINE void markConstantNameAndTypeAsReferenced(U_16 cpIndex);
1209
VMINLINE void markConstantUTF8AsReferenced(U_16 cpIndex);
1210
1211
VMINLINE void markConstantAsUsedByAnnotation(U_16 cpIndex);
1212
VMINLINE void markConstantAsUsedByLDC(U_8 cpIndex);
1213
VMINLINE void markConstantAsUsedByLDC2W(U_16 cpIndex);
1214
1215
VMINLINE void markClassAsUsedByInstanceOf(U_16 classCPIndex);
1216
VMINLINE void markClassAsUsedByCheckCast(U_16 classCPIndex);
1217
VMINLINE void markClassAsUsedByMultiANewArray(U_16 classCPIndex);
1218
VMINLINE void markClassAsUsedByANewArray(U_16 classCPIndex);
1219
VMINLINE void markClassAsUsedByNew(U_16 classCPIndex);
1220
1221
#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)
1222
VMINLINE void markClassAsUsedByAconst_init(U_16 classCPIndex);
1223
VMINLINE void markFieldRefAsUsedByWithField(U_16 fieldRefCPIndex);
1224
#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */
1225
1226
VMINLINE void markInvokeDynamicInfoAsUsedByInvokeDynamic(U_16 cpIndex);
1227
1228
VMINLINE void markFieldRefAsUsedByGetStatic(U_16 fieldRefCPIndex);
1229
VMINLINE void markFieldRefAsUsedByPutStatic(U_16 fieldRefCPIndex);
1230
VMINLINE void markFieldRefAsUsedByGetField(U_16 fieldRefCPIndex);
1231
VMINLINE void markFieldRefAsUsedByPutField(U_16 fieldRefCPIndex);
1232
1233
VMINLINE void markMethodRefAsUsedByInvokeVirtual(U_16 methodRefCPIndex);
1234
VMINLINE void markMethodRefAsUsedByInvokeSpecial(U_16 methodRefCPIndex);
1235
VMINLINE void markMethodRefAsUsedByInvokeStatic(U_16 methodRefCPIndex);
1236
VMINLINE void markMethodRefAsUsedByInvokeInterface(U_16 methodRefCPIndex);
1237
VMINLINE void markMethodRefAsUsedByInvokeHandle(U_16 methodRefCPIndex);
1238
VMINLINE void markMethodRefAsUsedByInvokeHandleGeneric(U_16 methodRefCPIndex);
1239
VMINLINE void markConstantBasedOnCpType(U_16 cpIndex, bool assertNotDoubleOrLong);
1240
1241
1242
static int compareLineNumbers(const void *left, const void *right);
1243
void compressLineNumberTable(U_16 methodIndex, U_32 lineNumbersCount);
1244
void sortAndCompressLineNumberTable(U_16 methodIndex, U_32 lineNumbersCount, U_8 *lineNumbersInfoCompressedInitial);
1245
};
1246
1247
#endif /* CLASSFILEORACLE_HPP_ */
1248
1249