diff --git a/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp b/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp index d733a24cf8d..7dc19e2da14 100644 --- a/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp +++ b/runtime/compiler/codegen/J9AheadOfTimeCompile.cpp @@ -502,8 +502,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal fieldRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); fieldRecord->setConstantPool(reloTarget, reinterpret_cast(aotCI->_constantPool)); fieldRecord->setCpIndex(reloTarget, static_cast(aotCI->_cpIndex)); - fieldRecord->setClassChainOffsetInSharedCache(reloTarget, aotCI->_classChainOffset, - self(), aotCI->getAOTCacheClassChainRecord()); + fieldRecord->setClassChainOffsetInSharedCache(reloTarget, aotCI, self()); } break; @@ -601,8 +600,7 @@ 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, - self(), aotCI->getAOTCacheClassChainRecord()); + vsfRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache, self(), aotCI); } break; @@ -616,8 +614,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal vcRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); vcRecord->setConstantPool(reloTarget, reinterpret_cast(aotCI->_constantPool)); vcRecord->setCpIndex(reloTarget, aotCI->_cpIndex); - vcRecord->setClassChainOffsetInSharedCache(reloTarget, aotCI->_classChainOffset, - self(), aotCI->getAOTCacheClassChainRecord()); + vcRecord->setClassChainOffsetInSharedCache(reloTarget, aotCI, self()); } break; @@ -671,7 +668,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal pRecord->setInlinedSiteIndex(reloTarget, inlinedSiteIndex); pRecord->setConstantPool(reloTarget, reinterpret_cast(owningMethod->constantPool())); pRecord->setCpIndex(reloTarget, cpIndexOrData); - pRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache, self(), classChainRecord); + pRecord->setRomClassOffsetInSharedCache(reloTarget, romClassOffsetInSharedCache, self(), inlinedCodeClass, classChainRecord); pRecord->setClassChainIdentifyingLoaderOffsetInSharedCache(reloTarget, classChainIdentifyingLoaderOffsetInSharedCache, self(), classChainRecord); pRecord->setClassChainForInlinedMethod(reloTarget, classChainOffsetInSharedCache, self(), classChainRecord); @@ -758,8 +755,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal vacRecord->setClassChainIdentifyingLoaderOffset(reloTarget, classChainOffsetInSharedCacheForCL, self(), aotCI->getAOTCacheClassChainRecord()); - vacRecord->setClassChainOffsetForClassBeingValidated(reloTarget, aotCI->_classChainOffset, - self(), aotCI->getAOTCacheClassChainRecord()); + vacRecord->setClassChainOffsetForClassBeingValidated(reloTarget, aotCI, self()); } break; @@ -783,8 +779,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal cbnRecord->setClassID(reloTarget, symValManager->getSymbolIDFromValue(svmRecord->_class)); cbnRecord->setBeholderID(reloTarget, symValManager->getSymbolIDFromValue(svmRecord->_beholder)); - cbnRecord->setClassChainOffset(reloTarget, svmRecord->_classChainOffset, - self(), svmRecord->getAOTCacheClassChainRecord()); + cbnRecord->setClassChainOffset(reloTarget, svmRecord, self()); } break; @@ -801,8 +796,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal pcRecord->setClassID(reloTarget, symValManager->getSymbolIDFromValue(classToValidate)); //store the classchain's offset for the class that needs to be validated in the second run - pcRecord->setClassChainOffset(reloTarget, svmRecord->_classChainOffset, - self(), svmRecord->getAOTCacheClassChainRecord()); + pcRecord->setClassChainOffset(reloTarget, svmRecord, self()); pcRecord->setClassChainOffsetForClassLoader(reloTarget, classChainOffsetInSharedCacheForCL, self(), svmRecord->getAOTCacheClassChainRecord()); } @@ -892,8 +886,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal scmRecord->setSystemClassID(reloTarget, symValManager->getSymbolIDFromValue(classToValidate)); // Store class chain to get name of class. Checking the class chain for // this record eliminates the need for a separate class chain validation. - scmRecord->setClassChainOffset(reloTarget, svmRecord->_classChainOffset, - self(), svmRecord->getAOTCacheClassChainRecord()); + scmRecord->setClassChainOffset(reloTarget, svmRecord, self()); } break; @@ -943,8 +936,7 @@ J9::AheadOfTimeCompile::initializeCommonAOTRelocationHeader(TR::IteratedExternal ccRecord->setClassID(reloTarget, symValManager->getSymbolIDFromValue(classToValidate)); // Store class chain to get name of class. Checking the class chain for // this record eliminates the need for a separate class chain validation. - ccRecord->setClassChainOffset(reloTarget, svmRecord->_classChainOffset, - self(), svmRecord->getAOTCacheClassChainRecord()); + ccRecord->setClassChainOffset(reloTarget, svmRecord, self()); } break; @@ -2626,4 +2618,30 @@ void J9::AheadOfTimeCompile::processRelocations() relocationDataCursor += s->getSizeOfRelocationData(); } } +#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) + if (!comp->getOption(TR_DisableDependencyTracking)) + { + auto method = comp->getMethodBeingCompiled()->getPersistentIdentifier(); + auto definingClass = comp->fe()->getClassOfMethod(method); + + Vector dependencies(comp->trMemory()->currentStackRegion()); + uintptr_t totalDependencies = comp->populateAOTMethodDependencies(definingClass, dependencies); + + if (totalDependencies == 0) + { + // If there are zero dependencies, we skip storing the chain. This + // flag must still be set to distinguish methods with zero + // dependencies from methods with untracked dependencies. + comp->getAotMethodHeaderEntry()->flags |= TR_AOTMethodHeader_TracksDependencies; + } + else + { + auto sharedCache = fej9->sharedCache(); + auto vmThread = fej9->getCurrentVMThread(); + auto dependencyChain = sharedCache->storeAOTMethodDependencies(vmThread, method, definingClass, dependencies.data(), dependencies.size()); + if (dependencyChain) + comp->getAotMethodHeaderEntry()->flags |= TR_AOTMethodHeader_TracksDependencies; + } + } +#endif /* !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) */ } diff --git a/runtime/compiler/compile/AOTClassInfo.hpp b/runtime/compiler/compile/AOTClassInfo.hpp index ec31a2edb35..e0d391d8864 100644 --- a/runtime/compiler/compile/AOTClassInfo.hpp +++ b/runtime/compiler/compile/AOTClassInfo.hpp @@ -77,9 +77,9 @@ class AOTClassInfo } #if defined(J9VM_OPT_JITSERVER) - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return _aotCacheClassChainRecord; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return _aotCacheClassChainRecord; } #else /* defined(J9VM_OPT_JITSERVER) */ - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return NULL; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return NULL; } #endif /* defined(J9VM_OPT_JITSERVER) */ TR_ExternalRelocationTargetKind _reloKind; // identifies validation needed (instance field, static field, class, arbitrary class) diff --git a/runtime/compiler/compile/J9Compilation.cpp b/runtime/compiler/compile/J9Compilation.cpp index 9853d7a3a67..d649dcb6a90 100644 --- a/runtime/compiler/compile/J9Compilation.cpp +++ b/runtime/compiler/compile/J9Compilation.cpp @@ -34,6 +34,7 @@ #include "compile/Compilation.hpp" #include "compile/Compilation_inlines.hpp" #include "compile/CompilationTypes.hpp" +#include "env/DependencyTable.hpp" #include "compile/ResolvedMethod.hpp" #include "control/OptimizationPlan.hpp" #include "control/Options.hpp" @@ -205,6 +206,9 @@ J9::Compilation::Compilation(int32_t id, _serializationRecords(decltype(_serializationRecords)::allocator_type(heapMemoryRegion)), _thunkRecords(decltype(_thunkRecords)::allocator_type(heapMemoryRegion)), #endif /* defined(J9VM_OPT_JITSERVER) */ +#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) + _aotMethodDependencies(decltype(_aotMethodDependencies)::allocator_type(heapMemoryRegion)), +#endif /* !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) */ _osrProhibitedOverRangeOfTrees(false), _wasFearPointAnalysisDone(false) { @@ -1583,6 +1587,73 @@ J9::Compilation::canAddOSRAssumptions() && !self()->wasFearPointAnalysisDone(); } +#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) +void +J9::Compilation::addAOTMethodDependency(TR_OpaqueClassBlock *clazz) + { + if (getOption(TR_DisableDependencyTracking)) + return; + + auto chainOffset = self()->fej9()->sharedCache()->rememberClass(clazz); + + if (TR_SharedCache::INVALID_CLASS_CHAIN_OFFSET == chainOffset) + self()->failCompilation("classChainOffset == INVALID_CLASS_CHAIN_OFFSET"); + + addAOTMethodDependency(chainOffset, self()->fej9()->isClassInitialized(clazz)); + } + +void +J9::Compilation::addAOTMethodDependency(TR_OpaqueClassBlock *clazz, uintptr_t chainOffset) + { + if (getOption(TR_DisableDependencyTracking)) + return; + + addAOTMethodDependency(chainOffset, self()->fej9()->isClassInitialized(clazz)); + } + +void +J9::Compilation::addAOTMethodDependency(uintptr_t chainOffset, bool ensureClassIsInitialized) + { + TR_ASSERT(TR_SharedCache::INVALID_CLASS_CHAIN_OFFSET != chainOffset, "Attempted to remember invalid chain offset"); + TR_ASSERT(self()->compileRelocatableCode(), "Must be generating AOT code"); + + auto it = _aotMethodDependencies.find(chainOffset); + if (it != _aotMethodDependencies.end()) + it->second = it->second || ensureClassIsInitialized; + else + _aotMethodDependencies.insert(it, {chainOffset, ensureClassIsInitialized}); + } + +// Populate the given dependencyBuffer with dependencies of this method, in the +// format needed by TR_J9SharedCache::storeAOTMethodDependencies(). Returns the +// total number of dependencies. +uintptr_t +J9::Compilation::populateAOTMethodDependencies(TR_OpaqueClassBlock *definingClass, Vector &dependencyBuffer) + { + // TODO: Methods may be able to run before their defining class is + // initialized. Adding this back in will save a fair amount of space in the + // SCC once that's figured out. + // + // uintptr_t definingClassChainOffset = self()->fej9()->sharedCache()->rememberClass(definingClass); + // TR_ASSERT_FATAL(TR_SharedCache::INVALID_CLASS_CHAIN_OFFSET != definingClassChainOffset, "Defining class %p of an AOT-compiled method must be remembered"); + // _aotMethodDependencies.erase(definingClassChainOffset); + + uintptr_t totalDependencies = _aotMethodDependencies.size(); + if (totalDependencies == 0) + return totalDependencies; + + dependencyBuffer.reserve(totalDependencies + 1); + dependencyBuffer.push_back(totalDependencies); + for (auto &entry : _aotMethodDependencies) + { + uintptr_t encodedOffset = TR_AOTDependencyTable::encodeDependencyOffset(entry.first, entry.second); + dependencyBuffer.push_back(encodedOffset); + } + + return totalDependencies; + } +#endif /* !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) */ + #if defined(J9VM_OPT_JITSERVER) void J9::Compilation::addSerializationRecord(const AOTCacheRecord *record, uintptr_t reloDataOffset) diff --git a/runtime/compiler/compile/J9Compilation.hpp b/runtime/compiler/compile/J9Compilation.hpp index e20cdb44ebd..17895d5f0aa 100644 --- a/runtime/compiler/compile/J9Compilation.hpp +++ b/runtime/compiler/compile/J9Compilation.hpp @@ -42,9 +42,7 @@ 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; @@ -432,6 +430,15 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector void setOSRProhibitedOverRangeOfTrees() { _osrProhibitedOverRangeOfTrees = true; } bool isOSRProhibitedOverRangeOfTrees() { return _osrProhibitedOverRangeOfTrees; } +#if defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) + void addAOTMethodDependency(TR_OpaqueClassBlock *ramClass) {} + void addAOTMethodDependency(TR_OpaqueClassBlock *ramClass, uintptr_t chainOffset) {} +#else + void addAOTMethodDependency(TR_OpaqueClassBlock *ramClass); + void addAOTMethodDependency(TR_OpaqueClassBlock *ramClass, uintptr_t chainOffset); + uintptr_t populateAOTMethodDependencies(TR_OpaqueClassBlock *definingClass, Vector &chainBuffer); +#endif + private: enum CachedClassPointerId { @@ -446,6 +453,10 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector TR_OpaqueClassBlock *getCachedClassPointer(CachedClassPointerId which); +#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) + void addAOTMethodDependency(uintptr_t offset, bool classIsInitialized); +#endif /* !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) */ + J9VMThread *_j9VMThread; bool _doneHWProfile; @@ -561,6 +572,14 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector UnorderedSet _thunkRecords; #endif /* defined(J9VM_OPT_JITSERVER) */ +#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) + // A map recording the dependencies of an AOT method. The keys are the class + // chain offsets of classes this method depends on, and the values record + // whether the class needs to be initialized before method loading, or only + // loaded. + UnorderedMap _aotMethodDependencies; +#endif /* defined(PERSISTENT_COLLECTIONS_UNSUPPORTED) */ + TR::SymbolValidationManager *_symbolValidationManager; bool _osrProhibitedOverRangeOfTrees; bool _wasFearPointAnalysisDone; diff --git a/runtime/compiler/control/CompilationThread.cpp b/runtime/compiler/control/CompilationThread.cpp index f7a7b9aefd1..2a3f77c5ed8 100644 --- a/runtime/compiler/control/CompilationThread.cpp +++ b/runtime/compiler/control/CompilationThread.cpp @@ -8632,6 +8632,9 @@ TR::CompilationInfoPerThreadBase::wrappedCompile(J9PortLibrary *portLib, void * options->setOption(TR_UseSymbolValidationManager, false); } + if (!vm->canTrackAOTDependencies() || !that->_compInfo.getPersistentInfo()->getTrackAOTDependencies()) + options->setOption(TR_DisableDependencyTracking); + // Adjust Options for AOT compilation if (vm->isAOT_DEPRECATED_DO_NOT_USE()) { diff --git a/runtime/compiler/control/JITClientCompilationThread.cpp b/runtime/compiler/control/JITClientCompilationThread.cpp index 5343e0b20d7..7e2d4fd0c81 100644 --- a/runtime/compiler/control/JITClientCompilationThread.cpp +++ b/runtime/compiler/control/JITClientCompilationThread.cpp @@ -3322,6 +3322,15 @@ remoteCompile(J9VMThread *vmThread, TR::Compilation *compiler, TR_ResolvedMethod } compiler->setIgnoringLocalSCC(aotCacheStore && compiler->getPersistentInfo()->getJITServerAOTCacheIgnoreLocalSCC()); + // TODO: To support dependency tracking with the JITServer AOT cache while + // ignoring the local SCC, we would have to store the dependencies at the + // server and detect (with the help of the server's serialization records) + // when they were satisfied. More limited support also makes sense when not + // ignoring the local SCC - the dependencies would just have to be saved at + // the server so they could be sent to and stored by the client. + if (aotCacheLoad || aotCacheStore) + compiler->setOption(TR_DisableDependencyTracking); + // This thread may have been notified at some point in the past that the deserializer was reset. // Since this is the start of a new compilation, we must clear the reset flag in order to detect // a concurrent deserializer reset during the course of this compilation. This clearing must diff --git a/runtime/compiler/env/J9SharedCache.cpp b/runtime/compiler/env/J9SharedCache.cpp index 4833fa373e2..b65939cdcab 100644 --- a/runtime/compiler/env/J9SharedCache.cpp +++ b/runtime/compiler/env/J9SharedCache.cpp @@ -1636,11 +1636,11 @@ 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::Compilation *comp = _compInfoPT->getCompilation(); + TR_ASSERT_FATAL(classChainRecord || !create || !comp->isAOTCacheStore(), "Must pass classChainRecord if creating class chain at JITServer"); TR_ASSERT(_stream, "stream must be initialized by now"); uintptr_t clientClassChainOffset = TR_SharedCache::INVALID_CLASS_CHAIN_OFFSET; - TR::Compilation *comp = _compInfoPT->getCompilation(); ClientSessionData *clientData = comp->getClientData(); bool needClassChainRecord = comp->isAOTCacheStore(); bool useServerOffsets = clientData->useServerOffsets(_stream) && needClassChainRecord; diff --git a/runtime/compiler/env/VMJ9.h b/runtime/compiler/env/VMJ9.h index 05d9a76e8c1..ee51cb39e56 100644 --- a/runtime/compiler/env/VMJ9.h +++ b/runtime/compiler/env/VMJ9.h @@ -243,6 +243,7 @@ class TR_J9VMBase : public TR_FrontEnd virtual bool needsContiguousCodeAndDataCacheAllocation() { return false; } virtual bool supportsJitMethodEntryAlignment() { return true; } virtual bool canUseSymbolValidationManager() { return false; } + virtual bool canTrackAOTDependencies() { return false; } ///// // Inlining optimization @@ -1632,6 +1633,7 @@ class TR_J9SharedCacheVM : public TR_J9VM // replacing calls to isAOT virtual bool canUseSymbolValidationManager() { return true; } + virtual bool canTrackAOTDependencies() { return true; } virtual bool supportsCodeCacheSnippets() { return false; } virtual bool needClassAndMethodPointerRelocations() { return true; } virtual bool inlinedAllocationsMustBeVerified() { return true; } diff --git a/runtime/compiler/env/VMJ9Server.hpp b/runtime/compiler/env/VMJ9Server.hpp index 1248c847750..2766fde1b52 100644 --- a/runtime/compiler/env/VMJ9Server.hpp +++ b/runtime/compiler/env/VMJ9Server.hpp @@ -301,6 +301,7 @@ class TR_J9SharedCacheServerVM: public TR_J9ServerVM // replacing calls to isAOT virtual bool canUseSymbolValidationManager() override { return true; } + virtual bool canTrackAOTDependencies() override { return true; } virtual bool supportsCodeCacheSnippets() override { return false; } virtual bool needClassAndMethodPointerRelocations() override { return true; } virtual bool inlinedAllocationsMustBeVerified() override { return true; } diff --git a/runtime/compiler/runtime/RelocationRecord.cpp b/runtime/compiler/runtime/RelocationRecord.cpp index 887d40c75aa..9e453f0174e 100644 --- a/runtime/compiler/runtime/RelocationRecord.cpp +++ b/runtime/compiler/runtime/RelocationRecord.cpp @@ -30,6 +30,7 @@ #include "j9cp.h" #include "j9protos.h" #include "rommeth.h" +#include "codegen/AheadOfTimeCompile.hpp" #include "codegen/CodeGenerator.hpp" #include "env/FrontEnd.hpp" #include "codegen/PicHelpers.hpp" @@ -56,7 +57,6 @@ #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" @@ -2692,11 +2692,12 @@ TR_RelocationRecordInlinedMethod::print(TR_RelocationRuntime *reloRuntime) void TR_RelocationRecordInlinedMethod::setRomClassOffsetInSharedCache( TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR::AheadOfTimeCompile *aotCompile, TR_OpaqueClassBlock *ramClass, const AOTCacheClassChainRecord *classChainRecord ) { uintptr_t *addr = &((TR_RelocationRecordInlinedMethodBinaryTemplate *)_record)->_romClassOffsetInSharedCache; reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, addr); + aotCompile->comp()->addAOTMethodDependency(ramClass); #if defined(J9VM_OPT_JITSERVER) aotCompile->addClassSerializationRecord(classChainRecord, addr); #endif /* defined(J9VM_OPT_JITSERVER) */ @@ -2708,6 +2709,7 @@ TR_RelocationRecordInlinedMethod::setRomClassOffsetInSharedCache(TR_RelocationTa { uintptr_t *addr = &((TR_RelocationRecordInlinedMethodBinaryTemplate *)_record)->_romClassOffsetInSharedCache; reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, addr); + aotCompile->comp()->addAOTMethodDependency(ramClass); #if defined(J9VM_OPT_JITSERVER) aotCompile->addClassSerializationRecord(ramClass, addr); #endif /* defined(J9VM_OPT_JITSERVER) */ @@ -3620,14 +3622,15 @@ TR_RelocationRecordValidateClass::print(TR_RelocationRuntime *reloRuntime) void TR_RelocationRecordValidateClass::setClassChainOffsetInSharedCache( - TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR_RelocationTarget *reloTarget, const TR::AOTClassInfo *aotCI, + TR::AheadOfTimeCompile *aotCompile ) { uintptr_t *addr = &((TR_RelocationRecordValidateClassBinaryTemplate *)_record)->_classChainOffsetInSharedCache; - reloTarget->storeRelocationRecordValue(classChainOffsetInSharedCache, addr); + reloTarget->storeRelocationRecordValue(aotCI->_classChainOffset, addr); + aotCompile->comp()->addAOTMethodDependency(aotCI->_clazz, aotCI->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassChainSerializationRecord(classChainRecord, addr); + aotCompile->addClassChainSerializationRecord(aotCI->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -3752,13 +3755,14 @@ TR_RelocationRecordValidateStaticField::print(TR_RelocationRuntime *reloRuntime) void TR_RelocationRecordValidateStaticField::setRomClassOffsetInSharedCache( TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR::AheadOfTimeCompile *aotCompile, TR::AOTClassInfo *aotCI ) { uintptr_t *addr = &((TR_RelocationRecordValidateStaticFieldBinaryTemplate *)_record)->_romClassOffsetInSharedCache; reloTarget->storeRelocationRecordValue(romClassOffsetInSharedCache, addr); + aotCompile->comp()->addAOTMethodDependency(aotCI->_clazz, aotCI->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassSerializationRecord(classChainRecord, addr); + aotCompile->addClassSerializationRecord(aotCI->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -3831,14 +3835,15 @@ TR_RelocationRecordValidateArbitraryClass::classChainIdentifyingLoaderOffset(TR_ void TR_RelocationRecordValidateArbitraryClass::setClassChainOffsetForClassBeingValidated( - TR_RelocationTarget *reloTarget, uintptr_t offset, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR_RelocationTarget *reloTarget, const TR::AOTClassInfo *aotCI, + TR::AheadOfTimeCompile *aotCompile ) { uintptr_t *addr = &((TR_RelocationRecordValidateArbitraryClassBinaryTemplate *)_record)->_classChainOffsetForClassBeingValidated; - reloTarget->storeRelocationRecordValue(offset, addr); + reloTarget->storeRelocationRecordValue(aotCI->_classChainOffset, addr); + aotCompile->comp()->addAOTMethodDependency(aotCI->_clazz, aotCI->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassChainSerializationRecord(classChainRecord, addr); + aotCompile->addClassChainSerializationRecord(aotCI->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -3936,14 +3941,16 @@ TR_RelocationRecordValidateClassByName::beholderID(TR_RelocationTarget *reloTarg void TR_RelocationRecordValidateClassByName::setClassChainOffset( - TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR_RelocationTarget *reloTarget, const TR::ClassValidationRecordWithChain *validationRecord, + TR::AheadOfTimeCompile *aotCompile ) { + TR::ClassValidationRecordWithChain *foo = NULL; uintptr_t *addr = &((TR_RelocationRecordValidateClassByNameBinaryTemplate *)_record)->_classChainOffsetInSCC; - reloTarget->storeRelocationRecordValue(classChainOffset, addr); + reloTarget->storeRelocationRecordValue(validationRecord->_classChainOffset, addr); + aotCompile->comp()->addAOTMethodDependency(validationRecord->_class, validationRecord->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassChainSerializationRecord(classChainRecord, addr); + aotCompile->addClassChainSerializationRecord(validationRecord->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -3995,14 +4002,15 @@ TR_RelocationRecordValidateProfiledClass::classID(TR_RelocationTarget *reloTarge void TR_RelocationRecordValidateProfiledClass::setClassChainOffset( - TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR_RelocationTarget *reloTarget, const TR::ProfiledClassRecord *validationRecord, + TR::AheadOfTimeCompile *aotCompile ) { uintptr_t *addr = &((TR_RelocationRecordValidateProfiledClassBinaryTemplate *)_record)->_classChainOffsetInSCC; - reloTarget->storeRelocationRecordValue(classChainOffset, addr); + reloTarget->storeRelocationRecordValue(validationRecord->_classChainOffset, addr); + aotCompile->comp()->addAOTMethodDependency(validationRecord->_class, validationRecord->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassChainSerializationRecord(classChainRecord, addr); + aotCompile->addClassChainSerializationRecord(validationRecord->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -4395,14 +4403,15 @@ TR_RelocationRecordValidateSystemClassByName::systemClassID(TR_RelocationTarget void TR_RelocationRecordValidateSystemClassByName::setClassChainOffset( - TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR_RelocationTarget *reloTarget, const TR::ClassValidationRecordWithChain *validationRecord, + TR::AheadOfTimeCompile *aotCompile ) { uintptr_t *addr = &((TR_RelocationRecordValidateSystemClassByNameBinaryTemplate *)_record)->_classChainOffsetInSCC; - reloTarget->storeRelocationRecordValue(classChainOffset, addr); + reloTarget->storeRelocationRecordValue(validationRecord->_classChainOffset, addr); + aotCompile->comp()->addAOTMethodDependency(validationRecord->_class, validationRecord->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassChainSerializationRecord(classChainRecord, addr); + aotCompile->addClassChainSerializationRecord(validationRecord->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } @@ -4487,14 +4496,15 @@ TR_RelocationRecordValidateClassChain::classID(TR_RelocationTarget *reloTarget) void TR_RelocationRecordValidateClassChain::setClassChainOffset( - TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord + TR_RelocationTarget *reloTarget, const TR::ClassChainRecord *validationRecord, + TR::AheadOfTimeCompile *aotCompile ) { uintptr_t *addr = &((TR_RelocationRecordValidateClassChainBinaryTemplate *)_record)->_classChainOffsetInSCC; - reloTarget->storeRelocationRecordValue(classChainOffset, addr); + reloTarget->storeRelocationRecordValue(validationRecord->_classChainOffset, addr); + aotCompile->comp()->addAOTMethodDependency(validationRecord->_class, validationRecord->_classChainOffset); #if defined(J9VM_OPT_JITSERVER) - aotCompile->addClassChainSerializationRecord(classChainRecord, addr); + aotCompile->addClassChainSerializationRecord(validationRecord->getAOTCacheClassChainRecord(), addr); #endif /* defined(J9VM_OPT_JITSERVER) */ } diff --git a/runtime/compiler/runtime/RelocationRecord.hpp b/runtime/compiler/runtime/RelocationRecord.hpp index 151b85ad055..699129f54a4 100644 --- a/runtime/compiler/runtime/RelocationRecord.hpp +++ b/runtime/compiler/runtime/RelocationRecord.hpp @@ -785,7 +785,7 @@ class TR_RelocationRecordInlinedMethod : public TR_RelocationRecordConstantPoolW virtual void print(TR_RelocationRuntime *reloRuntime); void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + TR::AheadOfTimeCompile *aotCompile, TR_OpaqueClassBlock *ramClass, const AOTCacheClassChainRecord *classChainRecord); void setRomClassOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t romClassOffsetInSharedCache, TR::AheadOfTimeCompile *aotCompile, TR_OpaqueClassBlock *ramClass); uintptr_t romClassOffsetInSharedCache(TR_RelocationTarget *reloTarget); @@ -1084,8 +1084,7 @@ class TR_RelocationRecordValidateClass : public TR_RelocationRecordConstantPoolW virtual bool isStaticFieldValidation() { return false ; } - void setClassChainOffsetInSharedCache(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetInSharedCache, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setClassChainOffsetInSharedCache(TR_RelocationTarget *reloTarget, const TR::AOTClassInfo *aotCI, TR::AheadOfTimeCompile *aotCompile); uintptr_t classChainOffsetInSharedCache(TR_RelocationTarget *reloTarget); virtual TR_RelocationErrorCode applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation); @@ -1119,8 +1118,7 @@ class TR_RelocationRecordValidateStaticField : public TR_RelocationRecordValidat virtual bool isStaticFieldValidation() { return true; } - 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::AOTClassInfo *aotCI); uintptr_t romClassOffsetInSharedCache(TR_RelocationTarget *reloTarget); protected: @@ -1140,8 +1138,7 @@ class TR_RelocationRecordValidateArbitraryClass : public TR_RelocationRecord TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); uintptr_t classChainIdentifyingLoaderOffset(TR_RelocationTarget *reloTarget); - void setClassChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget, uintptr_t classChainOffset, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setClassChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget, const TR::AOTClassInfo *aotCI, TR::AheadOfTimeCompile *aotCompile); uintptr_t classChainOffsetForClassBeingValidated(TR_RelocationTarget *reloTarget); virtual void preparePrivateData(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget); @@ -1168,8 +1165,7 @@ 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, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setClassChainOffset(TR_RelocationTarget *reloTarget, const TR::ClassValidationRecordWithChain *validationRecord, TR::AheadOfTimeCompile *aotCompile); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); }; @@ -1188,8 +1184,7 @@ 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, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setClassChainOffset(TR_RelocationTarget *reloTarget, const TR::ProfiledClassRecord *validationRecord, TR::AheadOfTimeCompile *aotCompile); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); void setClassChainOffsetForClassLoader(TR_RelocationTarget *reloTarget, uintptr_t classChainOffsetForCL, @@ -1334,8 +1329,7 @@ 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, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setClassChainOffset(TR_RelocationTarget *reloTarget, const TR::ClassValidationRecordWithChain *validationRecord, TR::AheadOfTimeCompile *aotCompile); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); }; @@ -1382,8 +1376,7 @@ 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, - TR::AheadOfTimeCompile *aotCompile, const AOTCacheClassChainRecord *classChainRecord); + void setClassChainOffset(TR_RelocationTarget *reloTarget, const TR::ClassChainRecord *validationRecord, TR::AheadOfTimeCompile *aotCompile); uintptr_t classChainOffset(TR_RelocationTarget *reloTarget); }; diff --git a/runtime/compiler/runtime/SymbolValidationManager.cpp b/runtime/compiler/runtime/SymbolValidationManager.cpp index ea3fba3ef0c..5ccee9b0c5b 100644 --- a/runtime/compiler/runtime/SymbolValidationManager.cpp +++ b/runtime/compiler/runtime/SymbolValidationManager.cpp @@ -762,7 +762,10 @@ TR::SymbolValidationManager::skipFieldRefClassRecord( if (classRefLen == definingClassLen && !memcmp(classRefName, definingClassName, classRefLen)) + { + comp()->addAOTMethodDependency(definingClass); return true; + } } return false; @@ -773,13 +776,22 @@ TR::SymbolValidationManager::addClassByNameRecord(TR_OpaqueClassBlock *clazz, TR { SVM_ASSERT_ALREADY_VALIDATED(this, beholder); if (isWellKnownClass(clazz)) + { + comp()->addAOTMethodDependency(clazz); return true; + } else if (clazz == beholder) + { return true; + } else if (anyClassFromCPRecordExists(clazz, beholder)) + { return true; // already have an equivalent ClassFromCP + } else + { return addClassRecordWithChain(new (_region) ClassByNameRecord(clazz, beholder)); + } } bool @@ -813,9 +825,14 @@ TR::SymbolValidationManager::addClassFromCPRecord(TR_OpaqueClassBlock *clazz, J9 TR_OpaqueClassBlock *beholder = _fej9->getClassFromCP(constantPoolOfBeholder); SVM_ASSERT_ALREADY_VALIDATED(this, beholder); if (isWellKnownClass(clazz)) + { + comp()->addAOTMethodDependency(clazz); return true; + } else if (clazz == beholder) + { return true; + } ClassByNameRecord byName(clazz, beholder); if (recordExists(&byName)) @@ -894,9 +911,14 @@ bool TR::SymbolValidationManager::addSystemClassByNameRecord(TR_OpaqueClassBlock *systemClass) { if (isWellKnownClass(systemClass)) + { + comp()->addAOTMethodDependency(systemClass); return true; + } else + { return addClassRecordWithChain(new (_region) SystemClassByNameRecord(systemClass)); + } } bool diff --git a/runtime/compiler/runtime/SymbolValidationManager.hpp b/runtime/compiler/runtime/SymbolValidationManager.hpp index 49f643e2c8f..8737de9bd4d 100644 --- a/runtime/compiler/runtime/SymbolValidationManager.hpp +++ b/runtime/compiler/runtime/SymbolValidationManager.hpp @@ -168,9 +168,9 @@ struct ClassValidationRecordWithChain : public ClassValidationRecord virtual void printFields(); #if defined(J9VM_OPT_JITSERVER) - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return _aotCacheClassChainRecord; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return _aotCacheClassChainRecord; } #else /* defined(J9VM_OPT_JITSERVER) */ - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return NULL; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return NULL; } #endif /* defined(J9VM_OPT_JITSERVER) */ TR_OpaqueClassBlock *_class; @@ -210,9 +210,9 @@ struct ProfiledClassRecord : public ClassValidationRecord virtual void printFields(); #if defined(J9VM_OPT_JITSERVER) - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return _aotCacheClassChainRecord; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return _aotCacheClassChainRecord; } #else /* defined(J9VM_OPT_JITSERVER) */ - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return NULL; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return NULL; } #endif /* defined(J9VM_OPT_JITSERVER) */ TR_OpaqueClassBlock *_class; @@ -403,9 +403,9 @@ struct ClassChainRecord : public SymbolValidationRecord virtual void printFields(); #if defined(J9VM_OPT_JITSERVER) - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return _aotCacheClassChainRecord; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return _aotCacheClassChainRecord; } #else /* defined(J9VM_OPT_JITSERVER) */ - const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() { return NULL; } + const AOTCacheClassChainRecord *getAOTCacheClassChainRecord() const { return NULL; } #endif /* defined(J9VM_OPT_JITSERVER) */ TR_OpaqueClassBlock *_class;