diff --git a/runtime/compiler/aarch64/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/aarch64/codegen/J9AheadOfTimeCompile.cpp index e04553e1143..584539d8f7a 100644 --- a/runtime/compiler/aarch64/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/aarch64/codegen/J9AheadOfTimeCompile.cpp @@ -35,6 +35,7 @@ J9::ARM64::AheadOfTimeCompile::AheadOfTimeCompile(TR::CodeGenerator *cg) : void J9::ARM64::AheadOfTimeCompile::processRelocations() { + TR::Compilation *comp = self()->comp(); TR_J9VMBase *fej9 = (TR_J9VMBase *)(_cg->fe()); TR::IteratedExternalRelocation *r; @@ -53,7 +54,7 @@ void J9::ARM64::AheadOfTimeCompile::processRelocations() // Note that when using the SymbolValidationManager, the well-known classes // must be checked even if no explicit records were generated, since they // might be responsible for the lack of records. - bool useSVM = self()->comp()->getOption(TR_UseSymbolValidationManager); + bool useSVM = comp->getOption(TR_UseSymbolValidationManager); if (self()->getSizeOfAOTRelocations() != 0 || useSVM) { @@ -64,7 +65,7 @@ void J9::ARM64::AheadOfTimeCompile::processRelocations() uintptr_t reloBufferSize = self()->getSizeOfAOTRelocations() + SIZEPOINTER + wellKnownClassesOffsetSize; uint8_t *relocationDataCursor = - self()->setRelocationData(fej9->allocateRelocationData(self()->comp(), reloBufferSize)); + self()->setRelocationData(fej9->allocateRelocationData(comp, reloBufferSize)); // set up the size for the region *(uintptr_t *)relocationDataCursor = reloBufferSize; @@ -72,11 +73,13 @@ void J9::ARM64::AheadOfTimeCompile::processRelocations() if (useSVM) { - TR::SymbolValidationManager *svm = - self()->comp()->getSymbolValidationManager(); - void *offsets = const_cast(svm->wellKnownClassChainOffsets()); - *(uintptr_t *)relocationDataCursor = - self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); + TR::SymbolValidationManager *svm = comp->getSymbolValidationManager(); + void *offsets = const_cast(svm->wellKnownClassChainOffsets()); + uintptr_t *wkcOffsetAddr = (uintptr_t *)relocationDataCursor; + *wkcOffsetAddr = self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); +#if defined(J9VM_OPT_JITSERVER) + self()->addWellKnownClassesSerializationRecord(svm->aotCacheWellKnownClassesRecord(), wkcOffsetAddr); +#endif /* defined(J9VM_OPT_JITSERVER) */ relocationDataCursor += SIZEPOINTER; } diff --git a/runtime/compiler/arm/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/arm/codegen/J9AheadOfTimeCompile.cpp index a5fac3452e4..559337d13ed 100644 --- a/runtime/compiler/arm/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/arm/codegen/J9AheadOfTimeCompile.cpp @@ -230,7 +230,7 @@ J9::ARM::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR::I TR_RelocationRecordArbitraryClassAddress *acaRecord = reinterpret_cast(reloRecord); // ExternalRelocation data is as expected for TR_ClassAddress - TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress(); + TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation *)relocation->getTargetAddress(); auto symRef = (TR::SymbolReference *)recordInfo->data1; auto sym = symRef->getSymbol()->castToStaticSymbol(); @@ -239,11 +239,13 @@ J9::ARM::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR::I uintptr_t inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(symRef->getOwningMethod(comp)->constantPool(), recordInfo->data2); uintptr_t classChainIdentifyingLoaderOffsetInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class); - uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class); + const AOTCacheClassChainRecord *classChainRecord = NULL; + uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord); acaRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); - acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache); - acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache); + acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache, + self(), classChainRecord); + acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord); } break; diff --git a/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp index 0cfa4918573..5634cfb1bb7 100644 --- a/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp @@ -36,20 +36,97 @@ #include "runtime/RelocationRuntime.hpp" #include "runtime/RelocationRecord.hpp" #include "runtime/SymbolValidationManager.hpp" +#if defined(J9VM_OPT_JITSERVER) +#include "runtime/JITClientSession.hpp" +#endif /* defined(J9VM_OPT_JITSERVER) */ + extern bool isOrderedPair(uint8_t reloType); uintptr_t -J9::AheadOfTimeCompile::getClassChainOffset(TR_OpaqueClassBlock *classToRemember) +J9::AheadOfTimeCompile::getClassChainOffset(TR_OpaqueClassBlock *classToRemember, + const AOTCacheClassChainRecord *&classChainRecord) + { + TR_J9VMBase *fej9 = (TR_J9VMBase *)self()->comp()->fe(); + TR_SharedCache *sharedCache = fej9->sharedCache(); + void *classChain = sharedCache->rememberClass(classToRemember, &classChainRecord); + if (!classChain) + self()->comp()->failCompilation("classChain == NULL"); + return self()->offsetInSharedCacheFromPointer(sharedCache, classChain); + } + +#if defined(J9VM_OPT_JITSERVER) + +void +J9::AheadOfTimeCompile::addClassSerializationRecord(const AOTCacheClassChainRecord *classChainRecord, + const uintptr_t *romClassOffsetAddr) + { + const AOTCacheClassRecord *record = classChainRecord ? classChainRecord->rootClassRecord() : NULL; + self()->addSerializationRecord(record, romClassOffsetAddr); + } + +void +J9::AheadOfTimeCompile::addClassSerializationRecord(TR_OpaqueClassBlock *ramClass, const uintptr_t *romClassOffsetAddr) { - TR_J9VMBase *fej9 = (TR_J9VMBase *)(self()->comp()->fe()); - TR_SharedCache * sharedCache = fej9->sharedCache(); - void *classChainForInlinedMethod = sharedCache->rememberClass(classToRemember); - if (!classChainForInlinedMethod) - self()->comp()->failCompilation("classChainForInlinedMethod == NULL"); - return self()->offsetInSharedCacheFromPointer(sharedCache, classChainForInlinedMethod); + TR::Compilation *comp = self()->comp(); + if (comp->isAOTCacheStore()) + { + const AOTCacheClassRecord *record = comp->getClientData()->getClassRecord((J9Class *)ramClass, comp->getStream()); + self()->addSerializationRecord(record, romClassOffsetAddr); + } + } + +void +J9::AheadOfTimeCompile::addMethodSerializationRecord(J9Method *method, TR_OpaqueClassBlock *definingClass, + const uintptr_t *romMethodOffsetAddr) + { + TR::Compilation *comp = self()->comp(); + if (comp->isAOTCacheStore()) + { + const AOTCacheMethodRecord *record = comp->getClientData()->getMethodRecord(method, (J9Class *)definingClass, + comp->getStream()); + self()->addSerializationRecord(record, romMethodOffsetAddr); + } } +void +J9::AheadOfTimeCompile::addClassChainSerializationRecord(const AOTCacheClassChainRecord *classChainRecord, + const uintptr_t *classChainOffsetAddr) + { + self()->addSerializationRecord(classChainRecord, classChainOffsetAddr); + } + +void +J9::AheadOfTimeCompile::addClassLoaderSerializationRecord(const AOTCacheClassChainRecord *classChainRecord, + const uintptr_t *loaderChainOffsetAddr) + { + const AOTCacheClassLoaderRecord *record = classChainRecord ? classChainRecord->rootClassLoaderRecord() : NULL; + self()->addSerializationRecord(record, loaderChainOffsetAddr); + } + +void +J9::AheadOfTimeCompile::addWellKnownClassesSerializationRecord(const AOTCacheWellKnownClassesRecord *wkcRecord, + const uintptr_t *wkcOffsetAddr) + { + self()->addSerializationRecord(wkcRecord, wkcOffsetAddr); + } + +void +J9::AheadOfTimeCompile::addSerializationRecord(const AOTCacheRecord *record, const uintptr_t *sccOffsetAddr) + { + TR::Compilation *comp = self()->comp(); + if (comp->isAOTCacheStore()) + { + uint8_t *start = self()->getRelocationData(); + uint8_t *end = start + *(uintptr_t *)start;// Total size of relocation data is stored in the first word + TR_ASSERT_FATAL(((uint8_t *)sccOffsetAddr >= start + sizeof(uintptr_t)) && ((uint8_t *)sccOffsetAddr < end), + "SCC offset address %p not in range %p - %p", sccOffsetAddr, start + sizeof(uintptr_t), end); + comp->addSerializationRecord(record, (uint8_t *)sccOffsetAddr - start); + } + } + +#endif /* defined(J9VM_OPT_JITSERVER) */ + uintptr_t J9::AheadOfTimeCompile::offsetInSharedCacheFromPointer(TR_SharedCache *sharedCache, void *ptr) { @@ -358,13 +435,14 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal { TR_RelocationRecordValidateInstanceField *fieldRecord = reinterpret_cast(reloRecord); uintptr_t inlinedSiteIndex = reinterpret_cast(relocation->getTargetAddress()); - TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); + TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); uintptr_t classChainOffsetInSharedCache = self()->offsetInSharedCacheFromPointer(sharedCache, aotCI->_classChain); fieldRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); fieldRecord->setConstantPool(reloTarget, reinterpret_cast(aotCI->_constantPool)); fieldRecord->setCpIndex(reloTarget, static_cast(aotCI->_cpIndex)); - fieldRecord->setClassChainOffsetInSharedCache(reloTarget, classChainOffsetInSharedCache); + fieldRecord->setClassChainOffsetInSharedCache(reloTarget, classChainOffsetInSharedCache, + self(), aotCI->getAOTCacheClassChainRecord()); } break; @@ -434,7 +512,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal imRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); imRecord->setConstantPool(reloTarget, reinterpret_cast(callSymRef->getOwningMethod(comp)->constantPool())); imRecord->setCpIndex(reloTarget, cpIndexOrData); - imRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache); + imRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache, self(), inlinedMethodClass); if (kind != TR_InlinedInterfaceMethod && kind != TR_InlinedVirtualMethod @@ -452,7 +530,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal TR_RelocationRecordValidateStaticField *vsfRecord = reinterpret_cast(reloRecord); uintptr_t inlinedSiteIndex = reinterpret_cast(relocation->getTargetAddress()); - TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); + TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); J9ROMClass *romClass = reinterpret_cast(fej9->getPersistentClassPointerFromClassPointer(aotCI->_clazz)); uintptr_t romClassOffsetInSharedCache = self()->offsetInSharedCacheFromROMClass(sharedCache, romClass); @@ -460,7 +538,8 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal vsfRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); vsfRecord->setConstantPool(reloTarget, reinterpret_cast(aotCI->_constantPool)); vsfRecord->setCpIndex(reloTarget, aotCI->_cpIndex); - vsfRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache); + vsfRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache, + self(), aotCI->getAOTCacheClassChainRecord()); } break; @@ -469,14 +548,15 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal TR_RelocationRecordValidateClass *vcRecord = reinterpret_cast(reloRecord); uintptr_t inlinedSiteIndex = reinterpret_cast(relocation->getTargetAddress()); - TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); + TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); uintptr_t classChainOffsetInSharedCache = self()->offsetInSharedCacheFromPointer(sharedCache, aotCI->_classChain); vcRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); vcRecord->setConstantPool(reloTarget, reinterpret_cast(aotCI->_constantPool)); vcRecord->setCpIndex(reloTarget, aotCI->_cpIndex); - vcRecord->setClassChainOffsetInSharedCache(reloTarget, classChainOffsetInSharedCache); + vcRecord->setClassChainOffsetInSharedCache(reloTarget, classChainOffsetInSharedCache, + self(), aotCI->getAOTCacheClassChainRecord()); } break; @@ -502,7 +582,8 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal uintptr_t classChainIdentifyingLoaderOffsetInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(inlinedCodeClass); - uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(inlinedCodeClass); + const AOTCacheClassChainRecord *classChainRecord = NULL; + uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(inlinedCodeClass, classChainRecord); uintptr_t methodIndex = fej9->getMethodIndexInClass(inlinedCodeClass, inlinedMethod->getNonPersistentIdentifier()); @@ -521,9 +602,10 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal pRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); pRecord->setConstantPool(reloTarget, reinterpret_cast(owningMethod->constantPool())); pRecord->setCpIndex(reloTarget, cpIndexOrData); - pRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache); - pRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache); - pRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache); + pRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache, self(), classChainRecord); + pRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache, + self(), classChainRecord); + pRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord); pRecord->setMethodIndex(reloTarget, methodIndex); } break; @@ -542,13 +624,16 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal TR_OpaqueClassBlock *j9class = fej9->getClassFromMethodBlock(j9method); uintptr_t classChainOffsetOfCLInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class); - uintptr_t classChainForInlinedMethodOffsetInSharedCache = self()->getClassChainOffset(j9class); + const AOTCacheClassChainRecord *classChainRecord = NULL; + uintptr_t classChainForInlinedMethodOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord); uintptr_t vTableOffset = static_cast(fej9->getInterpreterVTableSlot(j9method, j9class)); mpRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); - mpRecord->setClassChainForInlinedMethod(reloTarget, classChainForInlinedMethodOffsetInSharedCache); - mpRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainOffsetOfCLInSharedCache); + mpRecord->setClassChainForInlinedMethod(reloTarget, classChainForInlinedMethodOffsetInSharedCache, + self(), classChainRecord); + mpRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainOffsetOfCLInSharedCache, + self(), classChainRecord); mpRecord->setVTableSlot(reloTarget, vTableOffset); } break; @@ -582,11 +667,14 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal } uintptr_t classChainOffsetOfCLInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class); - uintptr_t classChainForInlinedMethodOffsetInSharedCache = self()->getClassChainOffset(j9class); + const AOTCacheClassChainRecord *classChainRecord = NULL; + uintptr_t classChainForInlinedMethodOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord); cpRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); - cpRecord->setClassChainForInlinedMethod(reloTarget, classChainForInlinedMethodOffsetInSharedCache); - cpRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainOffsetOfCLInSharedCache); + cpRecord->setClassChainForInlinedMethod(reloTarget, classChainForInlinedMethodOffsetInSharedCache, + self(), classChainRecord); + cpRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainOffsetOfCLInSharedCache, + self(), classChainRecord); } break; @@ -594,7 +682,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal { TR_RelocationRecordValidateArbitraryClass *vacRecord = reinterpret_cast(reloRecord); - TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); + TR::AOTClassInfo *aotCI = reinterpret_cast(relocation->getTargetAddress2()); TR_OpaqueClassBlock *classToValidate = aotCI->_clazz; uintptr_t classChainOffsetInSharedCacheForCL = sharedCache->getClassChainOffsetIdentifyingLoader(classToValidate); @@ -602,8 +690,10 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal void *classChainForClassToValidate = aotCI->_classChain; uintptr_t classChainOffsetInSharedCache = self()->offsetInSharedCacheFromPointer(sharedCache, classChainForClassToValidate); - vacRecord->setClassChainIdentifyingLoaderOffset(reloTarget, classChainOffsetInSharedCacheForCL); - vacRecord->setClassChainOffsetForClassBeingValidated(reloTarget, classChainOffsetInSharedCache); + vacRecord->setClassChainIdentifyingLoaderOffset(reloTarget, classChainOffsetInSharedCacheForCL, + self(), aotCI->getAOTCacheClassChainRecord()); + vacRecord->setClassChainOffsetForClassBeingValidated(reloTarget, classChainOffsetInSharedCache, + self(), aotCI->getAOTCacheClassChainRecord()); } break; @@ -629,7 +719,8 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal cbnRecord->setClassID(reloTarget, symValManager->getIDFromSymbol(svmRecord->_class)); cbnRecord->setBeholderID(reloTarget, symValManager->getIDFromSymbol(svmRecord->_beholder)); - cbnRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache); + cbnRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache, + self(), svmRecord->getAOTCacheClassChainRecord()); } break; @@ -649,8 +740,10 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal uintptr_t classChainOffsetInSharedCache = self()->offsetInSharedCacheFromPointer(sharedCache, classChainForClassToValidate); pcRecord->setClassID(reloTarget, symValManager->getIDFromSymbol(classToValidate)); - pcRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache); - pcRecord->setClassChainOffsetForClassLoader(reloTarget, classChainOffsetInSharedCacheForCL); + pcRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache, + self(), svmRecord->getAOTCacheClassChainRecord()); + pcRecord->setClassChainOffsetForClassLoader(reloTarget, classChainOffsetInSharedCacheForCL, + self(), svmRecord->getAOTCacheClassChainRecord()); } break; @@ -741,7 +834,8 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal uintptr_t classChainOffsetInSharedCache = self()->offsetInSharedCacheFromPointer(sharedCache, classChainForClassToValidate); scmRecord->setSystemClassID(reloTarget, symValManager->getIDFromSymbol(classToValidate)); - scmRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache); + scmRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache, + self(), svmRecord->getAOTCacheClassChainRecord()); } break; @@ -794,7 +888,8 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal uintptr_t classChainOffsetInSharedCache = self()->offsetInSharedCacheFromPointer(sharedCache, classChainForClassToValidate); ccRecord->setClassID(reloTarget, symValManager->getIDFromSymbol(classToValidate)); - ccRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache); + ccRecord->setClassChainOffset(reloTarget, classChainOffsetInSharedCache, + self(), svmRecord->getAOTCacheClassChainRecord()); } break; @@ -926,7 +1021,8 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal mfcsRecord->setDefiningClassID(reloTarget, symValManager->getIDFromSymbol(svmRecord->_definingClass)); mfcsRecord->setBeholderID(reloTarget, symValManager->getIDFromSymbol(svmRecord->_beholder)); mfcsRecord->setLookupClassID(reloTarget, symValManager->getIDFromSymbol(svmRecord->_lookupClass)); - mfcsRecord->setRomMethodOffsetInSCC(reloTarget, romMethodOffsetInSharedCache); + mfcsRecord->setRomMethodOffsetInSCC(reloTarget, romMethodOffsetInSharedCache, self(), + methodToValidate, svmRecord->_definingClass); } break; @@ -1076,11 +1172,13 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(constantPool, inlinedSiteIndex); uintptr_t classChainIdentifyingLoaderOffsetInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class); - uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class); + const AOTCacheClassChainRecord *classChainRecord = NULL; + uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord); acaRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); - acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache); - acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache); + acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache, + self(), classChainRecord); + acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord); } break; diff --git a/runtime/compiler/codegen/J9AheadOfTimeCompile.hpp b/runtime/compiler/codegen/J9AheadOfTimeCompile.hpp index 9082aa862e7..ba9de53741a 100644 --- a/runtime/compiler/codegen/J9AheadOfTimeCompile.hpp +++ b/runtime/compiler/codegen/J9AheadOfTimeCompile.hpp @@ -36,23 +36,112 @@ namespace J9 { typedef J9::AheadOfTimeCompile AheadOfTimeCompileConnector; } #include "env/jittypes.h" namespace TR { class Compilation; } +class AOTCacheRecord; +class AOTCacheClassChainRecord; +class AOTCacheWellKnownClassesRecord; + namespace J9 { class OMR_EXTENSIBLE AheadOfTimeCompile : public OMR::AheadOfTimeCompileConnector { - public: +public: static const size_t SIZEPOINTER = sizeof(uintptr_t); - AheadOfTimeCompile(uint32_t *headerSizeMap, TR::Compilation * c) : + AheadOfTimeCompile(uint32_t *headerSizeMap, TR::Compilation *c) : OMR::AheadOfTimeCompileConnector(headerSizeMap, c) { } - uintptr_t getClassChainOffset(TR_OpaqueClassBlock* classToRemember); + /** + * @brief Gets the class chain offset for a given RAMClass. Calls TR_SharedCache::rememberClass() + * and fails the compilation if the class chain cannot be created. + * + * @param[in] classToRemember the RAMClass to get the class chain offset for + * @param[out] classChainRecord pointer to the AOT cache class chain record corresponding to the class chain, if this + * is an out-of-process compilation that will be stored in JITServerAOT cache; + * ignored for local compilations and out-of-process compilations not stored in AOT cache + * @return class chain SCC offset + */ + uintptr_t getClassChainOffset(TR_OpaqueClassBlock *classToRemember, const AOTCacheClassChainRecord *&classChainRecord); + uintptr_t findCorrectInlinedSiteIndex(void *constantPool, uintptr_t currentInlinedSiteIndex); +#if defined(J9VM_OPT_JITSERVER) + /** + * @brief Adds an AOT cache class record corresponding to a ROMClass SCC offset + * if this out-of-process compilation will be stored in AOT cache. + * + * The resulting AOT cache class record is the root class record of the class chain record. + * + * @param classChainRecord pointer to the AOT cache class chain record for the class + * @param romClassOffsetAddr pointer to the binary relocation record field that stores the ROMClass SCC offset + */ + void addClassSerializationRecord(const AOTCacheClassChainRecord *classChainRecord, const uintptr_t *romClassOffsetAddr); + + /** + * @brief Adds an AOT cache class record corresponding to a ROMClass SCC offset + * if this out-of-process compilation will be stored in AOT cache. + * + * The AOT cache class record is looked up in the client session or created + * on demand, possibly requesting missing information from the client. + * + * @param ramClass the RAMClass that the ROMClass SCC offset is for + * @param romClassOffsetAddr pointer to the binary relocation record field that stores the ROMClass SCC offset + */ + void addClassSerializationRecord(TR_OpaqueClassBlock *ramClass, const uintptr_t *romClassOffsetAddr); + + /** + * @brief Adds an AOT cache method record corresponding to a ROMMethod SCC offset + * if this out-of-process compilation will be stored in AOT cache. + * + * The AOT cache method record is looked up in the client session or created + * on demand, possibly requesting missing information from the client. + * + * @param method the RAMMethod that the ROMMethod SCC offset is for + * @param definingClass RAMClass for the defining class of the method + * @param romMethodOffsetAddr pointer to the binary relocation record field that stores the ROMMethod SCC offset + */ + void addMethodSerializationRecord(J9Method *method, TR_OpaqueClassBlock *definingClass, const uintptr_t *romMethodOffsetAddr); + + /** + * @brief Adds an AOT cache class chain record corresponding to a class chain SCC + * offset if this out-of-process compilation will be stored in AOT cache. + * + * @param classChainRecord pointer to the AOT cache class chain record + * @param classChainOffsetAddr pointer to the binary relocation record field that stores the class chain SCC offset + */ + void addClassChainSerializationRecord(const AOTCacheClassChainRecord *classChainRecord, const uintptr_t *classChainOffsetAddr); + + /** + * @brief Adds an AOT cache class loader record corresponding to a class chain SCC offset identifying + * a class loader if this out-of-process compilation will be stored in AOT cache. + * + * The resulting AOT cache class loader record is the class loader record of the root class of the class chain. + * Note that while the AOT cache class chain record passed to this method is the one for the class being + * remembered, i.e. the same as the one passed to addClassChainSerializationRecord(), the AOT cache record + * associated with this SCC offset is the one identifying the class loader of the class being remembered. + * The JITServer AOT cache identifies class loaders by the name of the first loaded class (not by its class + * chain), hence the AOT cache class loader records are a distinct type from the class chain records. + * + * @param classChainRecord pointer to the AOT cache class chain record for the class + * whose loader is identified by the class chain SCC offset + * @param loaderChainOffsetAddr pointer to the binary relocation record field that stores + * the class chain SCC offset identifying the class loader + */ + void addClassLoaderSerializationRecord(const AOTCacheClassChainRecord *classChainRecord, const uintptr_t *loaderChainOffsetAddr); + + /** + * @brief Adds an AOT cache well-known classes record corresponding to a well-known classes + * SCC offset if this out-of-process compilation will be stored in AOT cache. + * + * @param wkcRecord pointer to the AOT cache well-known classes record + * @param wkcOffsetAddr pointer to the binary relocation record field that stores the well-known classes SCC offset + */ + void addWellKnownClassesSerializationRecord(const AOTCacheWellKnownClassesRecord *wkcRecord, const uintptr_t *wkcOffsetAddr); +#endif /* defined(J9VM_OPT_JITSERVER) */ + void dumpRelocationData(); uint8_t* dumpRelocationHeaderData(uint8_t *cursor, bool isVerbose); @@ -89,7 +178,20 @@ class OMR_EXTENSIBLE AheadOfTimeCompile : public OMR::AheadOfTimeCompileConnecto */ static bool classAddressUsesReloRecordInfo() { return false; } - protected: +protected: + +#if defined(J9VM_OPT_JITSERVER) + /** + * @brief Associates an AOT cache record with the corresponding SCC offset stored in AOT relocation data. + * + * If this is an out-of-process compilation that will be stored in JITServer AOT cache, computes the offset into + * AOT relocation data and calls Compilation::addSerializationRecord(record, offset), otherwise does nothing. + * + * @param record pointer to the AOT cache record to be added to this compilation + * @param sccOffsetAddr pointer to the binary relocation record field that stores the SCC offset + */ + void addSerializationRecord(const AOTCacheRecord *record, const uintptr_t *sccOffsetAddr); +#endif /* defined(J9VM_OPT_JITSERVER) */ /** * @brief TR_J9SharedCache::offsetInSharedCacheFrom* asserts if the pointer diff --git a/runtime/compiler/compile/J9Compilation.cpp b/runtime/compiler/compile/J9Compilation.cpp index 5958778e570..bd864565f09 100644 --- a/runtime/compiler/compile/J9Compilation.cpp +++ b/runtime/compiler/compile/J9Compilation.cpp @@ -192,10 +192,12 @@ J9::Compilation::Compilation(int32_t id, _remoteCompilation(false), _serializedRuntimeAssumptions(getTypedAllocator(self()->allocator())), _clientData(NULL), + _stream(NULL), _globalMemory(*::trPersistentMemory, heapMemoryRegion), _perClientMemory(_trMemory), _methodsRequiringTrampolines(getTypedAllocator(self()->allocator())), _aotCacheStore(false), + _serializationRecords(decltype(_serializationRecords)::allocator_type(heapMemoryRegion)), #endif /* defined(J9VM_OPT_JITSERVER) */ _osrProhibitedOverRangeOfTrees(false) { @@ -1562,3 +1564,14 @@ J9::Compilation::incompleteOptimizerSupportForReadWriteBarriers() return self()->getOption(TR_EnableFieldWatch); } +#if defined(J9VM_OPT_JITSERVER) +void +J9::Compilation::addSerializationRecord(const AOTCacheRecord *record, uintptr_t reloDataOffset) + { + TR_ASSERT_FATAL(_aotCacheStore, "Trying to add serialization record for compilation that is not an AOT cache store"); + if (record) + _serializationRecords.push_back({ record, reloDataOffset }); + else + _aotCacheStore = false;// Serialization failed; method won't be stored in AOT cache + } +#endif /* defined(J9VM_OPT_JITSERVER) */ diff --git a/runtime/compiler/compile/J9Compilation.hpp b/runtime/compiler/compile/J9Compilation.hpp index f347e16d28a..5f02103adaa 100644 --- a/runtime/compiler/compile/J9Compilation.hpp +++ b/runtime/compiler/compile/J9Compilation.hpp @@ -42,6 +42,10 @@ namespace J9 { typedef J9::Compilation CompilationConnector; } #include "env/OMRMemory.hpp" #include "compile/AOTClassInfo.hpp" #include "runtime/SymbolValidationManager.hpp" +#if defined(J9VM_OPT_JITSERVER) +#include "env/PersistentCollections.hpp" +#endif /* defined(J9VM_OPT_JITSERVER) */ + class TR_AOTGuardSite; class TR_FrontEnd; @@ -59,7 +63,8 @@ namespace TR { class IlGenRequest; } #ifdef J9VM_OPT_JITSERVER struct SerializedRuntimeAssumption; class ClientSessionData; -#endif +class AOTCacheRecord; +#endif /* defined(J9VM_OPT_JITSERVER) */ #define COMPILATION_AOT_HAS_INVOKEHANDLE -9 #define COMPILATION_RESERVE_RESOLVED_TRAMPOLINE_FATAL_ERROR -10 @@ -75,7 +80,6 @@ class ClientSessionData; #define COMPILATION_AOT_RELOCATION_FAILED -20 - namespace J9 { @@ -327,24 +331,31 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector #if defined(J9VM_OPT_JITSERVER) static bool isOutOfProcessCompilation() { return _outOfProcessCompilation; } // server side static void setOutOfProcessCompilation() { _outOfProcessCompilation = true; } + bool isRemoteCompilation() const { return _remoteCompilation; } // client side void setRemoteCompilation() { _remoteCompilation = true; } - TR::list& getSerializedRuntimeAssumptions() { return _serializedRuntimeAssumptions; } + + TR::list &getSerializedRuntimeAssumptions() { return _serializedRuntimeAssumptions; } + ClientSessionData *getClientData() const { return _clientData; } void setClientData(ClientSessionData *clientData) { _clientData = clientData; } - void switchToPerClientMemory() - { - _trMemory = _perClientMemory; - } - void switchToGlobalMemory() - { - _trMemory = &_globalMemory; - } - TR::list& getMethodsRequiringTrampolines() { return _methodsRequiringTrampolines; } + JITServer::ServerStream *getStream() const { return _stream; } + void setStream(JITServer::ServerStream *stream) { _stream = stream; } + + void switchToPerClientMemory() { _trMemory = _perClientMemory; } + void switchToGlobalMemory() { _trMemory = &_globalMemory; } + + TR::list &getMethodsRequiringTrampolines() { return _methodsRequiringTrampolines; } bool isAOTCacheStore() const { return _aotCacheStore; } void setAOTCacheStore(bool store) { _aotCacheStore = store; } + + Vector> &getSerializationRecords() { return _serializationRecords; } + // Adds an AOT cache record and the corresponding offset into AOT relocation data to the list that + // will be used when the result of this out-of-process compilation is serialized and stored in + // JITServer AOT cache. If record is NULL, fails serialization by setting _aotCacheStore to false. + void addSerializationRecord(const AOTCacheRecord *record, uintptr_t reloDataOffset); #endif /* defined(J9VM_OPT_JITSERVER) */ TR::SymbolValidationManager *getSymbolValidationManager() { return _symbolValidationManager; } @@ -439,7 +450,7 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector #if defined(J9VM_OPT_JITSERVER) // This list contains assumptions created during the compilation at the JITServer // It needs to be sent to the client at the end of compilation - TR::list _serializedRuntimeAssumptions; + TR::list _serializedRuntimeAssumptions; // The following flag is set when this compilation is performed in a // VM that does not have the runtime part (server side in JITServer) static bool _outOfProcessCompilation; @@ -449,6 +460,8 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector // Client session data for the client that requested this out-of-process // compilation (at the JITServer); unused (always NULL) at the client side ClientSessionData *_clientData; + // Server stream used by this out-of-process compilation; always NULL at the client + JITServer::ServerStream *_stream; TR_Memory *_perClientMemory; TR_Memory _globalMemory; @@ -461,6 +474,9 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector // True if the result of this out-of-process compilation will be // stored in JITServer AOT cache; always false at the client bool _aotCacheStore; + // List of AOT cache records and corresponding offsets into AOT relocation data that will + // be used to store the result of this compilation in AOT cache; always empty at the client + Vector> _serializationRecords; #endif /* defined(J9VM_OPT_JITSERVER) */ TR::SymbolValidationManager *_symbolValidationManager; diff --git a/runtime/compiler/control/CompilationThread.cpp b/runtime/compiler/control/CompilationThread.cpp index 72d5845c089..13b63871df8 100644 --- a/runtime/compiler/control/CompilationThread.cpp +++ b/runtime/compiler/control/CompilationThread.cpp @@ -1167,6 +1167,7 @@ TR::CompilationInfo::CompilationInfo(J9JITConfig *jitConfig) : _activationPolicy = JITServer::CompThreadActivationPolicy::AGGRESSIVE; _sharedROMClassCache = NULL; _JITServerAOTCacheMap = NULL; + _JITServerAOTDeserializer = NULL; #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -8567,6 +8568,9 @@ TR::CompilationInfoPerThreadBase::wrappedCompile(J9PortLibrary *portLib, void * // Create the KOT by default at the server as long as it is not disabled at the client. compiler->getOrCreateKnownObjectTable(); compiler->setClientData(that->getClientData()); + compiler->setStream(that->_methodBeingCompiled->_stream); + auto compInfoPTRemote = static_cast(that); + compiler->setAOTCacheStore(compInfoPTRemote->isAOTCacheStore()); } #endif /* defined(J9VM_OPT_JITSERVER) */ diff --git a/runtime/compiler/control/JITClientCompilationThread.cpp b/runtime/compiler/control/JITClientCompilationThread.cpp index be928daeff7..a9ac0ab465d 100644 --- a/runtime/compiler/control/JITClientCompilationThread.cpp +++ b/runtime/compiler/control/JITClientCompilationThread.cpp @@ -2117,8 +2117,9 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes std::vector uncachedClassInfos; if (create && getClasses && classChain) { - uintptr_t len = classChain[0] / sizeof(classChain[0]) - 1; - ramClassChain = JITServerHelpers::getRAMClassChain(clazz, len, vmThread, trMemory, compInfo, + // The first word of the class chain data stores the size of the whole record in bytes + uintptr_t numClasses = classChain[0] / sizeof(classChain[0]) - 1; + ramClassChain = JITServerHelpers::getRAMClassChain(clazz, numClasses, vmThread, trMemory, compInfo, uncachedRAMClasses, uncachedClassInfos); } client->write(response, classChain, ramClassChain, uncachedRAMClasses, uncachedClassInfos); @@ -3043,14 +3044,8 @@ updateCompThreadActivationPolicy(TR::CompilationInfoPerThreadBase *compInfoPT, J } TR_MethodMetaData * -remoteCompile( - J9VMThread * vmThread, - TR::Compilation * compiler, - TR_ResolvedMethod * compilee, - J9Method * method, - TR::IlGeneratorMethodDetails &details, - TR::CompilationInfoPerThreadBase *compInfoPT - ) +remoteCompile(J9VMThread *vmThread, TR::Compilation *compiler, TR_ResolvedMethod *compilee, J9Method *method, + TR::IlGeneratorMethodDetails &details, TR::CompilationInfoPerThreadBase *compInfoPT) { TR_ASSERT(vmThread->publicFlags & J9_PUBLIC_FLAGS_VM_ACCESS, "Client must work with VM access"); // JITServer: if TR_EnableJITServerPerCompConn is set, then each remote compilation establishes a new connection @@ -3061,29 +3056,29 @@ remoteCompile( J9Class *clazz = J9_CLASS_FROM_METHOD(method); J9ROMClass *romClass = clazz->romClass; J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method); - uint32_t romMethodOffset = uint32_t((uint8_t*) romMethod - (uint8_t*) romClass); - std::string detailsStr = std::string((char*) &details, sizeof(TR::IlGeneratorMethodDetails)); + std::string detailsStr((const char *)&details, sizeof(details)); TR::CompilationInfo *compInfo = compInfoPT->getCompilationInfo(); - bool useAotCompilation = compInfoPT->getMethodBeingCompiled()->_useAotCompilation; + TR_MethodToBeCompiled *entry = compInfoPT->getMethodBeingCompiled(); + TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo(); + bool useAotCompilation = entry->_useAotCompilation; + bool aotCacheStore = useAotCompilation && persistentInfo->getJITServerUseAOTCache(); // For JitDump recompilations need to use the same stream as for the original compile - JITServer::ClientStream *client = - enableJITServerPerCompConn && !details.isJitDumpMethod() ? - NULL - : compInfoPT->getClientStream(); + JITServer::ClientStream *client = (enableJITServerPerCompConn && !details.isJitDumpMethod()) ? NULL + : compInfoPT->getClientStream(); if (!client) { try { if (JITServerHelpers::isServerAvailable()) { - client = new (PERSISTENT_NEW) JITServer::ClientStream(compInfo->getPersistentInfo()); + client = new (PERSISTENT_NEW) JITServer::ClientStream(persistentInfo); if (!enableJITServerPerCompConn) compInfoPT->setClientStream(client); } else if (JITServerHelpers::shouldRetryConnection(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary))) { - client = new (PERSISTENT_NEW) JITServer::ClientStream(compInfo->getPersistentInfo()); + client = new (PERSISTENT_NEW) JITServer::ClientStream(persistentInfo); if (!enableJITServerPerCompConn) compInfoPT->setClientStream(client); JITServerHelpers::postStreamConnectionSuccess(); @@ -3137,45 +3132,70 @@ remoteCompile( serializeClass = compInfo->getclassesCachedAtServer().insert(clazz).second; } - auto classInfoTuple = JITServerHelpers::packRemoteROMClassInfo(clazz, compiler->fej9vm()->vmThread(), compiler->trMemory(), serializeClass); + auto classInfoTuple = JITServerHelpers::packRemoteROMClassInfo(clazz, compiler->fej9vm()->vmThread(), + compiler->trMemory(), serializeClass); std::string optionsStr = TR::Options::packOptions(compiler->getOptions()); - std::string recompMethodInfoStr = compiler->isRecompilationEnabled() ? std::string((char *) compiler->getRecompilationInfo()->getMethodInfo(), sizeof(TR_PersistentMethodInfo)) : std::string(); + std::string recompMethodInfoStr = compiler->isRecompilationEnabled() + ? std::string((const char *)compiler->getRecompilationInfo()->getMethodInfo(), sizeof(TR_PersistentMethodInfo)) + : std::string(); + + uintptr_t *classChain = NULL; + std::vector ramClassChain; + std::vector uncachedRAMClasses; + std::vector uncachedClassInfos; + if (aotCacheStore) + { + classChain = compiler->fej9vm()->sharedCache()->rememberClass(clazz); + if (classChain) + { + // The first word of the class chain data stores the size of the whole record in bytes + uintptr_t numClasses = classChain[0] / sizeof(classChain[0]) - 1; + ramClassChain = JITServerHelpers::getRAMClassChain(clazz, numClasses, vmThread, compiler->trMemory(), + compInfo, uncachedRAMClasses, uncachedClassInfos); + } + else if (TR::Options::getVerboseOption(TR_VerboseJITServer)) + { + TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "ERROR: Failed to get defining class chain for method %s", + compiler->signature()); + aotCacheStore = false; + } + } // TODO: make this a synchronized region to avoid bad_alloc exceptions compInfo->getSequencingMonitor()->enter(); // Collect the list of unloaded classes - std::vector unloadedClasses(compInfo->getUnloadedClassesTempList()->begin(), compInfo->getUnloadedClassesTempList()->end()); + std::vector unloadedClasses(compInfo->getUnloadedClassesTempList()->begin(), + compInfo->getUnloadedClassesTempList()->end()); compInfo->getUnloadedClassesTempList()->clear(); - std::vector illegalModificationList(compInfo->getIllegalFinalFieldModificationList()->begin(), - compInfo->getIllegalFinalFieldModificationList()->end()); + std::vector illegalModificationList(compInfo->getIllegalFinalFieldModificationList()->begin(), + compInfo->getIllegalFinalFieldModificationList()->end()); compInfo->getIllegalFinalFieldModificationList()->clear(); // Collect and encode the CHTable updates; this will acquire CHTable mutex - auto table = (JITClientPersistentCHTable*)compInfo->getPersistentInfo()->getPersistentCHTable(); - std::pair chtableUpdates = table->serializeUpdates(); + auto chTable = (JITClientPersistentCHTable *)persistentInfo->getPersistentCHTable(); + std::pair chtableUpdates = chTable->serializeUpdates(); // Update the sequence number for these updates uint32_t seqNo = compInfo->incCompReqSeqNo(); uint32_t lastCriticalSeqNo = !details.isJitDumpMethod() ? compInfo->getLastCriticalSeqNo() : 0; // If needed, update the seqNo of the last request that carried information that needed to be processed in order - if (!chtableUpdates.first.empty() - || !chtableUpdates.second.empty() - || !illegalModificationList.empty() - || !unloadedClasses.empty() - || details.isJitDumpMethod()) + if (!chtableUpdates.first.empty() || !chtableUpdates.second.empty() || + !illegalModificationList.empty() || !unloadedClasses.empty() || details.isJitDumpMethod()) + { compInfo->setLastCriticalSeqNo(seqNo); - + } compInfo->getSequencingMonitor()->exit(); uint32_t statusCode = compilationFailure; std::string codeCacheStr; std::string dataCacheStr; CHTableCommitData chTableData; - std::vector classesThatShouldNotBeNewlyExtended; + std::vector classesThatShouldNotBeNewlyExtended; std::string logFileStr; std::string svmSymbolToIdStr; - std::vector resolvedMirrorMethodsPersistIPInfo; + std::vector resolvedMirrorMethodsPersistIPInfo; TR_OptimizationPlan modifiedOptPlan; std::vector serializedRuntimeAssumptions; std::vector methodsRequiringTrampolines; + uint32_t methodIndex = (uint32_t)(method - clazz->ramMethods);// Index in the array of methods of the defining class try { // Release VM access just before sending the compilation request @@ -3191,12 +3211,16 @@ remoteCompile( Trc_JITServerRemoteCompileRequest(vmThread, seqNo, compiler->signature(), compiler->getHotnessName()); - client->buildCompileRequest(compiler->getPersistentInfo()->getClientUID(), seqNo, lastCriticalSeqNo, romMethodOffset, method, - clazz, *compInfoPT->getMethodBeingCompiled()->_optimizationPlan, detailsStr, - details.getType(), unloadedClasses, illegalModificationList, classInfoTuple, optionsStr, recompMethodInfoStr, - chtableUpdates.first, chtableUpdates.second, useAotCompilation, TR::Compiler->vm.isVMInStartupPhase(compInfoPT->getJitConfig())); + client->buildCompileRequest( + persistentInfo->getClientUID(), seqNo, lastCriticalSeqNo, method, clazz, *entry->_optimizationPlan, + detailsStr, details.getType(), unloadedClasses, illegalModificationList, classInfoTuple, optionsStr, + recompMethodInfoStr, chtableUpdates.first, chtableUpdates.second, useAotCompilation, + TR::Compiler->vm.isVMInStartupPhase(compInfoPT->getJitConfig()), methodIndex, + classChain, ramClassChain, uncachedRAMClasses, uncachedClassInfos + ); + JITServer::MessageType response; - while(!handleServerMessage(client, compiler->fej9vm(), response)); + while (!handleServerMessage(client, compiler->fej9vm(), response)); // Re-acquire VM access // handleServerMessage will always acquire VM access after read() and release VM access at the end @@ -3205,10 +3229,11 @@ remoteCompile( if (JITServer::MessageType::compilationCode == response) { - auto recv = client->getRecvData, - std::string, std::string, std::vector, - TR_OptimizationPlan, std::vector, JITServer::ServerMemoryState, - JITServer::ServerActiveThreadsState, std::vector>(); + auto recv = client->getRecvData< + std::string, std::string, CHTableCommitData, std::vector, std::string, std::string, + std::vector, TR_OptimizationPlan, std::vector, + JITServer::ServerMemoryState, JITServer::ServerActiveThreadsState, std::vector + >(); statusCode = compilationOK; codeCacheStr = std::get<0>(recv); dataCacheStr = std::get<1>(recv); @@ -3219,10 +3244,10 @@ remoteCompile( resolvedMirrorMethodsPersistIPInfo = std::get<6>(recv); modifiedOptPlan = std::get<7>(recv); serializedRuntimeAssumptions = std::get<8>(recv); - methodsRequiringTrampolines = std::get<11>(recv); - JITServer::ServerMemoryState nextMemoryState = std::get<9>(recv); JITServer::ServerActiveThreadsState nextActiveThreadState = std::get<10>(recv); + methodsRequiringTrampolines = std::get<11>(recv); + updateCompThreadActivationPolicy(compInfoPT, nextMemoryState, nextActiveThreadState); } else if (JITServer::MessageType::jitDumpPrintIL == response) @@ -3243,14 +3268,15 @@ remoteCompile( TR::CompilationInfoPerThreadBase::UninterruptibleOperation uop(*compInfoPT); releaseVMAccess(vmThread); - while(!handleServerMessage(client, compiler->fej9vm(), response)); + while (!handleServerMessage(client, compiler->fej9vm(), response)); acquireVMAccessNoSuspend(vmThread); TR_ASSERT_FATAL( - response == JITServer::MessageType::compilationThreadCrashed - || response == JITServer::MessageType::compilationFailure, - "Expected JITServer::MessageType::compilationThreadCrashed or JITServer::MessageType::compilationFailure but received %s\n", - JITServer::messageNames[response]); + (response == JITServer::MessageType::compilationThreadCrashed) || + (response == JITServer::MessageType::compilationFailure), + "Expected compilationThreadCrashed or compilationFailure but received %s\n", + JITServer::messageNames[response] + ); if (response == JITServer::MessageType::compilationThreadCrashed) { @@ -3265,7 +3291,7 @@ remoteCompile( // is set to NULL, because the original compile hasn't ended from the client's point of view // so options haven't changed. J9::JitDumpMethodDetails jitDumpDetails(method, NULL, useAotCompilation); - compInfoPT->getMethodBeingCompiled()->_optimizationPlan->setLogCompilation(jitdumpFile); + entry->_optimizationPlan->setLogCompilation(jitdumpFile); if (writeVerboseLog) TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, @@ -3294,7 +3320,7 @@ remoteCompile( // Since server has crashed, all compilations will switch to local JITServerHelpers::postStreamFailure(OMRPORT_FROM_J9PORT(compInfoPT->getJitConfig()->javaVM->portLibrary), compInfo); - compInfoPT->getMethodBeingCompiled()->_compErrCode = compilationFailure; + entry->_compErrCode = compilationFailure; compiler->failCompilation("JITServer compilation thread has crashed."); } else @@ -3417,7 +3443,7 @@ remoteCompile( TR_ASSERT(codeCacheStr.size(), "must have code cache"); TR_ASSERT(dataCacheStr.size(), "must have data cache"); - compInfoPT->getMethodBeingCompiled()->_optimizationPlan->clone(&modifiedOptPlan); + entry->_optimizationPlan->clone(&modifiedOptPlan); // Relocate the received compiled code metaData = remoteCompilationEnd(vmThread, compiler, compilee, method, compInfoPT, codeCacheStr, dataCacheStr); @@ -3488,10 +3514,9 @@ remoteCompile( if (!JITClientCHTableCommit(compiler, metaData, chTableData)) { -#ifdef COLLECT_CHTABLE_STATS - JITClientPersistentCHTable *table = (JITClientPersistentCHTable*) TR::comp()->getPersistentInfo()->getPersistentCHTable(); - table->_numCommitFailures += 1; -#endif +#if defined(COLLECT_CHTABLE_STATS) + chTable->_numCommitFailures += 1; +#endif /* COLLECT_CHTABLE_STATS */ if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompileEnd, TR_VerbosePerformance, TR_VerboseCompFailure)) { TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, "JITClient: Failure while committing chtable for %s", compiler->signature()); @@ -3501,7 +3526,6 @@ remoteCompile( } } - TR_ASSERT(!metaData || !metaData->startColdPC, "coldPC should be null"); // As a debugging feature, a local compilation can be performed immediately after a remote compilation. // Each of them has logs with the same compilationSequenceNumber @@ -3551,7 +3575,7 @@ remoteCompile( } else { - compInfoPT->getMethodBeingCompiled()->_compErrCode = statusCode; + entry->_compErrCode = statusCode; if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch)) TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE, diff --git a/runtime/compiler/control/JITServerCompilationThread.cpp b/runtime/compiler/control/JITServerCompilationThread.cpp index c7d8113709a..cc10a2d7281 100644 --- a/runtime/compiler/control/JITServerCompilationThread.cpp +++ b/runtime/compiler/control/JITServerCompilationThread.cpp @@ -110,33 +110,28 @@ computeServerActiveThreadsState(TR::CompilationInfo *compInfo) * @brief Method executed by JITServer to process the end of a compilation. */ void -outOfProcessCompilationEnd( - TR_MethodToBeCompiled *entry, - TR::Compilation *comp) +outOfProcessCompilationEnd(TR_MethodToBeCompiled *entry, TR::Compilation *comp) { entry->_tryCompilingAgain = false; // TODO: Need to handle recompilations gracefully when relocation fails - auto compInfoPT = ((TR::CompilationInfoPerThreadRemote*)(entry->_compInfoPT)); + auto compInfoPT = (TR::CompilationInfoPerThreadRemote *)entry->_compInfoPT; TR::CodeCache *codeCache = comp->cg()->getCodeCache(); TR_ASSERT(comp->getAotMethodDataStart(), "The header must have been set"); - TR_AOTMethodHeader *aotMethodHeaderEntry = comp->getAotMethodHeaderEntry(); + TR_AOTMethodHeader *aotMethodHeaderEntry = comp->getAotMethodHeaderEntry(); - U_8 *codeStart = (U_8 *)aotMethodHeaderEntry->compileMethodCodeStartPC; - OMR::CodeCacheMethodHeader *codeCacheHeader = (OMR::CodeCacheMethodHeader*)codeStart; + uint8_t *codeStart = (uint8_t *)aotMethodHeaderEntry->compileMethodCodeStartPC; + OMR::CodeCacheMethodHeader *codeCacheHeader = (OMR::CodeCacheMethodHeader *)codeStart; - TR_DataCache *dataCache = (TR_DataCache*)comp->getReservedDataCache(); - TR_ASSERT(dataCache, "A dataCache must be reserved for JITServer compilations\n"); + TR_DataCache *dataCache = (TR_DataCache *)comp->getReservedDataCache(); + TR_ASSERT(dataCache, "A dataCache must be reserved for JITServer compilations"); J9JITDataCacheHeader *dataCacheHeader = (J9JITDataCacheHeader *)comp->getAotMethodDataStart(); - J9JITExceptionTable *metaData = compInfoPT->getMetadata(); - size_t codeSize = codeCache->getWarmCodeAlloc() - (uint8_t*)codeCacheHeader; - size_t dataSize = dataCache->getSegment()->heapAlloc - (uint8_t*)dataCacheHeader; + size_t codeSize = codeCache->getWarmCodeAlloc() - (uint8_t *)codeCacheHeader; + size_t dataSize = dataCache->getSegment()->heapAlloc - (uint8_t *)dataCacheHeader; - //TR_ASSERT(((OMR::RuntimeAssumption*)metaData->runtimeAssumptionList)->getNextAssumptionForSameJittedBody() == metaData->runtimeAssumptionList, "assuming no assumptions"); - - std::string codeCacheStr((char*) codeCacheHeader, codeSize); - std::string dataCacheStr((char*) dataCacheHeader, dataSize); + std::string codeCacheStr((const char *)codeCacheHeader, codeSize); + std::string dataCacheStr((const char *)dataCacheHeader, dataSize); CHTableCommitData chTableData; if (!comp->getOption(TR_DisableCHOpts) && !entry->_useAotCompilation) @@ -183,15 +178,15 @@ outOfProcessCompilationEnd( } } - entry->_stream->finishCompilation(codeCacheStr, dataCacheStr, chTableData, - std::vector(classesThatShouldNotBeNewlyExtended->begin(), classesThatShouldNotBeNewlyExtended->end()), - logFileStr, svmSymbolToIdStr, - (resolvedMirrorMethodsPersistIPInfo) ? - std::vector(resolvedMirrorMethodsPersistIPInfo->begin(), resolvedMirrorMethodsPersistIPInfo->end()) : - std::vector(), - *entry->_optimizationPlan, serializedRuntimeAssumptions, memoryState, - activeThreadState, methodsRequiringTrampolines - ); + entry->_stream->finishCompilation( + codeCacheStr, dataCacheStr, chTableData, + std::vector(classesThatShouldNotBeNewlyExtended->begin(), classesThatShouldNotBeNewlyExtended->end()), + logFileStr, svmSymbolToIdStr, + resolvedMirrorMethodsPersistIPInfo + ? std::vector(resolvedMirrorMethodsPersistIPInfo->begin(), resolvedMirrorMethodsPersistIPInfo->end()) + : std::vector(), + *entry->_optimizationPlan, serializedRuntimeAssumptions, memoryState, activeThreadState, methodsRequiringTrampolines + ); compInfoPT->clearPerCompilationCaches(); if (TR::Options::getVerboseOption(TR_VerboseJITServer)) @@ -202,6 +197,23 @@ outOfProcessCompilationEnd( Trc_JITServerCompileEnd(compInfoPT->getCompilationThread(), compInfoPT->getCompThreadId(), compInfoPT->getCompilation()->signature(), compInfoPT->getCompilation()->getHotnessName()); + + if (compInfoPT->isAOTCacheStore()) + { + if (comp->isAOTCacheStore()) + { + auto clientData = comp->getClientData(); + auto cache = clientData->getAOTCache(); + cache->storeMethod(compInfoPT->getDefiningClassChainRecord(), compInfoPT->getMethodIndex(), + entry->_optimizationPlan->getOptLevel(), clientData->getAOTHeaderRecord(), + comp->getSerializationRecords(), codeCacheHeader, codeSize, + dataCacheHeader, dataSize, comp->signature(), clientData->getClientUID()); + } + else if (TR::Options::getVerboseOption(TR_VerboseJITServer)) + { + TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Failed to serialize AOT method %s", comp->signature()); + } + } } TR::CompilationInfoPerThreadRemote::CompilationInfoPerThreadRemote(TR::CompilationInfo &compInfo, J9JITConfig *jitConfig, int32_t id, bool isDiagnosticThread) @@ -218,7 +230,10 @@ TR::CompilationInfoPerThreadRemote::CompilationInfoPerThreadRemote(TR::Compilati _fieldAttributesCache(NULL), _staticAttributesCache(NULL), _isUnresolvedStrCache(NULL), - _classUnloadReadMutexDepth(0) + _classUnloadReadMutexDepth(0), + _aotCacheStore(false), + _methodIndex((uint32_t)-1), + _definingClassChainRecord(NULL) {} /** @@ -403,7 +418,7 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J // Release compMonitor before doing the blocking read compInfo->releaseCompMonitor(compThread); - char * clientOptions = NULL; + char *clientOptions = NULL; TR_OptimizationPlan *optPlan = NULL; _vm = NULL; bool useAotCompilation = false; @@ -419,35 +434,50 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J // hasIncNumActiveThreads is used to determine if decNumActiveThreads() should be // called when an exception is thrown. bool hasIncNumActiveThreads = false; + // Keep track of whether the lastProcessedCriticalSeqNo in the client session was updated + bool hasUpdatedSeqNo = false; + + _aotCacheStore = false; + _methodIndex = (uint32_t)-1; + _definingClassChainRecord = NULL; + try { - auto req = stream->readCompileRequest, std::vector, - JITServerHelpers::ClassInfoTuple, std::string, std::string, std::string, std::string, bool, bool>(); - - clientId = std::get<0>(req); - seqNo = std::get<1>(req); // Sequence number at the client - uint32_t criticalSeqNo = std::get<2>(req); // Sequence number of the request this request depends upon - uint32_t romMethodOffset = std::get<3>(req); - J9Method *ramMethod = std::get<4>(req); - J9Class *clazz = std::get<5>(req); - TR_OptimizationPlan clientOptPlan = std::get<6>(req); - std::string detailsStr = std::get<7>(req); - auto detailsType = std::get<8>(req); - auto &unloadedClasses = std::get<9>(req); - auto &illegalModificationList = std::get<10>(req); - auto &classInfoTuple = std::get<11>(req); - std::string clientOptStr = std::get<12>(req); - std::string recompInfoStr = std::get<13>(req); - const std::string &chtableUnloads = std::get<14>(req); - const std::string &chtableMods = std::get<15>(req); - useAotCompilation = std::get<16>(req); - - TR_ASSERT_FATAL(TR::Compiler->persistentMemory() == compInfo->persistentMemory(), "per-client persistent memory must not be set at this point"); + auto req = stream->readCompileRequest< + uint64_t, uint32_t, uint32_t, J9Method *, J9Class *, TR_OptimizationPlan, std::string, + J9::IlGeneratorMethodDetailsType, std::vector, std::vector, + JITServerHelpers::ClassInfoTuple, std::string, std::string, std::string, std::string, bool, bool, uint32_t, + uintptr_t *, std::vector, std::vector, std::vector + >(); + + clientId = std::get<0>(req); + seqNo = std::get<1>(req); // Sequence number at the client + uint32_t criticalSeqNo = std::get<2>(req); // Sequence number of the request this request depends upon + J9Method *ramMethod = std::get<3>(req); + J9Class *clazz = std::get<4>(req); + auto &clientOptPlan = std::get<5>(req); + auto &detailsStr = std::get<6>(req); + auto detailsType = std::get<7>(req); + auto &unloadedClasses = std::get<8>(req); + auto &illegalModificationList = std::get<9>(req); + auto &classInfoTuple = std::get<10>(req); + auto &clientOptStr = std::get<11>(req); + auto &recompInfoStr = std::get<12>(req); + auto &chtableUnloads = std::get<13>(req); + auto &chtableMods = std::get<14>(req); + useAotCompilation = std::get<15>(req); + bool isInStartupPhase = std::get<16>(req); + _methodIndex = std::get<17>(req); + uintptr_t *classChain = std::get<18>(req); + auto &ramClassChain = std::get<19>(req); + auto &uncachedRAMClasses = std::get<20>(req); + auto &uncachedClassInfos = std::get<21>(req); + + TR_ASSERT_FATAL(TR::Compiler->persistentMemory() == compInfo->persistentMemory(), + "per-client persistent memory must not be set at this point"); TR::IlGeneratorMethodDetails *clientDetails = (TR::IlGeneratorMethodDetails*) &detailsStr[0]; - *(uintptr_t*)clientDetails = 0; // smash remote vtable pointer to catch bugs early + *(uintptr_t *)clientDetails = 0; // smash remote vtable pointer to catch bugs early TR::IlGeneratorMethodDetails serverDetailsStorage; TR::IlGeneratorMethodDetails *serverDetails = TR::IlGeneratorMethodDetails::clone(serverDetailsStorage, *clientDetails, detailsType); @@ -481,23 +511,24 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J setExpectedSeqNo(criticalSeqNo); // Memorize the message I have to wait for bool sessionDataWasEmpty = false; - { - // Get a pointer to this client's session data - // Obtain monitor RAII style because creating a new hastable entry may throw bad_alloc - OMR::CriticalSection compilationMonitorLock(compInfo->getCompilationMonitor()); - compInfo->getClientSessionHT()->purgeOldDataIfNeeded(); // Try to purge old data - if (!(clientSession = compInfo->getClientSessionHT()->findOrCreateClientSession(clientId, criticalSeqNo, &sessionDataWasEmpty, _jitConfig))) - throw std::bad_alloc(); + { + // Get a pointer to this client's session data + // Obtain monitor RAII style because creating a new hastable entry may throw bad_alloc + OMR::CriticalSection compilationMonitorLock(compInfo->getCompilationMonitor()); + compInfo->getClientSessionHT()->purgeOldDataIfNeeded(); // Try to purge old data + if (!(clientSession = compInfo->getClientSessionHT()->findOrCreateClientSession(clientId, criticalSeqNo, &sessionDataWasEmpty, _jitConfig))) + throw std::bad_alloc(); - setClientData(clientSession); // Cache the session data into CompilationInfoPerThreadRemote object + setClientData(clientSession); // Cache the session data into CompilationInfoPerThreadRemote object - // After this line, all persistent allocations are made per-client, - // until exitPerClientAllocationRegion is called - enterPerClientAllocationRegion(); - TR_ASSERT(!clientSession->usesPerClientMemory() || TR::Compiler->persistentMemory() != compInfo->persistentMemory(), "per-client persistent memory must be set at this point"); + // After this line, all persistent allocations are made per-client, + // until exitPerClientAllocationRegion is called + enterPerClientAllocationRegion(); + TR_ASSERT(!clientSession->usesPerClientMemory() || (TR::Compiler->persistentMemory() != compInfo->persistentMemory()), + "per-client persistent memory must be set at this point"); - clientSession->setIsInStartupPhase(std::get<17>(req)); - } // End critical section + clientSession->setIsInStartupPhase(isInStartupPhase); + } // End critical section if (TR::Options::getVerboseOption(TR_VerboseJITServer)) TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "compThreadID=%d %s clientSessionData=%p for clientUID=%llu seqNo=%u (isCritical=%d) (criticalSeqNo=%u lastProcessedCriticalReq=%u)", @@ -636,7 +667,6 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J } } - // Critical requests must update lastProcessedCriticalSeqNo and notify any waiting threads. // Dependent threads will pass through once we've released the sequencing monitor. if (isCriticalRequest) @@ -648,6 +678,7 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J clientSession->getLastProcessedCriticalSeqNo(), clientSession->getNumActiveThreads()); clientSession->setLastProcessedCriticalSeqNo(seqNo); + hasUpdatedSeqNo = true; Trc_JITServerUpdateSeqNo(getCompilationThread(), getCompThreadId(), clientSession, (unsigned long long)clientSession->getClientUID(), getSeqNo(), criticalSeqNo, clientSession->getNumActiveThreads(), @@ -662,7 +693,6 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J clientSession->getSequencingMonitor()->exit(); } - // Copy the option string copyClientOptions(clientOptStr, clientSession->persistentMemory()); @@ -700,8 +730,6 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J TR_ASSERT_FATAL(romClass, "ROM class of J9Class=%p must be cached at this point", clazz); } - J9ROMMethod *romMethod = (J9ROMMethod*)((uint8_t*)romClass + romMethodOffset); - // Optimization plan needs to use the global allocator, // because there is a global pool of plans { @@ -728,6 +756,23 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J // If we want something then we need to increaseQueueWeightBy(weight) while holding compilation monitor entry._weight = 0; entry._useAotCompilation = useAotCompilation; + + auto aotCache = clientSession->getOrCreateAOTCache(stream); + _aotCacheStore = classChain && aotCache; + if (_aotCacheStore) + { + JITServerHelpers::cacheRemoteROMClassBatch(clientSession, uncachedRAMClasses, uncachedClassInfos); + _definingClassChainRecord = clientSession->getClassChainRecord(clazz, classChain, ramClassChain, stream); + if (!_definingClassChainRecord) + { + if (TR::Options::getVerboseOption(TR_VerboseJITServer)) + TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, + "Failed to get defining class chain record for %p; method %p won't be stored in AOT cache", + clazz, ramMethod + ); + _aotCacheStore = false; + } + } } catch (const JITServer::StreamFailure &e) { @@ -797,11 +842,11 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J Trc_JITServerStreamInterrupted(compThread, getCompThreadId(), __FUNCTION__, "", "", e.what()); abortCompilation = true; - // If the client aborted this compilation it could have happened only while asking for entire + // If the client aborted this compilation, it could have happened while asking for entire // CHTable and unloaded class address ranges and at that point the seqNo was not updated. - // We must update seqNo now to allow for blocking threads to pass through. + // In such case, we must update seqNo now to allow for blocking threads to pass through. // Since the caches are already cleared there is no harm in discarding this message. - if (isCriticalRequest) + if (isCriticalRequest && !hasUpdatedSeqNo) { clientSession->getSequencingMonitor()->enter(); if (seqNo > clientSession->getLastProcessedCriticalSeqNo()) diff --git a/runtime/compiler/control/JITServerCompilationThread.hpp b/runtime/compiler/control/JITServerCompilationThread.hpp index f115718c600..0d303c2647d 100644 --- a/runtime/compiler/control/JITServerCompilationThread.hpp +++ b/runtime/compiler/control/JITServerCompilationThread.hpp @@ -42,7 +42,7 @@ namespace TR // Objects of this type are instantiated at JITServer class CompilationInfoPerThreadRemote : public TR::CompilationInfoPerThread { - public: +public: friend class TR::CompilationInfo; CompilationInfoPerThreadRemote(TR::CompilationInfo &compInfo, J9JITConfig *jitConfig, int32_t id, bool isDiagnosticThread); @@ -109,7 +109,11 @@ class CompilationInfoPerThreadRemote : public TR::CompilationInfoPerThread void decrementClassUnloadReadMutexDepth() { _classUnloadReadMutexDepth--; } int32_t getClassUnloadReadMutexDepth() { return _classUnloadReadMutexDepth; } - private: + bool isAOTCacheStore() const { return _aotCacheStore; } + uint32_t getMethodIndex() const { return _methodIndex; } + const AOTCacheClassChainRecord *getDefiningClassChainRecord() { return _definingClassChainRecord; } + +private: /* Template method for allocating a cache of type T on the heap. * Cache pointer must be NULL. */ @@ -173,13 +177,17 @@ class CompilationInfoPerThreadRemote : public TR::CompilationInfoPerThread size_t _clientOptionsSize; IPTableHeap_t *_methodIPDataPerComp; TR_ResolvedMethodInfoCache *_resolvedMethodInfoMap; - ResolvedMirrorMethodsPersistIP_t *_resolvedMirrorMethodsPersistIPInfo; //list of mirrors of resolved methods for persisting IProfiler info + ResolvedMirrorMethodsPersistIP_t *_resolvedMirrorMethodsPersistIPInfo; // list of mirrors of resolved methods for persisting IProfiler info ClassOfStatic_t *_classOfStaticMap; FieldOrStaticAttrTable_t *_fieldAttributesCache; FieldOrStaticAttrTable_t *_staticAttributesCache; UnorderedMap, TR_IsUnresolvedString> *_isUnresolvedStrCache; int32_t _classUnloadReadMutexDepth; - static int32_t _numClearedCaches; //number of instances JITServer was forced to clear its internal per-client caches + bool _aotCacheStore; // True if the result of this compilation will be stored in AOT cache + uint32_t _methodIndex; // Index of the method being compiled in the array of methods of its defining class + const AOTCacheClassChainRecord *_definingClassChainRecord; // Used to store the result of the compilation in AOT cache + + static int32_t _numClearedCaches; // number of instances JITServer was forced to clear its internal per-client caches }; // class CompilationInfoPerThreadRemote } // namespace TR diff --git a/runtime/compiler/control/JITServerHelpers.cpp b/runtime/compiler/control/JITServerHelpers.cpp index c5ba909694b..faf7fb9c9e1 100644 --- a/runtime/compiler/control/JITServerHelpers.cpp +++ b/runtime/compiler/control/JITServerHelpers.cpp @@ -973,17 +973,17 @@ addRAMClassToChain(std::vector &chain, J9Class *clazz, std::vector -JITServerHelpers::getRAMClassChain(J9Class *clazz, size_t length, J9VMThread *vmThread, TR_Memory *trMemory, +JITServerHelpers::getRAMClassChain(J9Class *clazz, size_t numClasses, J9VMThread *vmThread, TR_Memory *trMemory, TR::CompilationInfo *compInfo, std::vector &uncachedRAMClasses, std::vector &uncachedClassInfos) { TR_ASSERT(uncachedRAMClasses.empty(), "Must pass empty vector"); TR_ASSERT(uncachedClassInfos.empty(), "Must pass empty vector"); - TR_ASSERT(length <= TR_J9SharedCache::maxClassChainLength, "Class chain is too long"); + TR_ASSERT(numClasses <= TR_J9SharedCache::maxClassChainLength, "Class chain is too long"); std::vector chain; - chain.reserve(length); - uncachedRAMClasses.reserve(length); + chain.reserve(numClasses); + uncachedRAMClasses.reserve(numClasses); auto &cached = compInfo->getclassesCachedAtServer(); { @@ -994,7 +994,7 @@ JITServerHelpers::getRAMClassChain(J9Class *clazz, size_t length, J9VMThread *vm addRAMClassToChain(chain, clazz->superclasses[i], uncachedRAMClasses, cached); for (auto it = (J9ITable *)clazz->iTable; it; it = it->next) addRAMClassToChain(chain, it->interfaceClass, uncachedRAMClasses, cached); - TR_ASSERT(chain.size() == length, "Invalid RAM class chain length: %zu != %zu", chain.size(), length); + TR_ASSERT(chain.size() == numClasses, "Invalid RAM class chain length: %zu != %zu", chain.size(), numClasses); } uncachedClassInfos.reserve(uncachedRAMClasses.size()); diff --git a/runtime/compiler/control/JITServerHelpers.hpp b/runtime/compiler/control/JITServerHelpers.hpp index 824ae1e2ea4..a885dd4610e 100644 --- a/runtime/compiler/control/JITServerHelpers.hpp +++ b/runtime/compiler/control/JITServerHelpers.hpp @@ -131,11 +131,11 @@ class JITServerHelpers static uintptr_t walkReferenceChainWithOffsets(TR_J9VM *fe, const std::vector &listOfOffsets, uintptr_t receiver); - // Called by the client as part of handling the SharedCache_rememberClass message when AOT cache is enabled. - // Returns the list of RAMClasses in the class chain for clazz and populates uncachedRAMClasses and - // uncachedClassInfos with the classes (and their data) that the client has not yet sent to the server. + // Called by the client as part of preparing the compilation request and handling the SharedCache_rememberClass message + // when AOT cache is enabled. Returns the list of RAMClasses in the class chain for clazz and populates uncachedRAMClasses + // and uncachedClassInfos with the classes (and their data) that the client has not yet sent to the server. static std::vector - getRAMClassChain(J9Class *clazz, size_t length, J9VMThread *vmThread, TR_Memory *trMemory, TR::CompilationInfo *compInfo, + getRAMClassChain(J9Class *clazz, size_t numClasses, J9VMThread *vmThread, TR_Memory *trMemory, TR::CompilationInfo *compInfo, std::vector &uncachedRAMClasses, std::vector &uncachedClassInfos); static void cacheRemoteROMClassBatch(ClientSessionData *clientData, const std::vector &ramClasses, diff --git a/runtime/compiler/control/MethodToBeCompiled.hpp b/runtime/compiler/control/MethodToBeCompiled.hpp index c87b7b5c7fc..80490d32bfd 100644 --- a/runtime/compiler/control/MethodToBeCompiled.hpp +++ b/runtime/compiler/control/MethodToBeCompiled.hpp @@ -32,7 +32,8 @@ #include "control/CompilationPriority.hpp" #include "ilgen/IlGeneratorMethodDetails_inlines.hpp" -#define MAX_COMPILE_ATTEMPTS 3 + +#define MAX_COMPILE_ATTEMPTS 3 #define ENTRY_INITIALIZED 0x1 #define ENTRY_QUEUED 0x2 @@ -144,11 +145,14 @@ struct TR_MethodToBeCompiled uint8_t _weight; // Up to 256 levels of weight bool _hasIncrementedNumCompThreadsCompilingHotterMethods; uint8_t _jitStateWhenQueued; + #if defined(J9VM_OPT_JITSERVER) - bool _remoteCompReq; // Comp request should be sent remotely to JITServer - JITServer::ServerStream *_stream; // A non-NULL field denotes an out-of-process compilation request - TR_Hotness _origOptLevel; // Cache original optLevel when transforming a remote sync compilation to a local cheap one - bool _shouldUpgradeOutOfProcessCompilation; // Flag used to determine whether a cold local compilation should be upgraded by LPQ + bool _remoteCompReq; // Comp request should be sent remotely to JITServer + JITServer::ServerStream *_stream; // A non-NULL field denotes an out-of-process compilation request + TR_Hotness _origOptLevel; // Cache original optLevel when transforming a + // remote sync compilation to a local cheap one + bool _shouldUpgradeOutOfProcessCompilation; // Flag used to determine whether a cold local + // compilation should be upgraded by LPQ #endif /* defined(J9VM_OPT_JITSERVER) */ }; // TR_MethodToBeCompiled diff --git a/runtime/compiler/env/J9SharedCache.cpp b/runtime/compiler/env/J9SharedCache.cpp index a76bedae9b0..343287f2bd0 100644 --- a/runtime/compiler/env/J9SharedCache.cpp +++ b/runtime/compiler/env/J9SharedCache.cpp @@ -1360,6 +1360,7 @@ TR_J9JITServerSharedCache::TR_J9JITServerSharedCache(TR_J9VMBase *fe) uintptr_t * TR_J9JITServerSharedCache::rememberClass(J9Class *clazz, const AOTCacheClassChainRecord **classChainRecord, bool create) { + TR_ASSERT_FATAL(classChainRecord || !create, "Must pass classChainRecord if creating class chain at JITServer"); TR_ASSERT(_stream, "stream must be initialized by now"); uintptr_t *classChain = NULL; diff --git a/runtime/compiler/net/CommunicationStream.hpp b/runtime/compiler/net/CommunicationStream.hpp index f4c523d79f7..8b5b69260c8 100644 --- a/runtime/compiler/net/CommunicationStream.hpp +++ b/runtime/compiler/net/CommunicationStream.hpp @@ -99,7 +99,7 @@ class CommunicationStream ClientMessage _cMsg; static const uint8_t MAJOR_NUMBER = 1; - static const uint16_t MINOR_NUMBER = 32; + static const uint16_t MINOR_NUMBER = 33; static const uint8_t PATCH_NUMBER = 0; static uint32_t CONFIGURATION_FLAGS; diff --git a/runtime/compiler/p/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/p/codegen/J9AheadOfTimeCompile.cpp index 2c4eb6a23cb..aa6bdf26a15 100644 --- a/runtime/compiler/p/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/p/codegen/J9AheadOfTimeCompile.cpp @@ -92,11 +92,13 @@ void J9::Power::AheadOfTimeCompile::processRelocations() if (useSVM) { - TR::SymbolValidationManager *svm = - comp->getSymbolValidationManager(); - void *offsets = const_cast(svm->wellKnownClassChainOffsets()); - *(uintptr_t *)relocationDataCursor = - self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); + TR::SymbolValidationManager *svm = comp->getSymbolValidationManager(); + void *offsets = const_cast(svm->wellKnownClassChainOffsets()); + uintptr_t *wkcOffsetAddr = (uintptr_t *)relocationDataCursor; + *wkcOffsetAddr = self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); +#if defined(J9VM_OPT_JITSERVER) + self()->addWellKnownClassesSerializationRecord(svm->aotCacheWellKnownClassesRecord(), wkcOffsetAddr); +#endif /* defined(J9VM_OPT_JITSERVER) */ relocationDataCursor += SIZEPOINTER; } @@ -292,7 +294,7 @@ J9::Power::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR: TR_RelocationRecordArbitraryClassAddress *acaRecord = reinterpret_cast(reloRecord); // ExternalRelocation data is as expected for TR_ClassAddress - TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation*) relocation->getTargetAddress(); + TR_RelocationRecordInformation *recordInfo = (TR_RelocationRecordInformation *)relocation->getTargetAddress(); auto symRef = (TR::SymbolReference *)recordInfo->data1; auto sym = symRef->getSymbol()->castToStaticSymbol(); @@ -301,13 +303,15 @@ J9::Power::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR: uintptr_t inlinedSiteIndex = self()->findCorrectInlinedSiteIndex(symRef->getOwningMethod(comp)->constantPool(), recordInfo->data2); uintptr_t classChainIdentifyingLoaderOffsetInSharedCache = sharedCache->getClassChainOffsetIdentifyingLoader(j9class); - uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class); + const AOTCacheClassChainRecord *classChainRecord = NULL; + uintptr_t classChainOffsetInSharedCache = self()->getClassChainOffset(j9class, classChainRecord); - TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n"); + TR_ASSERT((flags & RELOCATION_CROSS_PLATFORM_FLAGS_MASK) == 0, "reloFlags bits overlap cross-platform flags bits"); acaRecord->setReloFlags(reloTarget, flags); acaRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); - acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache); - acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache); + acaRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache, + self(), classChainRecord); + acaRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord); } break; diff --git a/runtime/compiler/runtime/JITServerAOTCache.cpp b/runtime/compiler/runtime/JITServerAOTCache.cpp index 88a4d08d864..26f26334782 100644 --- a/runtime/compiler/runtime/JITServerAOTCache.cpp +++ b/runtime/compiler/runtime/JITServerAOTCache.cpp @@ -590,9 +590,10 @@ JITServerAOTCache::storeMethod(const AOTCacheClassChainRecord *definingClassChai if (TR::Options::getVerboseOption(TR_VerboseJITServer)) TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, - "AOT cache %s: stored method %s @ %s index %u class ID %zu AOT header ID %zu for clientUID %llu", + "AOT cache %s: stored method %s @ %s index %u class ID %zu " + "AOT header ID %zu with %zu serialization records for clientUID %llu", _name.c_str(), signature, levelName, index, definingClassId, - aotHeaderRecord->data().id(), (unsigned long long)clientUID + aotHeaderRecord->data().id(), records.size(), (unsigned long long)clientUID ); return true; @@ -690,7 +691,7 @@ JITServerAOTCacheMap::get(const std::string &name, uint64_t clientUID) if (it != _map.end()) { if (TR::Options::getVerboseOption(TR_VerboseJITServer)) - TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Created AOT cache %s for clientUID %llu", + TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Using existing AOT cache %s for clientUID %llu", name.c_str(), (unsigned long long)clientUID); return it->second; } @@ -711,7 +712,7 @@ JITServerAOTCacheMap::get(const std::string &name, uint64_t clientUID) } if (TR::Options::getVerboseOption(TR_VerboseJITServer)) - TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Using existing AOT cache %s for clientUID %llu", + TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Created AOT cache %s for clientUID %llu", name.c_str(), (unsigned long long)clientUID); return cache; } diff --git a/runtime/compiler/runtime/JITServerAOTCache.hpp b/runtime/compiler/runtime/JITServerAOTCache.hpp index 7b552ac6edf..84da0dd205d 100644 --- a/runtime/compiler/runtime/JITServerAOTCache.hpp +++ b/runtime/compiler/runtime/JITServerAOTCache.hpp @@ -133,12 +133,15 @@ class AOTCacheMethodRecord final : public AOTCacheRecord // Helper template class to avoid duplicating code for class chain records and well-known classes records +// D is one of: ClassChainSerializationRecord, WellKnownClassesSerializationRecord +// R is one of: AOTCacheClassRecord, AOTCacheClassChainRecord template class AOTCacheListRecord : public AOTCacheRecord { public: const D &data() const { return _data; } const AOTSerializationRecord *dataAddr() const override { return &_data; } + // Array of record pointers is stored inline after the array of IDs that is stored inline after struct D header const R *const *records() const { return (const R *const *)_data.end(); } void subRecordsDo(const std::function &f) const override; @@ -151,8 +154,8 @@ class AOTCacheListRecord : public AOTCacheRecord return offsetof(AOTCacheListRecord, _data) + D::size(length) + length * sizeof(R *); } + // Layout: struct D header, uintptr_t ids[length], const R *records[length] D _data; - // Array of record pointers is stored inline after serialization record data }; @@ -161,6 +164,9 @@ class AOTCacheClassChainRecord final : public AOTCacheListRecordclassLoaderRecord(); } + private: using AOTCacheListRecord::AOTCacheListRecord; }; diff --git a/runtime/compiler/runtime/JITServerAOTDeserializer.cpp b/runtime/compiler/runtime/JITServerAOTDeserializer.cpp index c98f651e3f9..efc9c1f0c5e 100644 --- a/runtime/compiler/runtime/JITServerAOTDeserializer.cpp +++ b/runtime/compiler/runtime/JITServerAOTDeserializer.cpp @@ -803,15 +803,18 @@ JITServerAOTDeserializer::deserializationFailure(const SerializedAOTMethod *meth bool JITServerAOTDeserializer::updateSCCOffsets(SerializedAOTMethod *method, TR::Compilation *comp, bool &wasReset) { - //NOTE: Defining class chain record is validated by now + //NOTE: Defining class chain record is validated by now; there is no corresponding SCC offset to be updated - auto header = (TR_AOTMethodHeader *)(method->data() + sizeof(J9JITDataCacheHeader)); - if (header->offsetToRelocationDataItems == 0) - { - TR_ASSERT_FATAL(method->numRecords() == 0, "Unexpected serialization records in serialized method %s", - comp->signature()); - return true; - } + auto header = (const TR_AOTMethodHeader *)(method->data() + sizeof(J9JITDataCacheHeader)); + TR_ASSERT_FATAL((header->minorVersion == TR_AOTMethodHeader_MinorVersion) && + (header->majorVersion == TR_AOTMethodHeader_MajorVersion), + "Invalid TR_AOTMethodHeader version: %d.%d", header->majorVersion, header->minorVersion); + TR_ASSERT_FATAL((header->offsetToRelocationDataItems != 0) || (method->numRecords() == 0), + "Unexpected %zu serialization records in serialized method %s with no relocation data", + method->numRecords(), comp->signature()); + + uint8_t *start = method->data() + header->offsetToRelocationDataItems; + uint8_t *end = start + *(uintptr_t *)start;// Total size of relocation data is stored in the first word for (size_t i = 0; i < method->numRecords(); ++i) { @@ -822,9 +825,10 @@ JITServerAOTDeserializer::updateSCCOffsets(SerializedAOTMethod *method, TR::Comp return false; // Update the SCC offset stored in AOT method relocation data - uint8_t *ptr = method->data() + header->offsetToRelocationDataItems + serializedOffset.reloDataOffset(); - TR_ASSERT_FATAL(ptr < method->data() + method->dataSize(), - "Out-of-bounds relocation data offset in serialized method %s", comp->signature()); + uint8_t *ptr = start + serializedOffset.reloDataOffset(); + TR_ASSERT_FATAL((ptr >= start + sizeof(uintptr_t)/*skip the size word*/) && (ptr < end), + "Out-of-bounds relocation data offset %zu in serialized method %s", + serializedOffset.reloDataOffset(), comp->signature()); *(uintptr_t *)ptr = sccOffset; } diff --git a/runtime/compiler/runtime/RelocationRecord.cpp b/runtime/compiler/runtime/RelocationRecord.cpp index 1c9e492ef41..551057eecf2 100644 --- a/runtime/compiler/runtime/RelocationRecord.cpp +++ b/runtime/compiler/runtime/RelocationRecord.cpp @@ -56,11 +56,13 @@ #include "env/VMJ9.h" #include "control/rossa.h" #if defined(J9VM_OPT_JITSERVER) +#include "codegen/AheadOfTimeCompile.hpp" #include "control/CompilationRuntime.hpp" #include "control/CompilationThread.hpp" #include "control/MethodToBeCompiled.hpp" #endif /* defined(J9VM_OPT_JITSERVER) */ + // TODO: move this someplace common for RuntimeAssumptions.cpp and here #if defined(__IBMCPP__) && !defined(AIXPPC) && !defined(LINUXPPC) #define ASM_CALL __cdecl @@ -2618,13 +2620,30 @@ TR_RelocationRecordInlinedMethod::print(TR_RelocationRuntime *reloRuntime) J9ROMClass *inlinedCodeRomClass = reloRuntime->fej9()->sharedCache()->romClassFromOffsetInSharedCache(romClassOffsetInSharedCache(reloTarget)); J9UTF8 *inlinedCodeClassName = J9ROMCLASS_CLASSNAME(inlinedCodeRomClass); reloLogger->printf("\tromClassOffsetInSharedCache %x %.*s\n", romClassOffsetInSharedCache(reloTarget), J9UTF8_LENGTH(inlinedCodeClassName), J9UTF8_DATA(inlinedCodeClassName)); - //reloLogger->printf("\tromClassOffsetInSharedCache %x %.*s\n", romClassOffsetInSharedCache(reloTarget), J9UTF8_LENGTH(inlinedCodeClassname), J9UTF8_DATA(inlinedCodeClassName)); } void -TR_RelocationRecordInlinedMethod::setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache) +TR_RelocationRecordInlinedMethod::setRomClassOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) + { + uintptr_t *addr = &((TR_RelocationRecordInlinedMethodBinaryTemplate *)_record)->_romClassOffsetInSharedCache; + reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ + } + +void +TR_RelocationRecordInlinedMethod::setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, TR_OpaqueClassBlock *ramClass) { - reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, (uintptr_t *) &((TR_RelocationRecordInlinedMethodBinaryTemplate *)_record)->_romClassOffsetInSharedCache); + uintptr_t *addr = &((TR_RelocationRecordInlinedMethodBinaryTemplate *)_record)->_romClassOffsetInSharedCache; + reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassSerializationRecord(ramClass, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3153,9 +3172,16 @@ TR_RelocationRecordProfiledInlinedMethod::print(TR_RelocationRuntime *reloRuntim } void -TR_RelocationRecordProfiledInlinedMethod::setClassChainIdentifyingLoaderOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainIdentifyingLoaderOffsetInSharedCache) +TR_RelocationRecordProfiledInlinedMethod::setClassChainIdentifyingLoaderOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t classChainIdentifyingLoaderOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainIdentifyingLoaderOffsetInSharedCache, (uintptr_t *) &((TR_RelocationRecordProfiledInlinedMethodBinaryTemplate *)_record)->_classChainIdentifyingLoaderOffsetInSharedCache); + uintptr_t *addr = &((TR_RelocationRecordProfiledInlinedMethodBinaryTemplate *)_record)->_classChainIdentifyingLoaderOffsetInSharedCache; + reloTarget->storeRelocationRecordValue(classChainIdentifyingLoaderOffsetInSharedCache, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassLoaderSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3165,9 +3191,16 @@ TR_RelocationRecordProfiledInlinedMethod::classChainIdentifyingLoaderOffsetInSha } void -TR_RelocationRecordProfiledInlinedMethod::setClassChainForInlinedMethod(TR_RelocationTarget *reloTarget, uintptr_t classChainForInlinedMethod) +TR_RelocationRecordProfiledInlinedMethod::setClassChainForInlinedMethod( + TR_RelocationTarget *reloTarget, uintptr_t classChainForInlinedMethod, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainForInlinedMethod, (uintptr_t *) &((TR_RelocationRecordProfiledInlinedMethodBinaryTemplate *)_record)->_classChainForInlinedMethod); + uintptr_t *addr = &((TR_RelocationRecordProfiledInlinedMethodBinaryTemplate *)_record)->_classChainForInlinedMethod; + reloTarget->storeRelocationRecordValue(classChainForInlinedMethod, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3506,9 +3539,16 @@ TR_RelocationRecordValidateClass::print(TR_RelocationRuntime *reloRuntime) } void -TR_RelocationRecordValidateClass::setClassChainOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache) +TR_RelocationRecordValidateClass::setClassChainOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainOffsetInSharedCache, (uintptr_t *) &((TR_RelocationRecordValidateClassBinaryTemplate *)_record)->_classChainOffsetInSharedCache); + uintptr_t *addr = &((TR_RelocationRecordValidateClassBinaryTemplate *)_record)->_classChainOffsetInSharedCache; + reloTarget->storeRelocationRecordValue(classChainOffsetInSharedCache, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3630,9 +3670,16 @@ TR_RelocationRecordValidateStaticField::print(TR_RelocationRuntime *reloRuntime) } void -TR_RelocationRecordValidateStaticField::setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache) +TR_RelocationRecordValidateStaticField::setRomClassOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, (uintptr_t *) &((TR_RelocationRecordValidateStaticFieldBinaryTemplate *)_record)->_romClassOffsetInSharedCache); + uintptr_t *addr = &((TR_RelocationRecordValidateStaticFieldBinaryTemplate *)_record)->_romClassOffsetInSharedCache; + reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3684,9 +3731,16 @@ TR_RelocationRecordValidateArbitraryClass::print(TR_RelocationRuntime *reloRunti void -TR_RelocationRecordValidateArbitraryClass::setClassChainIdentifyingLoaderOffset(TR_RelocationTarget *reloTarget, uintptr_t offset) +TR_RelocationRecordValidateArbitraryClass::setClassChainIdentifyingLoaderOffset( + TR_RelocationTarget *reloTarget, uintptr_t offset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(offset, (uintptr_t *) &((TR_RelocationRecordValidateArbitraryClassBinaryTemplate *)_record)->_loaderClassChainOffset); + uintptr_t *addr = &((TR_RelocationRecordValidateArbitraryClassBinaryTemplate *)_record)->_loaderClassChainOffset; + reloTarget->storeRelocationRecordValue(offset, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassLoaderSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3696,9 +3750,16 @@ TR_RelocationRecordValidateArbitraryClass::classChainIdentifyingLoaderOffset(TR_ } void -TR_RelocationRecordValidateArbitraryClass::setClassChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget, uintptr_t offset) +TR_RelocationRecordValidateArbitraryClass::setClassChainOffsetForClassBeingValidated( + TR_RelocationTarget *reloTarget, uintptr_t offset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(offset, (uintptr_t *) &((TR_RelocationRecordValidateArbitraryClassBinaryTemplate *)_record)->_classChainOffsetForClassBeingValidated); + uintptr_t *addr = &((TR_RelocationRecordValidateArbitraryClassBinaryTemplate *)_record)->_classChainOffsetForClassBeingValidated; + reloTarget->storeRelocationRecordValue(offset, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3791,9 +3852,16 @@ TR_RelocationRecordValidateClassByName::beholderID(TR_RelocationTarget *reloTarg } void -TR_RelocationRecordValidateClassByName::setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset) +TR_RelocationRecordValidateClassByName::setClassChainOffset( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - return reloTarget->storeRelocationRecordValue(classChainOffset, (uintptr_t *) &((TR_RelocationRecordValidateClassByNameBinaryTemplate *)_record)->_classChainOffsetInSCC); + uintptr_t *addr = &((TR_RelocationRecordValidateClassByNameBinaryTemplate *)_record)->_classChainOffsetInSCC; + reloTarget->storeRelocationRecordValue(classChainOffset, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3843,9 +3911,16 @@ TR_RelocationRecordValidateProfiledClass::classID(TR_RelocationTarget *reloTarge } void -TR_RelocationRecordValidateProfiledClass::setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset) +TR_RelocationRecordValidateProfiledClass::setClassChainOffset( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainOffset, (uintptr_t *) &((TR_RelocationRecordValidateProfiledClassBinaryTemplate *)_record)->_classChainOffsetInSCC); + uintptr_t *addr = &((TR_RelocationRecordValidateProfiledClassBinaryTemplate *)_record)->_classChainOffsetInSCC; + reloTarget->storeRelocationRecordValue(classChainOffset, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -3855,9 +3930,16 @@ TR_RelocationRecordValidateProfiledClass::classChainOffset(TR_RelocationTarget * } void -TR_RelocationRecordValidateProfiledClass::setClassChainOffsetForClassLoader(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetForCL) +TR_RelocationRecordValidateProfiledClass::setClassChainOffsetForClassLoader( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetForCL, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainOffsetForCL, (uintptr_t *) &((TR_RelocationRecordValidateProfiledClassBinaryTemplate *)_record)->_classChainOffsetForCLInScc); + uintptr_t *addr = &((TR_RelocationRecordValidateProfiledClassBinaryTemplate *)_record)->_classChainOffsetForCLInScc; + reloTarget->storeRelocationRecordValue(classChainOffsetForCL, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassLoaderSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -4229,9 +4311,16 @@ TR_RelocationRecordValidateSystemClassByName::systemClassID(TR_RelocationTarget } void -TR_RelocationRecordValidateSystemClassByName::setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset) +TR_RelocationRecordValidateSystemClassByName::setClassChainOffset( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainOffset, (uintptr_t *) &((TR_RelocationRecordValidateSystemClassByNameBinaryTemplate *)_record)->_classChainOffsetInSCC); + uintptr_t *addr = &((TR_RelocationRecordValidateSystemClassByNameBinaryTemplate *)_record)->_classChainOffsetInSCC; + reloTarget->storeRelocationRecordValue(classChainOffset, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -4314,9 +4403,16 @@ TR_RelocationRecordValidateClassChain::classID(TR_RelocationTarget *reloTarget) } void -TR_RelocationRecordValidateClassChain::setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset) +TR_RelocationRecordValidateClassChain::setClassChainOffset( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainOffset, (uintptr_t *) &((TR_RelocationRecordValidateClassChainBinaryTemplate *)_record)->_classChainOffsetInSCC); + uintptr_t *addr = &((TR_RelocationRecordValidateClassChainBinaryTemplate *)_record)->_classChainOffsetInSCC; + reloTarget->storeRelocationRecordValue(classChainOffset, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -4757,9 +4853,16 @@ TR_RelocationRecordValidateMethodFromClassAndSig::beholderID(TR_RelocationTarget } void -TR_RelocationRecordValidateMethodFromClassAndSig::setRomMethodOffsetInSCC(TR_RelocationTarget *reloTarget, uintptr_t romMethodOffsetInSCC) +TR_RelocationRecordValidateMethodFromClassAndSig::setRomMethodOffsetInSCC( + TR_RelocationTarget *reloTarget, uintptr_t romMethodOffsetInSCC, + TR::AheadOfTimeCompile *aotCompile, J9Method *method, TR_OpaqueClassBlock *definingClass +) { - reloTarget->storeRelocationRecordValue(romMethodOffsetInSCC, (uintptr_t *) &((TR_RelocationRecordValidateMethodFromClassAndSigBinaryTemplate *)_record)->_romMethodOffsetInSCC); + uintptr_t *addr = &((TR_RelocationRecordValidateMethodFromClassAndSigBinaryTemplate *)_record)->_romMethodOffsetInSCC; + reloTarget->storeRelocationRecordValue(romMethodOffsetInSCC, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addMethodSerializationRecord(method, definingClass, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -5427,14 +5530,18 @@ TR_RelocationRecordHCR::applyRelocation(TR_RelocationRuntime *reloRuntime, TR_Re { void *methodAddress = (void *)reloRuntime->exceptionTable()->ramMethod; if (offset(reloTarget)) // non-NULL means resolved - createClassRedefinitionPicSite(methodAddress, (void*)reloLocation, sizeof(UDATA), true, getMetadataAssumptionList(reloRuntime->exceptionTable())); + { + createClassRedefinitionPicSite(methodAddress, (void *)reloLocation, sizeof(uintptr_t), true, + getMetadataAssumptionList(reloRuntime->exceptionTable())); + } else - { - uint32_t locationSize = 1; // see OMR::RuntimeAssumption::isForAddressMaterializationSequence - if (reloFlags(reloTarget) & needsFullSizeRuntimeAssumption) - locationSize = sizeof(uintptr_t); - createClassRedefinitionPicSite((void*)-1, (void*)reloLocation, locationSize, true, getMetadataAssumptionList(reloRuntime->exceptionTable())); - } + { + uint32_t locationSize = 1; // see OMR::RuntimeAssumption::isForAddressMaterializationSequence + if (reloFlags(reloTarget) & needsFullSizeRuntimeAssumption) + locationSize = sizeof(uintptr_t); + createClassRedefinitionPicSite((void *)-1, (void *)reloLocation, locationSize, true, + getMetadataAssumptionList(reloRuntime->exceptionTable())); + } return 0; } @@ -5459,9 +5566,16 @@ TR_RelocationRecordPointer::action(TR_RelocationRuntime *reloRuntime) } void -TR_RelocationRecordPointer::setClassChainIdentifyingLoaderOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainIdentifyingLoaderOffsetInSharedCache) +TR_RelocationRecordPointer::setClassChainIdentifyingLoaderOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t classChainIdentifyingLoaderOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainIdentifyingLoaderOffsetInSharedCache, (uintptr_t *) &((TR_RelocationRecordPointerBinaryTemplate *)_record)->_classChainIdentifyingLoaderOffsetInSharedCache); + uintptr_t *addr = &((TR_RelocationRecordPointerBinaryTemplate *)_record)->_classChainIdentifyingLoaderOffsetInSharedCache; + reloTarget->storeRelocationRecordValue(classChainIdentifyingLoaderOffsetInSharedCache, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassLoaderSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t @@ -5471,9 +5585,16 @@ TR_RelocationRecordPointer::classChainIdentifyingLoaderOffsetInSharedCache(TR_Re } void -TR_RelocationRecordPointer::setClassChainForInlinedMethod(TR_RelocationTarget *reloTarget, uintptr_t classChainForInlinedMethod) +TR_RelocationRecordPointer::setClassChainForInlinedMethod( + TR_RelocationTarget *reloTarget, uintptr_t classChainForInlinedMethod, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord +) { - reloTarget->storeRelocationRecordValue(classChainForInlinedMethod, (uintptr_t *) &((TR_RelocationRecordPointerBinaryTemplate *)_record)->_classChainForInlinedMethod); + uintptr_t *addr = &((TR_RelocationRecordPointerBinaryTemplate *)_record)->_classChainForInlinedMethod; + reloTarget->storeRelocationRecordValue(classChainForInlinedMethod, addr); +#if defined(J9VM_OPT_JITSERVER) + aotCompile->addClassChainSerializationRecord(classChainRecord, addr); +#endif /* defined(J9VM_OPT_JITSERVER) */ } uintptr_t diff --git a/runtime/compiler/runtime/RelocationRecord.hpp b/runtime/compiler/runtime/RelocationRecord.hpp index ceddb96262d..1c69d970144 100644 --- a/runtime/compiler/runtime/RelocationRecord.hpp +++ b/runtime/compiler/runtime/RelocationRecord.hpp @@ -38,6 +38,9 @@ class TR_RelocationRecord; class TR_RelocationTarget; struct TR_RelocationRecordBinaryTemplate; typedef TR_ExternalRelocationTargetKind TR_RelocationRecordType; +namespace TR { class AheadOfTimeCompile; } +class AOTCacheClassChainRecord; + #define TR_VALIDATE_STATIC_OR_SPECIAL_METHOD_FROM_CP_IS_SPLIT 0x01 @@ -756,7 +759,10 @@ class TR_RelocationRecordInlinedMethod : public TR_RelocationRecordConstantPoolW TR_RelocationRecordInlinedMethod(TR_RelocationRuntime *reloRuntime, TR_RelocationRecordBinaryTemplate *record) : TR_RelocationRecordConstantPoolWithIndex(reloRuntime, record) {} virtual void print(TR_RelocationRuntime *reloRuntime); - void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache); + void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, TR_OpaqueClassBlock *ramClass); uintptr_t romClassOffsetInSharedCache(TR_RelocationTarget *reloTarget); virtual void preparePrivateData(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget); @@ -933,10 +939,14 @@ class TR_RelocationRecordProfiledInlinedMethod : public TR_RelocationRecordInlin virtual void print(TR_RelocationRuntime *reloRuntime); - void setClassChainIdentifyingLoaderOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache); + void setClassChainIdentifyingLoaderOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + ); uintptr_t classChainIdentifyingLoaderOffsetInSharedCache(TR_RelocationTarget *reloTarget); - void setClassChainForInlinedMethod(TR_RelocationTarget *reloTarget, uintptr_t classChainForInlinedMethod); + void setClassChainForInlinedMethod(TR_RelocationTarget *reloTarget, uintptr_t classChainForInlinedMethod, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainForInlinedMethod(TR_RelocationTarget *reloTarget); void setMethodIndex(TR_RelocationTarget *reloTarget, uintptr_t methodIndex); @@ -1049,7 +1059,8 @@ class TR_RelocationRecordValidateClass : public TR_RelocationRecordConstantPoolW virtual bool isStaticFieldValidation() { return false ; } - void setClassChainOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache); + void setClassChainOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffsetInSharedCache(TR_RelocationTarget *reloTarget); virtual int32_t applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation); @@ -1083,7 +1094,8 @@ class TR_RelocationRecordValidateStaticField : public TR_RelocationRecordValidat virtual bool isStaticFieldValidation() { return true; } - void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache); + void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t romClassOffsetInSharedCache(TR_RelocationTarget *reloTarget); protected: @@ -1099,10 +1111,12 @@ class TR_RelocationRecordValidateArbitraryClass : public TR_RelocationRecord virtual char *name(); virtual void print(TR_RelocationRuntime *reloRuntime); - void setClassChainIdentifyingLoaderOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset); + void setClassChainIdentifyingLoaderOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainIdentifyingLoaderOffset(TR_RelocationTarget *reloTarget); - void setClassChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset); + void setClassChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget); virtual void preparePrivateData(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget); @@ -1129,7 +1143,8 @@ class TR_RelocationRecordValidateClassByName : public TR_RelocationRecord void setBeholderID(TR_RelocationTarget *reloTarget, uint16_t beholderID); uint16_t beholderID(TR_RelocationTarget *reloTarget); - void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset); + void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); }; @@ -1148,10 +1163,12 @@ class TR_RelocationRecordValidateProfiledClass : public TR_RelocationRecord void setClassID(TR_RelocationTarget *reloTarget, uint16_t classID); uint16_t classID(TR_RelocationTarget *reloTarget); - void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset); + void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); - void setClassChainOffsetForClassLoader(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetForCL); + void setClassChainOffsetForClassLoader(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetForCL, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffsetForClassLoader(TR_RelocationTarget *reloTarget); }; @@ -1292,7 +1309,8 @@ class TR_RelocationRecordValidateSystemClassByName : public TR_RelocationRecord void setSystemClassID(TR_RelocationTarget *reloTarget, uint16_t systemClassID); uint16_t systemClassID(TR_RelocationTarget *reloTarget); - void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset); + void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); }; @@ -1339,7 +1357,8 @@ class TR_RelocationRecordValidateClassChain : public TR_RelocationRecord void setClassID(TR_RelocationTarget *reloTarget, uint16_t classID); uint16_t classID(TR_RelocationTarget *reloTarget); - void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset); + void setClassChainOffset(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); }; @@ -1501,7 +1520,8 @@ class TR_RelocationRecordValidateMethodFromClassAndSig : public TR_RelocationRec void setLookupClassID(TR_RelocationTarget *reloTarget, uint16_t lookupClassID); uint16_t lookupClassID(TR_RelocationTarget *reloTarget); - void setRomMethodOffsetInSCC(TR_RelocationTarget *reloTarget, uintptr_t romMethodOffsetInSCC); + void setRomMethodOffsetInSCC(TR_RelocationTarget *reloTarget, uintptr_t romMethodOffsetInSCC, + TR::AheadOfTimeCompile *aotCompile, J9Method *method, TR_OpaqueClassBlock *definingClass); uintptr_t romMethodOffsetInSCC(TR_RelocationTarget *reloTarget); }; @@ -1702,10 +1722,14 @@ class TR_RelocationRecordPointer : public TR_RelocationRecordWithInlinedSiteInde virtual void print(TR_RelocationRuntime *reloRuntime); - void setClassChainIdentifyingLoaderOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache); + void setClassChainIdentifyingLoaderOffsetInSharedCache( + TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + ); uintptr_t classChainIdentifyingLoaderOffsetInSharedCache(TR_RelocationTarget *reloTarget); - void setClassChainForInlinedMethod(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache); + void setClassChainForInlinedMethod(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, + TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainForInlinedMethod(TR_RelocationTarget *reloTarget); virtual TR_RelocationRecordAction action(TR_RelocationRuntime *reloRuntime); diff --git a/runtime/compiler/x/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/x/codegen/J9AheadOfTimeCompile.cpp index a198c64cdeb..7ab79cc41bd 100644 --- a/runtime/compiler/x/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/x/codegen/J9AheadOfTimeCompile.cpp @@ -99,9 +99,12 @@ void J9::X86::AheadOfTimeCompile::processRelocations() if (useSVM) { TR::SymbolValidationManager *svm = comp->getSymbolValidationManager(); - void *offsets = const_cast(svm->wellKnownClassChainOffsets()); - *(uintptr_t *)relocationDataCursor = - self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); + void *offsets = const_cast(svm->wellKnownClassChainOffsets()); + uintptr_t *wkcOffsetAddr = (uintptr_t *)relocationDataCursor; + *wkcOffsetAddr = self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); +#if defined(J9VM_OPT_JITSERVER) + self()->addWellKnownClassesSerializationRecord(svm->aotCacheWellKnownClassesRecord(), wkcOffsetAddr); +#endif /* defined(J9VM_OPT_JITSERVER) */ relocationDataCursor += SIZEPOINTER; } diff --git a/runtime/compiler/z/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/z/codegen/J9AheadOfTimeCompile.cpp index 3578edf87fa..835a6d51ad3 100644 --- a/runtime/compiler/z/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/z/codegen/J9AheadOfTimeCompile.cpp @@ -102,11 +102,13 @@ void J9::Z::AheadOfTimeCompile::processRelocations() if (useSVM) { - TR::SymbolValidationManager *svm = - comp->getSymbolValidationManager(); - void *offsets = const_cast(svm->wellKnownClassChainOffsets()); - *(uintptr_t *)relocationDataCursor = - self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); + TR::SymbolValidationManager *svm = comp->getSymbolValidationManager(); + void *offsets = const_cast(svm->wellKnownClassChainOffsets()); + uintptr_t *wkcOffsetAddr = (uintptr_t *)relocationDataCursor; + *wkcOffsetAddr = self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets); +#if defined(J9VM_OPT_JITSERVER) + self()->addWellKnownClassesSerializationRecord(svm->aotCacheWellKnownClassesRecord(), wkcOffsetAddr); +#endif /* defined(J9VM_OPT_JITSERVER) */ relocationDataCursor += SIZEPOINTER; }