diff --git a/doc/compiler/aot/RelocationRecords.md b/doc/compiler/aot/RelocationRecords.md index ce6cc026387..e3173b71982 100644 --- a/doc/compiler/aot/RelocationRecords.md +++ b/doc/compiler/aot/RelocationRecords.md @@ -140,4 +140,4 @@ exact type of the API class for each relocation kind can be found in |`TR_ValidateDynamicMethodFromCallsiteIndex`|Validates the target method of an `invokeDynamic` invocation.| |`TR_ValidateHandleMethodFromCPIndex`|Validates the target method of an `invokeHandle` invocation.| |`TR_CallsiteTableEntryAddress`|Relocates the callsite table entry address.| - +|`TR_MethodTypeTableEntryAddress`|Relocates the method type table entry address.| diff --git a/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp index 9d2e5989bc9..d03226001d6 100644 --- a/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp @@ -1394,6 +1394,22 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal } break; + + case TR_MethodTypeTableEntryAddress: + { + auto *mteaRecord = reinterpret_cast(reloRecord); + + TR::SymbolReference *symRef = reinterpret_cast(relocation->getTargetAddress()); + uint8_t flags = static_cast(reinterpret_cast(relocation->getTargetAddress2())); + + TR_OpaqueMethodBlock *method = symRef->getOwningMethod(comp)->getNonPersistentIdentifier(); + + mteaRecord->setReloFlags(reloTarget, flags); + mteaRecord->setMethodID(reloTarget, symValManager->getSymbolIDFromValue(method)); + mteaRecord->setCpIndex(reloTarget, symRef->getSymbol()->getStaticSymbol()->getMethodTypeIndex()); + } + break; + default: TR_ASSERT(false, "Unknown relo type %d!\n", kind); comp->failCompilation("Unknown relo type %d!\n", kind); @@ -2393,6 +2409,22 @@ J9::AheadOfTimeCompile::dumpRelocationHeaderData(uint8_t *cursor, bool isVerbose } break; + case TR_MethodTypeTableEntryAddress: + { + auto *mteaRecord = reinterpret_cast(reloRecord); + + self()->traceRelocationOffsets(startOfOffsets, offsetSize, endOfCurrentRecord, orderedPair); + if (isVerbose) + { + traceMsg( + self()->comp(), + "\n Method Type Table Entry Address: methodID=%d, cpIndex=%d ", + (uint32_t)mteaRecord->methodID(reloTarget), + mteaRecord->cpIndex(reloTarget)); + } + } + break; + default: TR_ASSERT_FATAL(false, "dumpRelocationHeaderData: unknown relo kind %d\n", kind); } diff --git a/runtime/compiler/il/J9StaticSymbol_inlines.hpp b/runtime/compiler/il/J9StaticSymbol_inlines.hpp index 45c6d66377c..c730b9e9965 100644 --- a/runtime/compiler/il/J9StaticSymbol_inlines.hpp +++ b/runtime/compiler/il/J9StaticSymbol_inlines.hpp @@ -42,6 +42,9 @@ J9::StaticSymbol::makeMethodTypeTableEntry(int32_t methodTypeIndex) TR_ASSERT(self()->getDataType() == TR::Address, "MethodTypeTableEntries have historically had TR::Address as data type"); _methodTypeIndex = methodTypeIndex; self()->setMethodTypeTableEntry(); + + // Needed so that the relo infra does not think this is a static field address + self()->setNotDataAddress(); } inline void diff --git a/runtime/compiler/p/runtime/PPCRelocationTarget.cpp b/runtime/compiler/p/runtime/PPCRelocationTarget.cpp index 71f9728cbec..6c8525199e8 100644 --- a/runtime/compiler/p/runtime/PPCRelocationTarget.cpp +++ b/runtime/compiler/p/runtime/PPCRelocationTarget.cpp @@ -314,6 +314,7 @@ TR_PPC32RelocationTarget::isOrderedPairRelocation(TR_RelocationRecord *reloRecor case TR_DebugCounter: case TR_MethodEnterExitHookAddress: case TR_CallsiteTableEntryAddress: + case TR_MethodTypeTableEntryAddress: return true; default: return false; diff --git a/runtime/compiler/runtime/RelocationRecord.cpp b/runtime/compiler/runtime/RelocationRecord.cpp index b912170602d..58bc5828879 100644 --- a/runtime/compiler/runtime/RelocationRecord.cpp +++ b/runtime/compiler/runtime/RelocationRecord.cpp @@ -429,6 +429,12 @@ struct TR_RelocationRecordCallsiteTableEntryAddressBinaryTemplate : public TR_Re int32_t _callsiteIndex; }; +struct TR_RelocationRecordMethodTypeTableEntryAddressBinaryTemplate : public TR_RelocationRecordBinaryTemplate + { + uint16_t _methodID; + int32_t _cpIndex; + }; + // END OF BINARY TEMPLATES uint8_t @@ -871,6 +877,9 @@ TR_RelocationRecord::create(TR_RelocationRecord *storage, TR_RelocationRuntime * case TR_CallsiteTableEntryAddress: reloRecord = new (storage) TR_RelocationRecordCallsiteTableEntryAddress(reloRuntime, record); break; + case TR_MethodTypeTableEntryAddress: + reloRecord = new (storage) TR_RelocationRecordMethodTypeTableEntryAddress(reloRuntime, record); + break; default: // TODO: error condition printf("Unexpected relo record: %d\n", reloType);fflush(stdout); @@ -6900,6 +6909,74 @@ TR_RelocationRecordCallsiteTableEntryAddress::applyRelocation(TR_RelocationRunti return TR_RelocationErrorCode::relocationOK; } +// TR_RelocationRecordMethodTypeTableEntryAddress +void +TR_RelocationRecordMethodTypeTableEntryAddress::print(TR_RelocationRuntime *reloRuntime) + { + TR_RelocationTarget *reloTarget = reloRuntime->reloTarget(); + TR_RelocationRuntimeLogger *reloLogger = reloRuntime->reloLogger(); + TR_RelocationRecord::print(reloRuntime); + reloLogger->printf("\tmethodID %d\n", methodID(reloTarget)); + reloLogger->printf("\tcpIndex %d\n", cpIndex(reloTarget)); + } + +void +TR_RelocationRecordMethodTypeTableEntryAddress::setMethodID(TR_RelocationTarget *reloTarget, uint16_t methodID) + { + reloTarget->storeUnsigned16b(methodID, (uint8_t *) &((TR_RelocationRecordMethodTypeTableEntryAddressBinaryTemplate *)_record)->_methodID); + } + +uint16_t +TR_RelocationRecordMethodTypeTableEntryAddress::methodID(TR_RelocationTarget *reloTarget) + { + return reloTarget->loadUnsigned16b((uint8_t *) &((TR_RelocationRecordMethodTypeTableEntryAddressBinaryTemplate *)_record)->_methodID); + } + +void +TR_RelocationRecordMethodTypeTableEntryAddress::setCpIndex(TR_RelocationTarget *reloTarget, int32_t cpIndex) + { + reloTarget->storeSigned32b(cpIndex, (uint8_t *) &((TR_RelocationRecordMethodTypeTableEntryAddressBinaryTemplate *)_record)->_cpIndex); + } + +int32_t +TR_RelocationRecordMethodTypeTableEntryAddress::cpIndex(TR_RelocationTarget *reloTarget) + { + return reloTarget->loadSigned32b((uint8_t *) &((TR_RelocationRecordMethodTypeTableEntryAddressBinaryTemplate *)_record)->_cpIndex); + } + +void +TR_RelocationRecordMethodTypeTableEntryAddress::preparePrivateData(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget) + { + TR_RelocationRecordMethodTypeTableEntryAddressPrivateData *reloPrivateData = &(privateData()->methodTypeTableEntryAddr); + + TR_OpaqueMethodBlock *method = reloRuntime->comp()->getSymbolValidationManager()->getMethodFromID(methodID(reloTarget)); + TR_ResolvedMethod *resolvedMethod = reloRuntime->fej9()->createResolvedMethod(reloRuntime->trMemory(), method, NULL); + + reloPrivateData->_methodTypeTableEntryAddress = resolvedMethod->methodTypeTableEntryAddress(cpIndex(reloTarget)); + } + +TR_RelocationErrorCode +TR_RelocationRecordMethodTypeTableEntryAddress::applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation) + { + TR_RelocationRecordMethodTypeTableEntryAddressPrivateData *reloPrivateData = &(privateData()->methodTypeTableEntryAddr); + void *methodTypeTableEntryAddr = reloPrivateData->_methodTypeTableEntryAddress; + + reloTarget->storeAddressSequence((uint8_t *)methodTypeTableEntryAddr, reloLocation, reloFlags(reloTarget)); + + return TR_RelocationErrorCode::relocationOK; + } + +TR_RelocationErrorCode +TR_RelocationRecordMethodTypeTableEntryAddress::applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocationHigh, uint8_t *reloLocationLow) + { + TR_RelocationRecordMethodTypeTableEntryAddressPrivateData *reloPrivateData = &(privateData()->methodTypeTableEntryAddr); + void *methodTypeTableEntryAddr = reloPrivateData->_methodTypeTableEntryAddress; + + reloTarget->storeAddress((uint8_t *)methodTypeTableEntryAddr, reloLocationHigh, reloLocationLow, reloFlags(reloTarget)); + + return TR_RelocationErrorCode::relocationOK; + } + // The _relocationRecordHeaderSizeTable table should be the last thing in this file uint32_t TR_RelocationRecord::_relocationRecordHeaderSizeTable[TR_NumExternalRelocationKinds] = { @@ -7022,5 +7099,6 @@ uint32_t TR_RelocationRecord::_relocationRecordHeaderSizeTable[TR_NumExternalRel sizeof(TR_RelocationRecordValidateDynamicMethodFromCallsiteIndexBinaryTemplate), // TR_ValidateDynamicMethodFromCallsiteIndex = 116 sizeof(TR_RelocationRecordValidateHandleMethodFromCPIndexBinaryTemplate), // TR_ValidateHandleMethodFromCPIndex = 117 sizeof(TR_RelocationRecordCallsiteTableEntryAddressBinaryTemplate), // TR_CallsiteTableEntryAddress = 118 + sizeof(TR_RelocationRecordMethodTypeTableEntryAddressBinaryTemplate), // TR_MethodTypeTableEntryAddress = 119 }; // The _relocationRecordHeaderSizeTable table should be the last thing in this file diff --git a/runtime/compiler/runtime/RelocationRecord.hpp b/runtime/compiler/runtime/RelocationRecord.hpp index 00d4766d858..0d2ed4af9b6 100644 --- a/runtime/compiler/runtime/RelocationRecord.hpp +++ b/runtime/compiler/runtime/RelocationRecord.hpp @@ -181,6 +181,11 @@ struct TR_RelocationRecordCallsiteTableEntryAddressPrivateData void *_callsiteTableEntryAddress; }; +struct TR_RelocationRecordMethodTypeTableEntryAddressPrivateData + { + void *_methodTypeTableEntryAddress; + }; + union TR_RelocationRecordPrivateData { TR_RelocationRecordHelperAddressPrivateData helperAddress; @@ -201,6 +206,7 @@ union TR_RelocationRecordPrivateData TR_RelocationRecordBreakpointGuardPrivateData breakpointGuard; TR_RelocationRecordMethodEnterExitHookAddressPrivateData hookAddress; TR_RelocationRecordCallsiteTableEntryAddressPrivateData callsiteTableEntryAddr; + TR_RelocationRecordMethodTypeTableEntryAddressPrivateData methodTypeTableEntryAddr; }; enum TR_RelocationRecordAction @@ -2090,5 +2096,26 @@ class TR_RelocationRecordCallsiteTableEntryAddress : public TR_RelocationRecord virtual TR_RelocationErrorCode applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocationHigh, uint8_t *reloLocationLow); }; +class TR_RelocationRecordMethodTypeTableEntryAddress : public TR_RelocationRecord + { + public: + TR_RelocationRecordMethodTypeTableEntryAddress() {} + TR_RelocationRecordMethodTypeTableEntryAddress(TR_RelocationRuntime *reloRuntime, TR_RelocationRecordBinaryTemplate *record) : TR_RelocationRecord(reloRuntime, record) {} + + virtual const char *name() { return "TR_RelocationRecordMethodTypeTableEntryAddress"; } + virtual void print(TR_RelocationRuntime *reloRuntime); + + void setMethodID(TR_RelocationTarget *reloTarget, uint16_t methodID); + uint16_t methodID(TR_RelocationTarget *reloTarget); + + void setCpIndex(TR_RelocationTarget *reloTarget, int32_t cpIndex); + int32_t cpIndex(TR_RelocationTarget *reloTarget); + + virtual void preparePrivateData(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget); + + virtual TR_RelocationErrorCode applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation); + virtual TR_RelocationErrorCode applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocationHigh, uint8_t *reloLocationLow); + }; + #endif // RELOCATION_RECORD_INCL diff --git a/runtime/compiler/runtime/Runtime.cpp b/runtime/compiler/runtime/Runtime.cpp index 7669af61f24..ebccd083db4 100644 --- a/runtime/compiler/runtime/Runtime.cpp +++ b/runtime/compiler/runtime/Runtime.cpp @@ -2099,6 +2099,7 @@ bool isOrderedPair(U_8 recordType) case TR_DebugCounter: case TR_MethodEnterExitHookAddress: case TR_CallsiteTableEntryAddress: + case TR_MethodTypeTableEntryAddress: #endif isOrderedPair = true; break; diff --git a/runtime/compiler/z/codegen/S390AOTRelocation.cpp b/runtime/compiler/z/codegen/S390AOTRelocation.cpp index fd13c9e5e07..c46163eda09 100644 --- a/runtime/compiler/z/codegen/S390AOTRelocation.cpp +++ b/runtime/compiler/z/codegen/S390AOTRelocation.cpp @@ -260,6 +260,19 @@ void TR::S390EncodingRelocation::addRelocation(TR::CodeGenerator *cg, uint8_t *c line, node); } + else if (_reloType==TR_MethodTypeTableEntryAddress) + { + cg->addExternalRelocation( + TR::ExternalRelocation::create( + cursor, + (uint8_t *)_symbolReference, + NULL, + TR_MethodTypeTableEntryAddress, + cg), + file, + line, + node); + } else { TR_ASSERT(0,"relocation type [%d] not handled yet", _reloType);