Path: blob/master/runtime/bcutil/ClassFileOracle.hpp
5985 views
/*******************************************************************************1* Copyright (c) 2001, 2022 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122/*23* ClassFileOracle.hpp24*/2526#ifndef CLASSFILEORACLE_HPP_27#define CLASSFILEORACLE_HPP_2829/* @ddr_namespace: default */30#include "j9comp.h"31#include "cfr.h"32#include "cfreader.h"33#include "ut_j9bcu.h"34#include "bcnames.h"3536#include "BuildResult.hpp"37#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)38#include "VMHelpers.hpp"39#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */4041/*42* It is not guaranteed that slot1 value for constantpool index=0 entry will be zero.43* Therefore check the index first, if it is zero, return zero instead of returning the value in slot1.44*45* */46#define UTF8_INDEX_FROM_CLASS_INDEX(cp, cpIndex) ((U_16)((cpIndex == 0)? 0 : cp[cpIndex].slot1))4748class BufferManager;49class ConstantPoolMap;50class ROMClassCreationContext;5152class ClassFileOracle53{54public:55class VerificationTypeInfo;56class ArrayAnnotationElements;57class NestedAnnotation;5859struct FieldInfo60{61bool isSynthetic;62bool hasGenericSignature;63U_16 genericSignatureIndex;64J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute;65J9CfrAttributeRuntimeVisibleTypeAnnotations *typeAnnotationsAttribute;66bool isFieldContended;67};6869struct StackMapFrameInfo70{71U_8 frameType;72U_16 offsetDelta;73U_16 localsCount;74U_16 stackItemsCount;75U_8 *localsTypeInfo;76U_8 *stackItemsTypeInfo;77};7879struct LocalVariableInfo80{81J9CfrAttributeLocalVariableTable *localVariableTableAttribute;82J9CfrAttributeLocalVariableTypeTable *localVariableTypeTableAttribute;83};8485struct BytecodeFixupEntry86{87U_8 type; /* One of ConstantPoolMap::EntryUseFlags constants. */88U_16 cpIndex;89U_32 codeIndex;90};9192struct MethodInfo93{94bool hasFrameIteratorSkipAnnotation;95U_32 modifiers;96U_32 extendedModifiers;97U_8 sendSlotCount;98U_16 exceptionsThrownCount;99U_16 genericSignatureIndex;100U_16 stackMapFramesCount;101U_32 lineNumbersCount;102U_32 lineNumbersInfoCompressedSize;103U_32 localVariablesCount;104StackMapFrameInfo *stackMapFramesInfo;105LocalVariableInfo *localVariablesInfo;106U_8 *lineNumbersInfoCompressed;107J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute;108J9CfrAttributeRuntimeVisibleParameterAnnotations *parameterAnnotationsAttribute;109J9CfrAttributeRuntimeVisibleTypeAnnotations *methodTypeAnnotationsAttribute;110J9CfrAttributeRuntimeVisibleTypeAnnotations *codeTypeAnnotationsAttribute;111J9CfrAttributeAnnotationDefault *defaultAnnotationAttribute;112U_32 byteCodeFixupCount;113J9CfrAttributeMethodParameters *methodParametersAttribute;114BytecodeFixupEntry *byteCodeFixupTable;115bool isByteCodeFixupDone;116};117118struct RecordComponentInfo119{120bool hasGenericSignature;121U_16 nameIndex;122U_16 descriptorIndex;123U_16 genericSignatureIndex;124J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute;125J9CfrAttributeRuntimeVisibleTypeAnnotations *typeAnnotationsAttribute;126};127128/*129* Interfaces.130*/131132struct ConstantPoolIndexVisitor133{134virtual void visitConstantPoolIndex(U_16 cpIndex) = 0;135};136137struct ExceptionHandlerVisitor138{139virtual void visitExceptionHandler(U_32 startPC, U_32 endPC, U_32 handlerPC, U_16 exceptionClassCPIndex) = 0;140};141142struct MethodParametersVisitor143{144virtual void visitMethodParameters(U_16 cpIndex, U_16 flag) = 0;145};146147148struct VerificationTypeInfoVisitor149{150virtual void visitStackMapObject(U_8 slotType, U_16 classCPIndex, U_16 classNameCPIndex) = 0;151virtual void visitStackMapNewObject(U_8 slotType, U_16 offset) = 0;152virtual void visitStackMapItem(U_8 slotType) = 0;153};154155struct StackMapFrameVisitor156{157virtual void visitStackMapFrame(U_16 localsCount, U_16 stackItemsCount, U_16 offsetDelta, U_8 frameType, VerificationTypeInfo *typeInfo) = 0;158};159160struct AnnotationElementVisitor161{162virtual void visitConstant(U_16 elementNameIndex, U_16 cpIndex, U_8 elementType) {}163virtual void visitEnum(U_16 elementNameIndex, U_16 typeNameIndex, U_16 constNameIndex) {}164virtual void visitClass(U_16 elementNameIndex, U_16 cpIndex) {}165virtual void visitArray(U_16 elementNameIndex, U_16 elementCount, ArrayAnnotationElements *arrayAnnotationElements) {}166virtual void visitNestedAnnotation(U_16 elementNameIndex, NestedAnnotation *nestedAnnotation) {}167};168169struct AnnotationVisitor170{171virtual void visitParameter(U_16 numberOfAnnotations) = 0;172virtual void visitAnnotation(U_16 typeIndex, U_16 elementValuePairCount) = 0;173virtual void visitTypeAnnotation(U_8 targetType, J9CfrTypeAnnotationTargetInfo *targetInfo, J9CfrTypePath *typePath) = 0;174};175176struct AnnotationsAttributeVisitor177{178virtual void visitAnnotationsAttribute(U_16 fieldOrMethodIndex, U_32 length, U_16 numberOfAnnotations) = 0;179virtual void visitDefaultAnnotationAttribute(U_16 fieldOrMethodIndex, U_32 length) = 0;180virtual void visitParameterAnnotationsAttribute(U_16 fieldOrMethodIndex, U_32 length, U_8 numberOfParameters) = 0;181virtual void visitTypeAnnotationsAttribute(U_16 fieldOrMethodIndex, U_32 length, U_16 numberOfAnnotations) = 0;182virtual void visitMalformedAnnotationsAttribute(U_32 rawDataLength, U_8 *rawAttributeData) = 0;183};184185struct BootstrapMethodVisitor186{187virtual void visitBootstrapMethod(U_16 cpIndex, U_16 argumentCount) = 0;188virtual void visitBootstrapArgument(U_16 cpIndex) = 0;189};190191/*192* Iteration artifacts.193*/194195class VerificationTypeInfo196{197public:198VerificationTypeInfo(StackMapFrameInfo *stackMapFrameInfo, J9CfrClassFile *classFile) :199_stackMapFrameInfo(stackMapFrameInfo),200_classFile(classFile)201{202}203204void localsDo(VerificationTypeInfoVisitor *visitor) { slotsDo(_stackMapFrameInfo->localsCount, _stackMapFrameInfo->localsTypeInfo, visitor); }205void stackItemsDo(VerificationTypeInfoVisitor *visitor) { slotsDo(_stackMapFrameInfo->stackItemsCount, _stackMapFrameInfo->stackItemsTypeInfo, visitor); }206207private:208U_16 getParameter(U_8 *bytes) const { return (U_16(bytes[1]) << 8) | U_16(bytes[2]); }209void slotsDo(U_16 count, U_8 *bytes, VerificationTypeInfoVisitor *visitor)210{211for (U_16 i = 0; i < count; ++i) {212U_8 slotType = bytes[0];213switch (slotType) {214case CFR_STACKMAP_TYPE_OBJECT: {215U_16 cpIndex = getParameter(bytes);216U_16 nameIndex = (U_16) _classFile->constantPool[cpIndex].slot1;217visitor->visitStackMapObject(slotType, cpIndex, nameIndex);218bytes += 3;219break;220}221case CFR_STACKMAP_TYPE_NEW_OBJECT:222visitor->visitStackMapNewObject(slotType, getParameter(bytes));223bytes += 3;224break;225default:226visitor->visitStackMapItem(slotType);227bytes += 1;228break;229}230}231}232233StackMapFrameInfo *_stackMapFrameInfo;234J9CfrClassFile *_classFile;235};236237class ArrayAnnotationElements238{239public:240ArrayAnnotationElements(ClassFileOracle *classFileOracle, J9CfrAnnotationElementArray *annotationElementArray) :241_classFileOracle(classFileOracle),242_annotationElementArray(annotationElementArray)243{244}245246void elementsDo(AnnotationElementVisitor *annotationElementVisitor)247{248J9CfrAnnotationElement **endAnnotationElements = _annotationElementArray->values + _annotationElementArray->numberOfValues;249for (J9CfrAnnotationElement **annotationElement = _annotationElementArray->values; annotationElement != endAnnotationElements; ++annotationElement) {250_classFileOracle->annotationElementDo(annotationElementVisitor, 0, *annotationElement);251}252}253254private:255ClassFileOracle *_classFileOracle;256J9CfrAnnotationElementArray *_annotationElementArray;257};258259class NestedAnnotation260{261public:262NestedAnnotation(ClassFileOracle *classFileOracle, J9CfrAnnotation *annotation) :263_classFileOracle(classFileOracle),264_annotation(annotation)265{266}267268void annotationDo(AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor, AnnotationElementVisitor *annotationAnnotationVisitor)269{270if (NULL != annotationVisitor) {271annotationVisitor->visitAnnotation(_annotation->typeIndex, _annotation->numberOfElementValuePairs);272}273if (NULL != annotationElementVisitor) {274_classFileOracle->annotationElementsDo(annotationElementVisitor, _annotation->elementValuePairs, _annotation->numberOfElementValuePairs);275}276if (NULL != annotationAnnotationVisitor) {277_classFileOracle->annotationElementsDo(annotationAnnotationVisitor, _annotation->elementValuePairs, _annotation->numberOfElementValuePairs);278}279}280281private:282ClassFileOracle *_classFileOracle;283J9CfrAnnotation *_annotation;284};285286class AnnotationAnnotationVisitor : public AnnotationElementVisitor287{288public:289AnnotationAnnotationVisitor(AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor) :290_annotationVisitor(annotationVisitor),291_annotationElementVisitor(annotationElementVisitor)292{293}294295void visitArray(U_16 elementNameIndex, U_16 elementCount, ArrayAnnotationElements *arrayAnnotationElements)296{297arrayAnnotationElements->elementsDo(this);298}299300void visitNestedAnnotation(U_16 elementNameIndex, NestedAnnotation *nestedAnnotation)301{302nestedAnnotation->annotationDo(_annotationVisitor, _annotationElementVisitor, this);303}304305private:306AnnotationVisitor *_annotationVisitor;307AnnotationElementVisitor *_annotationElementVisitor;308};309310/*311* Iterators.312*/313314class FieldIterator315{316public:317FieldIterator(FieldInfo *fieldsInfo, J9CfrClassFile *classFile) :318_fieldsInfo(fieldsInfo),319_classFile(classFile),320_fields(classFile->fields),321_index(0)322{323}324325U_16 getNameIndex() const { return _fields[_index].nameIndex; }326U_16 getDescriptorIndex() const { return _fields[_index].descriptorIndex; }327U_8 getFirstByteOfDescriptor() const { return _classFile->constantPool[getDescriptorIndex()].bytes[0]; }328U_16 getAccessFlags() const { return _fields[_index].accessFlags; }329U_16 getFieldIndex() const {return _index; }330331bool isConstant() const { return (getAccessFlags() & CFR_ACC_STATIC) && (NULL != _fields[_index].constantValueAttribute); }332bool isConstantInteger() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Integer; }333bool isConstantDouble() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Double; }334bool isConstantFloat() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Float; }335bool isConstantLong() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_Long; }336bool isConstantString() const { return isConstant() && getConstantValueTag() == CFR_CONSTANT_String; }337338bool isSynthetic() const { return _fieldsInfo[_index].isSynthetic; }339bool hasGenericSignature() const { return _fieldsInfo[_index].hasGenericSignature; }340U_16 getGenericSignatureIndex() const { return _fieldsInfo[_index].genericSignatureIndex; }341bool hasAnnotation() const { return _fieldsInfo[_index].annotationsAttribute != NULL;}342bool hasTypeAnnotation() const { return _fieldsInfo[_index].typeAnnotationsAttribute != NULL;}343bool isFieldContended() const { return _fieldsInfo[_index].isFieldContended; }344345346U_32 getConstantValueSlot1() const { return _classFile->constantPool[getConstantValueConstantPoolIndex()].slot1; }347U_32 getConstantValueSlot2() const { return _classFile->constantPool[getConstantValueConstantPoolIndex()].slot2; }348U_16 getConstantValueConstantPoolIndex() const { return _fields[_index].constantValueAttribute->constantValueIndex; }349350bool isNotDone() const { return _index < _classFile->fieldsCount; }351void next() { _index++; }352353private:354U_8 getConstantValueTag() const { return _classFile->constantPool[getConstantValueConstantPoolIndex()].tag; }355356FieldInfo *_fieldsInfo;357J9CfrClassFile *_classFile;358J9CfrField *_fields;359U_16 _index;360};361362class LocalVariablesIterator363{364public:365LocalVariablesIterator(U_16 count, LocalVariableInfo *localVariablesInfo) :366_localVariableTableIndex(0),367_index(0),368_count(count),369_localVariablesInfo(localVariablesInfo),370_localVariableTable(NULL) // TODO why do we need this?371{372findNextValidEntry();373}374375U_16 getNameIndex() const { return _localVariableTable[_localVariableTableIndex].nameIndex; }376U_16 getDescriptorIndex() const { return _localVariableTable[_localVariableTableIndex].descriptorIndex; }377U_16 getGenericSignatureIndex();378U_16 getIndex() const { return _index; } /* Equivalent to _localVariableTable[_localVariableTableIndex].index */379U_32 getStartPC() const { return _localVariableTable[_localVariableTableIndex].startPC; }380U_32 getLength() const { return _localVariableTable[_localVariableTableIndex].length; }381382bool hasGenericSignature();383384bool isNotDone() const { return _index < _count; }385void next()386{387++_localVariableTableIndex;388findNextValidEntry();389}390391private:392void findNextValidEntry()393{394/*395* _localVariableTable is a cached pointer to _localVariablesInfo[_index].localVariableTableAttribute->localVariableTable.396* The LocalVariableInfo array is indexed by the "local variable index" (a.k.a. slot number).397* An entry is valid if:398* - there is a localVariableTable for the current slot (_index) and399* - the entry's index matches the current slot number (_index)400* The algorithm below checks if the current entry is valid; if not, the cached pointer is cleared and the search begins.401* When a valid entry is found, the pointer to the corresponding localVariableTable is cached to allow easy access from the402* getter methods above.403*/404if ((NULL == _localVariableTable) /* Is the cached pointer invalid? */405|| (_localVariableTableIndex >= _localVariablesInfo[_index].localVariableTableAttribute->localVariableTableLength) /* Have we walked off the end of the current localVariableTable? */406|| (_index != _localVariableTable[_localVariableTableIndex].index)) { /* Is the _index different from the current entry's index? */407_localVariableTable = NULL;408while ((NULL == _localVariableTable) && isNotDone()) { /* Keep looking until a valid entry is found or we run out of entries */409if ((NULL == _localVariablesInfo[_index].localVariableTableAttribute)410|| (_localVariableTableIndex >= _localVariablesInfo[_index].localVariableTableAttribute->localVariableTableLength)) {411/* If there is no localVariableTable or we've exhausted the entries for the current slot, advance to the next slot */412++_index;413_localVariableTableIndex = 0;414} else if (_index != _localVariablesInfo[_index].localVariableTableAttribute->localVariableTable[_localVariableTableIndex].index) {415/* If the current entry doesn't match the slot number, advance to the next entry */416++_localVariableTableIndex;417} else {418/* A valid entry has been found. Cache the localVariableTable pointer and exit the loop. */419_localVariableTable = _localVariablesInfo[_index].localVariableTableAttribute->localVariableTable;420}421}422}423}424425U_16 _localVariableTableIndex;426U_16 _index;427U_16 _count;428LocalVariableInfo *_localVariablesInfo;429J9CfrLocalVariableTableEntry *_localVariableTable;430};431432class MethodIterator433{434public:435MethodIterator(MethodInfo *methodsInfo, J9CfrClassFile *classFile) :436_methodIndex(0),437_methodsInfo(methodsInfo),438_classFile(classFile)439{440}441442bool isEmpty() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccEmptyMethod); }443bool isForwarder() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccForwarderMethod); }444bool isGetter() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccGetterMethod); }445bool isVirtual() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodVTable); }446bool isSynthetic() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccSynthetic); }447448bool isStatic() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_STATIC); }449bool isAbstract() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_ABSTRACT); }450bool isNative() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_NATIVE); }451bool isPrivate() const { return 0 != (_classFile->methods[_methodIndex].accessFlags & CFR_ACC_PRIVATE); }452453bool isByteCodeFixupDone() const { return _methodsInfo[_methodIndex].isByteCodeFixupDone; }454void setByteCodeFixupDone() { _methodsInfo[_methodIndex].isByteCodeFixupDone = true; }455456bool hasStackMap() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasStackMap); }457bool hasBackwardBranches() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasBackwardBranches); }458bool hasGenericSignature() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasGenericSignature); }459bool hasFrameIteratorSkipAnnotation() const { return _methodsInfo[_methodIndex].hasFrameIteratorSkipAnnotation; }460bool hasAnnotationsData() const { return NULL != _methodsInfo[_methodIndex].annotationsAttribute; }461bool hasParameterAnnotations() const { return NULL != _methodsInfo[_methodIndex].parameterAnnotationsAttribute; }462bool hasMethodTypeAnnotations() const { return NULL != _methodsInfo[_methodIndex].methodTypeAnnotationsAttribute; }463bool hasCodeTypeAnnotations() const { return NULL != _methodsInfo[_methodIndex].codeTypeAnnotationsAttribute; }464bool hasDefaultAnnotation() const { return NULL != _methodsInfo[_methodIndex].defaultAnnotationAttribute; }465bool hasMethodParameters() const { return 0 != (_methodsInfo[_methodIndex].modifiers & J9AccMethodHasMethodParameters); }466467U_8 getMethodParametersCount() const { return (NULL == _classFile->methods[_methodIndex].methodParametersAttribute) ? 0 : _classFile->methods[_methodIndex].methodParametersAttribute->numberOfMethodParameters; }468U_32 getModifiers() const { return _methodsInfo[_methodIndex].modifiers; }469U_32 getExtendedModifiers() const { return _methodsInfo[_methodIndex].extendedModifiers; }470U_16 getAccessFlags() const { return _classFile->methods[_methodIndex].accessFlags; }471U_8 getSendSlotCount() const { return _methodsInfo[_methodIndex].sendSlotCount; }472U_16 getMaxLocals() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->maxLocals; }473U_16 getNameIndex() const { return _classFile->methods[_methodIndex].nameIndex; }474U_16 getDescriptorIndex() const { return _classFile->methods[_methodIndex].descriptorIndex; }475U_16 getIndex() const { return _methodIndex; }476U_16 getMaxStack() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->maxStack; }477U_16 getStackMapFramesCount() const { return _methodsInfo[_methodIndex].stackMapFramesCount; }478U_16 getExceptionHandlersCount() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->exceptionTableLength; }479U_16 getExceptionsThrownCount() const { return _methodsInfo[_methodIndex].exceptionsThrownCount; }480U_16 getGenericSignatureIndex() const { return _methodsInfo[_methodIndex].genericSignatureIndex; }481U_8 *getCode() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->code; }482U_32 getCodeLength() const { return (NULL == _classFile->methods[_methodIndex].codeAttribute) ? 0 : _classFile->methods[_methodIndex].codeAttribute->codeLength; }483U_32 getLineNumbersCount() const { return _methodsInfo[_methodIndex].lineNumbersCount; }484U_32 getLineNumbersInfoCompressedSize() const { return _methodsInfo[_methodIndex].lineNumbersInfoCompressedSize; }485U_8 *getLineNumbersInfoCompressed() const { return _methodsInfo[_methodIndex].lineNumbersInfoCompressed; }486U_32 getLocalVariablesCount() const { return _methodsInfo[_methodIndex].localVariablesCount; }487488U_32 getByteCodeFixupCount() const { return _methodsInfo[_methodIndex].byteCodeFixupCount; }489ClassFileOracle::BytecodeFixupEntry * getByteCodeFixupTable() const { return _methodsInfo[_methodIndex].byteCodeFixupTable; }490491void exceptionsThrownDo(ConstantPoolIndexVisitor *visitor)492{ // TODO refactor MethodInfo and MethodIterator to make this usable by ClassFileOracle::walkMethodThrownExceptions493J9CfrAttributeExceptions *exceptions = _classFile->methods[_methodIndex].exceptionsAttribute;494if (NULL != exceptions) {495U_16 *end = exceptions->exceptionIndexTable + exceptions->numberOfExceptions;496for (U_16 *exceptionIndex = exceptions->exceptionIndexTable; exceptionIndex != end; ++exceptionIndex) {497if (0 != *exceptionIndex) {498/* Each exception is a constantClass, use slot1 to get at the underlying UTF8 */499visitor->visitConstantPoolIndex(U_16(_classFile->constantPool[ *exceptionIndex ].slot1));500}501}502}503}504505void exceptionHandlersDo(ExceptionHandlerVisitor *visitor)506{507if (NULL != _classFile->methods[_methodIndex].codeAttribute) {508J9CfrExceptionTableEntry* end = _classFile->methods[_methodIndex].codeAttribute->exceptionTable + getExceptionHandlersCount();509for (J9CfrExceptionTableEntry* entry = _classFile->methods[_methodIndex].codeAttribute->exceptionTable; entry != end; ++entry) {510visitor->visitExceptionHandler(entry->startPC, entry->endPC, entry->handlerPC, entry->catchType);511}512}513}514515void methodParametersDo(MethodParametersVisitor *visitor)516{517J9CfrAttributeMethodParameters *methodParams = _classFile->methods[_methodIndex].methodParametersAttribute;518if (NULL != methodParams) {519U_8 methodParamsCount = methodParams->numberOfMethodParameters;520U_16 * methodParametersIndexTable = methodParams->methodParametersIndexTable;521for (int i = 0; i < methodParamsCount; i++) {522visitor->visitMethodParameters(methodParametersIndexTable[i], methodParams->flags[i]);523}524}525}526527void stackMapFramesDo(StackMapFrameVisitor *visitor)528{529StackMapFrameInfo *end = _methodsInfo[_methodIndex].stackMapFramesInfo + _methodsInfo[_methodIndex].stackMapFramesCount;530for (StackMapFrameInfo *info = _methodsInfo[_methodIndex].stackMapFramesInfo; info != end; ++info) {531VerificationTypeInfo typeInfo(info, _classFile);532visitor->visitStackMapFrame(info->localsCount, info->stackItemsCount, info->offsetDelta, info->frameType, &typeInfo);533}534}535536LocalVariablesIterator getLocalVariablesIterator() { return LocalVariablesIterator((NULL == _methodsInfo[_methodIndex].localVariablesInfo) ? 0 : getMaxLocals(), _methodsInfo[_methodIndex].localVariablesInfo); }537538bool isNotDone() const { return _methodIndex < _classFile->methodsCount; }539void next() { _methodIndex++; }540541private:542543U_16 _methodIndex;544MethodInfo *_methodsInfo;545J9CfrClassFile *_classFile;546};547548class UTF8Iterator549{550public:551UTF8Iterator(J9CfrClassFile *classFile) :552_classFile(classFile),553_cpIndex(classFile->firstUTF8CPIndex),554_entry(&classFile->constantPool[_cpIndex])555{556}557558U_16 getCPIndex() const { return _cpIndex; }559U_16 getUTF8Length() const { return U_16(_entry->slot1); }560U_8 *getUTF8Data() const { return _entry->bytes; }561562bool isNotDone() const { return 0 != _cpIndex; }563void next()564{565_cpIndex = _entry->nextCPIndex;566_entry = &_classFile->constantPool[_cpIndex];567}568569private:570J9CfrClassFile *_classFile;571U_16 _cpIndex;572J9CfrConstantPoolInfo *_entry;573};574575class NameAndTypeIterator576{577public:578NameAndTypeIterator(J9CfrClassFile *classFile) :579_classFile(classFile),580_cpIndex(classFile->firstNATCPIndex),581_entry(&classFile->constantPool[_cpIndex])582{583}584585U_16 getCPIndex() const { return _cpIndex; }586U_16 getNameIndex() const { return U_16(_entry->slot1); }587U_16 getDescriptorIndex() const { return U_16(_entry->slot2); }588589bool isNotDone() const { return 0 != _cpIndex; }590void next()591{592_cpIndex = _entry->nextCPIndex;593_entry = &_classFile->constantPool[_cpIndex];594}595596private:597J9CfrClassFile *_classFile;598U_16 _cpIndex;599J9CfrConstantPoolInfo *_entry;600};601602class RecordComponentIterator603{604public:605RecordComponentIterator(RecordComponentInfo *recordComponentsInfo, U_16 recordComponentCount) :606_recordComponentsInfo(recordComponentsInfo),607_recordComponentCount(recordComponentCount),608_index(0)609{610}611612U_16 getNameIndex() const { return _recordComponentsInfo[_index].nameIndex; }613U_16 getDescriptorIndex() const { return _recordComponentsInfo[_index].descriptorIndex; }614U_16 getGenericSignatureIndex() const { return _recordComponentsInfo[_index].genericSignatureIndex; }615U_16 getRecordComponentIndex() const { return _index; }616617bool hasGenericSignature() const { return _recordComponentsInfo[_index].hasGenericSignature; }618bool hasAnnotation() const { return _recordComponentsInfo[_index].annotationsAttribute != NULL; }619bool hasTypeAnnotation() const { return _recordComponentsInfo[_index].typeAnnotationsAttribute != NULL; }620621bool isNotDone() const { return _index < _recordComponentCount; }622void next() { _index++; }623624private:625RecordComponentInfo *_recordComponentsInfo;626U_16 _recordComponentCount;627U_16 _index;628};629630/*631* Iteration functions.632*/633634void annotationElementDo(AnnotationElementVisitor *annotationElementVisitor, U_16 elementNameIndex, J9CfrAnnotationElement *annotationElement)635{636switch (annotationElement->tag) {637case 'e':638annotationElementVisitor->visitEnum(elementNameIndex,639((J9CfrAnnotationElementEnum *)annotationElement)->typeNameIndex,640((J9CfrAnnotationElementEnum *)annotationElement)->constNameIndex);641break;642case 'c':643annotationElementVisitor->visitClass(elementNameIndex,644((J9CfrAnnotationElementClass *)annotationElement)->classInfoIndex);645break;646case '@': {647NestedAnnotation nestedAnnotation(this, &(((J9CfrAnnotationElementAnnotation *)annotationElement)->annotationValue));648annotationElementVisitor->visitNestedAnnotation(elementNameIndex,649&nestedAnnotation);650break;651}652case '[': {653ArrayAnnotationElements arrayAnnotationElements(this, (J9CfrAnnotationElementArray *)annotationElement);654annotationElementVisitor->visitArray(elementNameIndex,655((J9CfrAnnotationElementArray *)annotationElement)->numberOfValues,656&arrayAnnotationElements);657break;658}659default:660annotationElementVisitor->visitConstant(elementNameIndex, ((J9CfrAnnotationElementPrimitive *)annotationElement)->constValueIndex, annotationElement->tag);661break;662}663}664665void annotationElementsDo(AnnotationElementVisitor *annotationElementVisitor, J9CfrAnnotationElementPair *elementValuePairs, U_16 elementValuePairCount)666{667J9CfrAnnotationElementPair *endElementValuePairs = elementValuePairs + elementValuePairCount;668for (J9CfrAnnotationElementPair *elementValuePair = elementValuePairs; elementValuePair != endElementValuePairs; ++elementValuePair) {669annotationElementDo(annotationElementVisitor, elementValuePair->elementNameIndex, elementValuePair->value);670}671}672673void defaultAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationElementVisitor *annotationElementVisitor)674{675if (NULL != _methodsInfo[methodIndex].defaultAnnotationAttribute) {676if (NULL != annotationsAttributeVisitor) {677annotationsAttributeVisitor->visitDefaultAnnotationAttribute(methodIndex, _methodsInfo[methodIndex].defaultAnnotationAttribute->length);678}679if (NULL != annotationElementVisitor) {680annotationElementDo(annotationElementVisitor, _classFile->methods[methodIndex].nameIndex, _methodsInfo[methodIndex].defaultAnnotationAttribute->defaultValue);681}682}683}684685VMINLINE void686annotationsDo(U_16 index, J9CfrAttributeRuntimeVisibleAnnotations *annotationsAttribute, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)687{688if (NULL != annotationsAttribute) {689if ((annotationsAttribute->rawDataLength > 0) && (NULL != annotationsAttributeVisitor)) { /* Detected bad attribute: this will fail when reparsed by Java code. */690annotationsAttributeVisitor->visitMalformedAnnotationsAttribute(annotationsAttribute->rawDataLength, annotationsAttribute->rawAttributeData);691} else {692if (NULL != annotationsAttributeVisitor) {693annotationsAttributeVisitor->visitAnnotationsAttribute(index, annotationsAttribute->length, annotationsAttribute->numberOfAnnotations);694}695if ((NULL != annotationVisitor) || (NULL != annotationElementVisitor)) {696J9CfrAnnotation *endAnnotations = annotationsAttribute->annotations + annotationsAttribute->numberOfAnnotations;697for (J9CfrAnnotation *annotation = annotationsAttribute->annotations; annotation != endAnnotations; ++annotation) {698if (NULL != annotationVisitor) {699annotationVisitor->visitAnnotation(annotation->typeIndex, annotation->numberOfElementValuePairs);700}701if (NULL != annotationElementVisitor) {702annotationElementsDo(annotationElementVisitor, annotation->elementValuePairs, annotation->numberOfElementValuePairs);703}704}705}706}707}708}709void classAnnotationsDo(AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)710{711annotationsDo(0, _annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);712}713714void classTypeAnnotationsDo(AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)715{716typeAnnotationsDo(0, _typeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);717}718719void fieldAnnotationDo(U_16 fieldIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)720{721annotationsDo(fieldIndex, _fieldsInfo[fieldIndex].annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);722}723724void fieldTypeAnnotationDo(U_16 fieldIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)725{726typeAnnotationsDo(fieldIndex, _fieldsInfo[fieldIndex].typeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);727}728729void methodAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)730{731annotationsDo(methodIndex, _methodsInfo[methodIndex].annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);732}733734void methodTypeAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)735{736typeAnnotationsDo(methodIndex, _methodsInfo[methodIndex].methodTypeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);737}738739void methodCodeTypeAnnotationDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)740{741typeAnnotationsDo(methodIndex, _methodsInfo[methodIndex].codeTypeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);742}743744void recordComponentAnnotationDo(U_16 recordComponentIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor) {745annotationsDo(recordComponentIndex, _recordComponentsInfo[recordComponentIndex].annotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);746}747748void recordComponentTypeAnnotationDo(U_16 recordComponentIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor) {749typeAnnotationsDo(recordComponentIndex, _recordComponentsInfo[recordComponentIndex].typeAnnotationsAttribute, annotationsAttributeVisitor, annotationVisitor, annotationElementVisitor);750}751752void parameterAnnotationsDo(U_16 methodIndex, AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)753{754J9CfrAttributeRuntimeVisibleParameterAnnotations *parameterAnnotationsAttribute = _methodsInfo[methodIndex].parameterAnnotationsAttribute;755if (NULL != parameterAnnotationsAttribute) {756if (parameterAnnotationsAttribute->rawDataLength > 0) { /* Detected bad attribute: this will fail when reparsed by Java code. */757annotationsAttributeVisitor->visitMalformedAnnotationsAttribute(parameterAnnotationsAttribute->rawDataLength,758parameterAnnotationsAttribute->rawAttributeData);759} else {760if (NULL != annotationsAttributeVisitor) {761annotationsAttributeVisitor->visitParameterAnnotationsAttribute(methodIndex, parameterAnnotationsAttribute->length, parameterAnnotationsAttribute->numberOfParameters);762}763U_8 parameterIndex = 0;764J9CfrParameterAnnotations *endParameterAnnotations = parameterAnnotationsAttribute->parameterAnnotations + parameterAnnotationsAttribute->numberOfParameters;765for (J9CfrParameterAnnotations *parameterAnnotations = parameterAnnotationsAttribute->parameterAnnotations; parameterAnnotations != endParameterAnnotations; ++parameterAnnotations, ++parameterIndex) {766if (NULL != annotationVisitor) {767annotationVisitor->visitParameter(parameterAnnotations->numberOfAnnotations);768}769if ((NULL != annotationVisitor) || (NULL != annotationElementVisitor)) {770J9CfrAnnotation *endAnnotations = parameterAnnotations->annotations + parameterAnnotations->numberOfAnnotations;771for (J9CfrAnnotation *annotation = parameterAnnotations->annotations; annotation != endAnnotations; ++annotation) {772if (NULL != annotationVisitor) {773annotationVisitor->visitAnnotation(annotation->typeIndex, annotation->numberOfElementValuePairs);774}775if (NULL != annotationElementVisitor) {776annotationElementsDo(annotationElementVisitor, annotation->elementValuePairs, annotation->numberOfElementValuePairs);777}778}779}780}781}782}783}784785void typeAnnotationsDo(U_16 index, J9CfrAttributeRuntimeVisibleTypeAnnotations *typeAnnotationsAttribute,786AnnotationsAttributeVisitor *annotationsAttributeVisitor, AnnotationVisitor *annotationVisitor, AnnotationElementVisitor *annotationElementVisitor)787{788Trc_BCU_Assert_NotNull(typeAnnotationsAttribute);789if (typeAnnotationsAttribute->rawDataLength > 0) { /* Detected bad attribute: this will fail when reparsed by Java code. */790annotationsAttributeVisitor->visitMalformedAnnotationsAttribute(typeAnnotationsAttribute->rawDataLength,791typeAnnotationsAttribute->rawAttributeData);792} else {793if (NULL != annotationsAttributeVisitor) {794annotationsAttributeVisitor->visitTypeAnnotationsAttribute(index, typeAnnotationsAttribute->length, typeAnnotationsAttribute->numberOfAnnotations);795}796if ((NULL != annotationVisitor) || (NULL != annotationElementVisitor)) {797for (U_16 typeAnnotationIndex = 0; typeAnnotationIndex < typeAnnotationsAttribute->numberOfAnnotations; ++typeAnnotationIndex) {798J9CfrTypeAnnotation *typeAnnotation = &(typeAnnotationsAttribute->typeAnnotations[typeAnnotationIndex]);799if (NULL != annotationVisitor) {800annotationVisitor->visitTypeAnnotation(typeAnnotation->targetType, &(typeAnnotation->targetInfo), &(typeAnnotation->typePath));801annotationVisitor->visitAnnotation(typeAnnotation->annotation.typeIndex, typeAnnotation->annotation.numberOfElementValuePairs);802}803if (NULL != annotationElementVisitor) {804annotationElementsDo(annotationElementVisitor, typeAnnotation->annotation.elementValuePairs, typeAnnotation->annotation.numberOfElementValuePairs);805}806807}808}809}810}811812/*813* Iterate over the constant pool indices corresponding to interface names (UTF8s).814* Also iterates over the injected interface names (UTF8s) in the "extra" cp slots.815* numOfInjectedInterfaces represents the number of extra slots containing the UTF8s.816*/817#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)818void interfacesDo(ConstantPoolIndexVisitor *visitor, U_16 numOfInjectedInterfaces)819#else /* J9VM_OPT_VALHALLA_VALUE_TYPES */820void interfacesDo(ConstantPoolIndexVisitor *visitor)821#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */822{823U_16 *end = _classFile->interfaces + getInterfacesCount();824for (U_16 *interface = _classFile->interfaces; interface != end; ++interface) {825/* Each interface is a constantClass, use slot1 to get at the underlying UTF8 */826visitor->visitConstantPoolIndex(U_16(_classFile->constantPool[ *interface ].slot1));827}828#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)829for (int i = 0; i < numOfInjectedInterfaces; i++) {830visitor->visitConstantPoolIndex(getConstantPoolCount() + i);831}832#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */833}834835/*836* Iterate over the constant pool indices corresponding to inner class names (UTF8s).837*/838void innerClassesDo(ConstantPoolIndexVisitor *visitor)839{840if (NULL != _innerClasses) {841J9CfrClassesEntry *end = _innerClasses->classes + _innerClasses->numberOfClasses;842U_16 thisClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, _classFile->thisClass);843for (J9CfrClassesEntry *entry = _innerClasses->classes; entry != end; ++entry) {844U_16 outerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->outerClassInfoIndex);845/* In some cases, there might be two entries for the same class.846* But the UTF8 classname entry will be only one.847* Therefore comparing the UTF8 will find the matches, while comparing the class entries will not848*/849if (thisClassUTF8 == outerClassUTF8) {850/* Member class - use slot1 to get at the underlying UTF8. */851U_16 innerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->innerClassInfoIndex);852visitor->visitConstantPoolIndex(innerClassUTF8);853}854}855}856}857858/*859* Iterate over the constant pool indices corresponding to enclosed inner class names (UTF8s).860*/861void enclosedInnerClassesDo(ConstantPoolIndexVisitor *visitor)862{863if (NULL != _innerClasses) {864J9CfrClassesEntry *end = _innerClasses->classes + _innerClasses->numberOfClasses;865U_16 thisClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, _classFile->thisClass);866for (J9CfrClassesEntry *entry = _innerClasses->classes; entry != end; ++entry) {867U_16 outerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->outerClassInfoIndex);868U_16 innerClassUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, entry->innerClassInfoIndex);869/* Count all remaining entries in the InnerClass attribute (except the entries covered by innerClassesDo())870* so as to check the InnerClass attribute between the inner classes and the enclosing class.871* See getDeclaringClass() for details.872*/873if ((thisClassUTF8 != outerClassUTF8) && (thisClassUTF8 != innerClassUTF8)) {874visitor->visitConstantPoolIndex(innerClassUTF8);875}876}877}878}879880#if JAVA_SPEC_VERSION >= 11881void nestMembersDo(ConstantPoolIndexVisitor *visitor)882{883if (NULL != _nestMembers) {884U_16 nestMembersCount = getNestMembersCount();885for (U_16 i = 0; i < nestMembersCount; i++) {886U_16 nestMemberUTF8 = UTF8_INDEX_FROM_CLASS_INDEX(_classFile->constantPool, _nestMembers->classes[i]);887visitor->visitConstantPoolIndex(nestMemberUTF8);888}889}890}891#endif /* JAVA_SPEC_VERSION >= 11 */892893/*894* Iterate over the bootstrap methods and their arguments.895*/896void bootstrapMethodsDo(BootstrapMethodVisitor *visitor)897{898if (NULL != _bootstrapMethodsAttribute) {899J9CfrBootstrapMethod *end = _bootstrapMethodsAttribute->bootstrapMethods + _bootstrapMethodsAttribute->numberOfBootstrapMethods;900for (J9CfrBootstrapMethod *bsm = _bootstrapMethodsAttribute->bootstrapMethods; bsm != end; ++bsm) {901U_16 *endArguments = bsm->bootstrapArguments + bsm->numberOfBootstrapArguments;902visitor->visitBootstrapMethod(bsm->bootstrapMethodIndex, bsm->numberOfBootstrapArguments);903for (U_16 *argument = bsm->bootstrapArguments; argument != endArguments; ++argument) {904visitor->visitBootstrapArgument(*argument);905}906}907}908}909910UTF8Iterator getUTF8Iterator() const { return UTF8Iterator(_classFile); }911NameAndTypeIterator getNameAndTypeIterator() const { return NameAndTypeIterator(_classFile); }912FieldIterator getFieldIterator() { return FieldIterator(_fieldsInfo, _classFile); }913MethodIterator getMethodIterator() { return MethodIterator(_methodsInfo, _classFile); }914RecordComponentIterator getRecordComponentIterator() { return RecordComponentIterator(_recordComponentsInfo, _recordComponentCount); }915916ClassFileOracle(BufferManager *bufferManager, J9CfrClassFile *classFile, ConstantPoolMap *constantPoolMap, U_8 * verifyExcludeAttribute, U_8 * romBuilderClassFileBuffer, ROMClassCreationContext *context);917~ClassFileOracle();918919bool isOK() const { return OK == _buildResult; }920BuildResult getBuildResult() const { return _buildResult; }921922/*923* Query methods.924*/925926U_32 getClassFileSize() const { return _classFile->classFileSize; }927U_16 getAccessFlags() const { return _classFile->accessFlags; }928U_16 getSingleScalarStaticCount() const { return _singleScalarStaticCount; }929U_16 getInterfacesCount() const { return _classFile->interfacesCount; }930U_16 getMethodsCount() const { return _classFile->methodsCount; }931U_16 getFieldsCount() const { return _classFile->fieldsCount; }932U_16 getConstantPoolCount() const { return _classFile->constantPoolCount; }933U_16 getObjectStaticCount() const { return _objectStaticCount; }934U_16 getDoubleScalarStaticCount() const { return _doubleScalarStaticCount; }935U_16 getMemberAccessFlags() const { return _memberAccessFlags; }936U_16 getInnerClassCount() const { return _innerClassCount; }937U_16 getEnclosedInnerClassCount() const { return _enclosedInnerClassCount; }938#if JAVA_SPEC_VERSION >= 11939U_16 getNestMembersCount() const { return _nestMembersCount; }940U_16 getNestHostNameIndex() const { return _nestHost; }941#endif /* JAVA_SPEC_VERSION >= 11 */942U_16 getMajorVersion() const { return _classFile->majorVersion; }943U_16 getMinorVersion() const { return _classFile->minorVersion; }944U_32 getMaxBranchCount() const { return _maxBranchCount; }945U_16 getClassNameIndex() const { return U_16(_classFile->constantPool[_classFile->thisClass].slot1); }946U_16 getSuperClassNameIndex() const { return U_16(_classFile->constantPool[_classFile->superClass].slot1); }947U_16 getOuterClassNameIndex() const { return _outerClassNameIndex; }948U_16 getSimpleNameIndex() const { return _simpleNameIndex; }949U_16 getEnclosingMethodClassRefIndex() const { return hasEnclosingMethod() ? _enclosingMethod->classIndex : 0; }950U_16 getEnclosingMethodNameAndSignatureIndex() const { return hasEnclosingMethod() ? _enclosingMethod->methodIndex : 0; }951U_16 getGenericSignatureIndex() const { return hasGenericSignature() ? _genericSignature->signatureIndex : 0; }952U_16 getUTF8Length(U_16 cpIndex) const { return U_16(_classFile->constantPool[cpIndex].slot1); }953U_8 *getUTF8Data(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].bytes; }954U_16 getNameAndSignatureNameUTF8Length(U_16 cpIndex) const { return getUTF8Length(U_16(_classFile->constantPool[cpIndex].slot1)); }955U_8 *getNameAndSignatureNameUTF8Data(U_16 cpIndex) const { return getUTF8Data(U_16(_classFile->constantPool[cpIndex].slot1)); }956U_16 getNameAndSignatureSignatureUTF8Length(U_16 cpIndex) const { return getUTF8Length(U_16(_classFile->constantPool[cpIndex].slot2)); }957U_8 *getNameAndSignatureSignatureUTF8Data(U_16 cpIndex) const { return getUTF8Data(U_16(_classFile->constantPool[cpIndex].slot2)); }958U_16 getSourceFileIndex() const { return hasSourceFile() ? _sourceFile->sourceFileIndex : 0; }959U_32 getSourceDebugExtensionLength() const { return hasSourceDebugExtension() ? _sourceDebugExtension->length : 0; }960U_8 *getSourceDebugExtensionData() const { return hasSourceDebugExtension() ? _sourceDebugExtension->value : NULL; }961U_16 getBootstrapMethodCount() const { return hasBootstrapMethods() ? _bootstrapMethodsAttribute->numberOfBootstrapMethods : 0; }962963bool hasClassAnnotations() const { return NULL != _annotationsAttribute; }964bool hasTypeAnnotations() const { return NULL != _typeAnnotationsAttribute; }965U_16 getFieldNameIndex(U_16 fieldIndex) const { return _classFile->fields[fieldIndex].nameIndex; }966U_16 getFieldDescriptorIndex(U_16 fieldIndex) const { return _classFile->fields[fieldIndex].descriptorIndex; }967U_16 getMethodNameIndex(U_16 methodIndex) const { return _classFile->methods[methodIndex].nameIndex; }968void sortLineNumberTable(U_16 methodIndex, J9CfrLineNumberTableEntry *lineNumbersInfo);969U_16 getMethodDescriptorIndex(U_16 methodIndex) const { return _classFile->methods[methodIndex].descriptorIndex; }970void getPrimitiveConstant(U_16 cpIndex, U_32 *slot1, U_32 *slot2) const971{972*slot1 = _classFile->constantPool[cpIndex].slot1;973*slot2 = _classFile->constantPool[cpIndex].slot2;974}975976U_8 getCPTag(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].tag; }977U_32 getCPSlot1(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].slot1; }978U_32 getCPSlot2(U_16 cpIndex) const { return _classFile->constantPool[cpIndex].slot2; }979980/*981* Long and Double CP entries are never tagged as "referenced" because they are only reached through LDC2W instructions,982* so don't check the ".referenced" flag in isConstantLong() or isConstantDouble().983*/984bool isConstantLong(U_16 cpIndex) const { return CFR_CONSTANT_Long == _classFile->constantPool[cpIndex].tag; }985bool isConstantDouble(U_16 cpIndex) const { return CFR_CONSTANT_Double == _classFile->constantPool[cpIndex].tag; }986bool isConstantDynamic(U_16 cpIndex) const { return CFR_CONSTANT_Dynamic == _classFile->constantPool[cpIndex].tag;}987bool isConstantInteger0(U_16 cpIndex) const { return (CFR_CONSTANT_Integer == _classFile->constantPool[cpIndex].tag) && (0 == _classFile->constantPool[cpIndex].slot1); }988bool isConstantFloat0(U_16 cpIndex) const { return (CFR_CONSTANT_Float == _classFile->constantPool[cpIndex].tag) && (0 == _classFile->constantPool[cpIndex].slot1); }989bool isUTF8AtIndexEqualToString(U_16 cpIndex, const char *string, UDATA stringSize) { return (getUTF8Length(cpIndex) == (stringSize - 1)) && (0 == memcmp(getUTF8Data(cpIndex), string, stringSize - 1)); }990bool hasEmptyFinalizeMethod() const { return _hasEmptyFinalizeMethod; }991bool hasFinalFields() const { return _hasFinalFields; }992bool isClassContended() const { return _isClassContended; }993bool isClassUnmodifiable() const { return _isClassUnmodifiable; }994bool hasNonStaticNonAbstractMethods() const { return _hasNonStaticNonAbstractMethods; }995bool hasFinalizeMethod() const { return _hasFinalizeMethod; }996bool isCloneable() const { return _isCloneable; }997bool isSerializable() const { return _isSerializable; }998bool isSynthetic() const { return _isSynthetic; }999bool hasEnclosingMethod() const { return NULL != _enclosingMethod; }1000bool hasGenericSignature() const { return NULL != _genericSignature; }1001bool hasSimpleName() const { return 0 != getSimpleNameIndex(); }1002bool hasVerifyExcludeAttribute() const { return _hasVerifyExcludeAttribute; }1003bool hasSourceFile() const { return NULL != _sourceFile; }1004bool hasSourceDebugExtension() const { return NULL != _sourceDebugExtension; }1005bool hasBootstrapMethods() const { return NULL != _bootstrapMethodsAttribute; }1006bool hasClinit() const { return _hasClinit; }1007bool annotationRefersDoubleSlotEntry() const { return _annotationRefersDoubleSlotEntry; }1008bool isInnerClass() const { return _isInnerClass; }1009bool needsStaticConstantInit() const { return _needsStaticConstantInit; }1010bool isRecord() const { return _isRecord; }1011U_16 getRecordComponentCount() const { return _recordComponentCount; }1012bool isSealed() const { return _isSealed; }1013U_16 getPermittedSubclassesClassCount() const { return _isSealed ? _permittedSubclassesAttribute->numberOfClasses : 0; }1014bool isValueBased() const { return _isClassValueBased; }1015#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1016bool needsIdentityInterface() const { return _isIdentityInterfaceNeeded; }1017bool hasIdentityInterface() const { return _hasIdentityInterface; }1018bool isValueType() const { return _isValueType; }1019#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */10201021U_16 getPermittedSubclassesClassNameAtIndex(U_16 index) const {1022U_16 result = 0;1023if (_isSealed) {1024U_16 classCpIndex = _permittedSubclassesAttribute->classes[index];1025result = _classFile->constantPool[classCpIndex].slot1;1026}1027return result;1028}102910301031U_8 constantDynamicType(U_16 cpIndex) const1032{1033J9CfrConstantPoolInfo* nas = &_classFile->constantPool[_classFile->constantPool[cpIndex].slot2];1034J9CfrConstantPoolInfo* signature = &_classFile->constantPool[nas->slot2];1035U_8 result = 0;10361037if ('D' == signature->bytes[0]) {1038result = JBldc2dw;1039} else if ('J' == signature->bytes[0]) {1040result = JBldc2lw;1041} else {1042Trc_BCU_Assert_ShouldNeverHappen();1043}10441045return result;1046}10471048private:1049class InterfaceVisitor;10501051enum {1052FRAMEITERATORSKIP_ANNOTATION,1053SUN_REFLECT_CALLERSENSITIVE_ANNOTATION,1054JDK_INTERNAL_REFLECT_CALLERSENSITIVE_ANNOTATION,1055#if JAVA_SPEC_VERSION >= 181056JDK_INTERNAL_REFLECT_CALLERSENSITIVEADAPTER_ANNOTATION,1057#endif /* JAVA_SPEC_VERSION >= 18*/1058JAVA8_CONTENDED_ANNOTATION,1059CONTENDED_ANNOTATION,1060UNMODIFIABLE_ANNOTATION,1061VALUEBASED_ANNOTATION,1062#if defined(J9VM_OPT_OPENJDK_METHODHANDLE)1063HIDDEN_ANNOTATION,1064#endif /* defined(J9VM_OPT_OPENJDK_METHODHANDLE) */1065#if JAVA_SPEC_VERSION >= 161066SCOPED_ANNOTATION,1067#endif /* JAVA_SPEC_VERSION >= 16*/1068KNOWN_ANNOTATION_COUNT1069};10701071struct KnownAnnotation1072{1073const char *name;1074size_t size;1075};10761077static KnownAnnotation _knownAnnotations[];1078BuildResult _buildResult;1079BufferManager *_bufferManager;1080J9CfrClassFile *_classFile;1081ConstantPoolMap *_constantPoolMap;1082U_8 *_verifyExcludeAttribute;1083U_8 *_romBuilderClassFileBuffer;1084UDATA _bctFlags;1085ROMClassCreationContext *_context;10861087U_16 _singleScalarStaticCount;1088U_16 _objectStaticCount;1089U_16 _doubleScalarStaticCount;1090U_16 _memberAccessFlags;1091U_16 _innerClassCount;1092U_16 _enclosedInnerClassCount;1093#if JAVA_SPEC_VERSION >= 111094U_16 _nestMembersCount;1095U_16 _nestHost;1096#endif /* JAVA_SPEC_VERSION >= 11 */1097U_32 _maxBranchCount;1098U_16 _outerClassNameIndex;1099U_16 _simpleNameIndex;1100U_16 _recordComponentCount;11011102bool _hasEmptyFinalizeMethod;1103bool _hasFinalFields;1104bool _hasNonStaticNonAbstractMethods;1105bool _hasFinalizeMethod;1106bool _isCloneable;1107bool _isSerializable;1108bool _isSynthetic;1109bool _isClassContended;1110bool _isClassUnmodifiable;1111bool _hasVerifyExcludeAttribute;1112bool _hasFrameIteratorSkipAnnotation;1113bool _hasClinit;1114bool _annotationRefersDoubleSlotEntry;1115bool _isInnerClass;1116bool _needsStaticConstantInit;1117bool _isRecord;1118bool _isSealed;1119bool _isClassValueBased;1120#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1121bool _hasIdentityInterface;1122bool _isIdentityInterfaceNeeded;1123bool _isValueType;1124bool _hasNonStaticSynchronizedMethod;1125bool _hasNonStaticFields;1126bool _hasNonEmptyConstructor;1127#endif /* J9VM_OPT_VALHALLA_VALUE_TYPES */11281129FieldInfo *_fieldsInfo;1130MethodInfo *_methodsInfo;1131RecordComponentInfo *_recordComponentsInfo;11321133J9CfrAttributeSignature *_genericSignature;1134J9CfrAttributeEnclosingMethod *_enclosingMethod;1135J9CfrAttributeSourceFile *_sourceFile;1136J9CfrAttributeUnknown *_sourceDebugExtension;1137J9CfrAttributeRuntimeVisibleAnnotations *_annotationsAttribute;1138J9CfrAttributeRuntimeVisibleTypeAnnotations *_typeAnnotationsAttribute;1139J9CfrAttributeInnerClasses *_innerClasses;1140J9CfrAttributeBootstrapMethods *_bootstrapMethodsAttribute;1141J9CfrAttributePermittedSubclasses *_permittedSubclassesAttribute;1142#if JAVA_SPEC_VERSION >= 111143J9CfrAttributeNestMembers *_nestMembers;1144#endif /* JAVA_SPEC_VERSION >= 11 */11451146void walkHeader();1147void walkFields();1148void walkAttributes();1149void checkHiddenClass();1150void walkInterfaces();1151#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1152void checkAndRecordIsIdentityInterfaceNeeded();1153#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */1154void walkMethods();1155void walkRecordComponents(J9CfrAttributeRecord *attrib);11561157UDATA walkAnnotations(U_16 annotationsCount, J9CfrAnnotation *annotations, UDATA knownAnnotationSet);1158void walkTypeAnnotations(U_16 annotationsCount, J9CfrTypeAnnotation *annotations);1159void walkAnnotationElement(J9CfrAnnotationElement * annotationElement);11601161void computeSendSlotCount(U_16 methodIndex);11621163void walkMethodAttributes(U_16 methodIndex);1164void walkMethodThrownExceptions(U_16 methodIndex);1165void walkMethodCodeAttribute(U_16 methodIndex);1166void throwGenericErrorWithCustomMsg(UDATA code, UDATA offset);1167void walkMethodCodeAttributeAttributes(U_16 methodIndex);1168void walkMethodCodeAttributeCaughtExceptions(U_16 methodIndex);1169void walkMethodCodeAttributeCode(U_16 methodIndex);1170void walkMethodMethodParametersAttribute(U_16 methodIndex);11711172U_8 * walkStackMapSlots(U_8 *framePointer, U_16 typeInfoCount);11731174bool methodIsFinalize(U_16 methodIndex, bool isForwarder);1175bool methodIsEmpty(U_16 methodIndex);1176bool methodIsForwarder(U_16 methodIndex);1177bool methodIsGetter(U_16 methodIndex);1178bool methodIsVirtual(U_16 methodIndex);1179bool methodIsObjectConstructor(U_16 methodIndex);1180bool methodIsClinit(U_16 methodIndex);1181bool methodIsNonStaticNonAbstract(U_16 methodIndex);1182#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1183bool methodIsConstructor(U_16 methodIndex);1184bool methodIsNonStaticSynchronized(U_16 methodIndex);1185#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */11861187bool shouldConvertInvokeVirtualToInvokeSpecialForMethodRef(U_16 methodRefCPIndex);1188UDATA shouldConvertInvokeVirtualToMethodHandleBytecodeForMethodRef(U_16 methodRefCPIndex);11891190VMINLINE bool containsKnownAnnotation(UDATA knownAnnotationSet, UDATA knownAnnotation);1191VMINLINE UDATA addAnnotationBit(UDATA annotationBits, UDATA knownAnnotation);11921193VMINLINE void addBytecodeFixupEntry(BytecodeFixupEntry *entry, U_32 codeIndex, U_16 cpIndex, U_8 type);11941195VMINLINE void markClassAsReferenced(U_16 classCPIndex);1196VMINLINE void markClassNameAsReferenced(U_16 classCPIndex);1197VMINLINE void markStringAsReferenced(U_16 cpIndex);1198VMINLINE void markNameAndDescriptorAsReferenced(U_16 nasCPIndex);1199VMINLINE void markFieldRefAsReferenced(U_16 cpIndex);1200VMINLINE void markMethodRefAsReferenced(U_16 cpIndex);1201VMINLINE void markMethodTypeAsReferenced(U_16 cpIndex);1202VMINLINE void markMethodHandleAsReferenced(U_16 cpIndex);1203VMINLINE void markMethodRefForMHInvocationAsReferenced(U_16 cpIndex);12041205VMINLINE void markConstantAsReferenced(U_16 cpIndex);1206VMINLINE void markConstantDynamicAsReferenced(U_16 cpIndex);1207VMINLINE void markConstantNameAndTypeAsReferenced(U_16 cpIndex);1208VMINLINE void markConstantUTF8AsReferenced(U_16 cpIndex);12091210VMINLINE void markConstantAsUsedByAnnotation(U_16 cpIndex);1211VMINLINE void markConstantAsUsedByLDC(U_8 cpIndex);1212VMINLINE void markConstantAsUsedByLDC2W(U_16 cpIndex);12131214VMINLINE void markClassAsUsedByInstanceOf(U_16 classCPIndex);1215VMINLINE void markClassAsUsedByCheckCast(U_16 classCPIndex);1216VMINLINE void markClassAsUsedByMultiANewArray(U_16 classCPIndex);1217VMINLINE void markClassAsUsedByANewArray(U_16 classCPIndex);1218VMINLINE void markClassAsUsedByNew(U_16 classCPIndex);12191220#if defined(J9VM_OPT_VALHALLA_VALUE_TYPES)1221VMINLINE void markClassAsUsedByAconst_init(U_16 classCPIndex);1222VMINLINE void markFieldRefAsUsedByWithField(U_16 fieldRefCPIndex);1223#endif /* defined(J9VM_OPT_VALHALLA_VALUE_TYPES) */12241225VMINLINE void markInvokeDynamicInfoAsUsedByInvokeDynamic(U_16 cpIndex);12261227VMINLINE void markFieldRefAsUsedByGetStatic(U_16 fieldRefCPIndex);1228VMINLINE void markFieldRefAsUsedByPutStatic(U_16 fieldRefCPIndex);1229VMINLINE void markFieldRefAsUsedByGetField(U_16 fieldRefCPIndex);1230VMINLINE void markFieldRefAsUsedByPutField(U_16 fieldRefCPIndex);12311232VMINLINE void markMethodRefAsUsedByInvokeVirtual(U_16 methodRefCPIndex);1233VMINLINE void markMethodRefAsUsedByInvokeSpecial(U_16 methodRefCPIndex);1234VMINLINE void markMethodRefAsUsedByInvokeStatic(U_16 methodRefCPIndex);1235VMINLINE void markMethodRefAsUsedByInvokeInterface(U_16 methodRefCPIndex);1236VMINLINE void markMethodRefAsUsedByInvokeHandle(U_16 methodRefCPIndex);1237VMINLINE void markMethodRefAsUsedByInvokeHandleGeneric(U_16 methodRefCPIndex);1238VMINLINE void markConstantBasedOnCpType(U_16 cpIndex, bool assertNotDoubleOrLong);123912401241static int compareLineNumbers(const void *left, const void *right);1242void compressLineNumberTable(U_16 methodIndex, U_32 lineNumbersCount);1243void sortAndCompressLineNumberTable(U_16 methodIndex, U_32 lineNumbersCount, U_8 *lineNumbersInfoCompressedInitial);1244};12451246#endif /* CLASSFILEORACLE_HPP_ */124712481249