Skip to content

Commit

Permalink
Use dependency table as arbitrary class fallback
Browse files Browse the repository at this point in the history
For classes acquired via profiling, the dependency table can be used to
obtain candidates for relocation.

Signed-off-by: Christian Despres <[email protected]>
  • Loading branch information
cjjdespres committed Dec 9, 2024
1 parent e1af88f commit 3aadacf
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 12 deletions.
3 changes: 3 additions & 0 deletions runtime/compiler/compile/J9Compilation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector
// fails serialization by setting _aotCacheStore to false if we are not ignoring the client's SCC, and otherwise
// fails the compilation entirely.
void addThunkRecord(const AOTCacheThunkRecord *record);
#else
bool isDeserializedAOTMethod() const { return false; }
bool ignoringLocalSCC() const { return false; }
#endif /* defined(J9VM_OPT_JITSERVER) */

TR::SymbolValidationManager *getSymbolValidationManager() { return _symbolValidationManager; }
Expand Down
38 changes: 35 additions & 3 deletions runtime/compiler/env/DependencyTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "control/CompilationRuntime.hpp"
#include "control/CompilationThread.hpp"
#include "env/ClassLoaderTable.hpp"
#include "env/DependencyTable.hpp"
#include "env/J9SharedCache.hpp"
#include "env/PersistentCHTable.hpp"
Expand Down Expand Up @@ -469,9 +470,32 @@ TR_AOTDependencyTable::resolvePendingLoads()
_pendingLoads.clear();
}

TR_OpaqueClassBlock *
TR_AOTDependencyTable::findClassCandidate(uintptr_t romClassOffset)
J9Class *
TR_AOTDependencyTable::findCandidateWithChainAndLoader(TR::Compilation *comp, uintptr_t classChainOffset, void *classLoaderChain)
{
if (comp->isDeserializedAOTMethod() || comp->ignoringLocalSCC())
return NULL;

auto classChain = (uintptr_t *)_sharedCache->pointerFromOffsetInSharedCache(classChainOffset);
return findChainLoaderCandidate(comp, classChain, classLoaderChain);
}

J9Class *
TR_AOTDependencyTable::findCandidateWithChainAndLoader(TR::Compilation *comp, uintptr_t *classChain, void *classLoaderChain)
{
if (comp->isDeserializedAOTMethod() || comp->ignoringLocalSCC())
return NULL;

return findChainLoaderCandidate(comp, classChain, classLoaderChain);
}

J9Class *
TR_AOTDependencyTable::findChainLoaderCandidate(TR::Compilation *comp, uintptr_t *classChain, void *classLoaderChain)
{
TR_ASSERT_FATAL(classLoaderChain, "Must be given a loader chain");

uintptr_t romClassOffset = _sharedCache->startingROMClassOffsetOfClassChain(classChain);

OMR::CriticalSection cs(_tableMonitor);

if (!isActive())
Expand All @@ -481,7 +505,15 @@ TR_AOTDependencyTable::findClassCandidate(uintptr_t romClassOffset)
if (it == _offsetMap.end())
return NULL;

return (TR_OpaqueClassBlock *)findCandidateForDependency(it->second._loadedClasses, true);
for (const auto& clazz: it->second._loadedClasses)
{
// Init condition taken from jitGetClassInClassloaderFromUTF8()
if ((J9ClassInitFailed != clazz->initializeStatus) &&
(_sharedCache->persistentClassLoaderTable()->lookupClassChainAssociatedWithClassLoader(clazz->classLoader) == classLoaderChain))
return clazz;
}

return NULL;
}

void
Expand Down
12 changes: 8 additions & 4 deletions runtime/compiler/env/DependencyTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class TR_AOTDependencyTable
void classLoadEvent(TR_OpaqueClassBlock *ramClass, bool isClassLoad, bool isClassInitialization) {}
void invalidateUnloadedClass(TR_OpaqueClassBlock *ramClass) {}
void invalidateRedefinedClass(TR_PersistentCHTable *table, TR_J9VMBase *fej9, TR_OpaqueClassBlock *oldClass, TR_OpaqueClassBlock *freshClass) {}
TR_OpaqueClassBlock *findClassCandidate(uintptr_t offset) { return NULL; }
J9Class *findCandidateWithChainAndLoader(TR::Compilation *comp, uintptr_t classChainOffset, void *classLoaderChain) { return NULL; }
J9Class *findCandidateWithChainAndLoader(TR::Compilation *comp, uintptr_t *classChain, void *classLoaderChain) { return NULL; }
void methodWillBeCompiled(J9Method *method) {}
void printStats() {}
};
Expand Down Expand Up @@ -118,9 +119,11 @@ class TR_AOTDependencyTable
// RAM method of ramClass.
void invalidateRedefinedClass(TR_PersistentCHTable *table, TR_J9VMBase *fej9, TR_OpaqueClassBlock *oldClass, TR_OpaqueClassBlock *freshClass);

// Given a ROM class offset, return an initialized class with a valid class
// chain starting with that offset.
TR_OpaqueClassBlock *findClassCandidate(uintptr_t offset);
// Given a class chain and class loader chain, return an initialized class
// with a valid class chain starting with that offset and with a class loader
// with that loader chain
J9Class *findCandidateWithChainAndLoader(TR::Compilation *comp, uintptr_t classChainOffset, void *classLoaderChain);
J9Class *findCandidateWithChainAndLoader(TR::Compilation *comp, uintptr_t *classChain, void *classLoaderChain);

static uintptr_t decodeDependencyOffset(uintptr_t offset)
{
Expand Down Expand Up @@ -169,6 +172,7 @@ class TR_AOTDependencyTable
OffsetEntry *getOffsetEntry(uintptr_t offset, bool create);

J9Class *findCandidateForDependency(const PersistentUnorderedSet<J9Class *> &loadedClasses, bool needsInitialization);
J9Class *findChainLoaderCandidate(TR::Compilation *comp, uintptr_t *classChain, void *classLoaderChain);

// Stop tracking the given method. This will invalidate the MethodEntryRef
// for the method.
Expand Down
7 changes: 7 additions & 0 deletions runtime/compiler/runtime/RelocationRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "control/Options_inlines.hpp"
#include "env/CHTable.hpp"
#include "env/ClassLoaderTable.hpp"
#include "env/DependencyTable.hpp"
#include "env/PersistentCHTable.hpp"
#include "env/jittypes.h"
#include "env/VMAccessCriticalSection.hpp"
Expand Down Expand Up @@ -3363,6 +3364,12 @@ TR_RelocationRecordProfiledInlinedMethod::preparePrivateData(TR_RelocationRuntim
}
#endif /* defined(J9VM_OPT_JITSERVER) */
}
if (!inlinedCodeClass)
{
if (auto dependencyTable = reloRuntime->comp()->getPersistentInfo()->getAOTDependencyTable())
inlinedCodeClass = (TR_OpaqueClassBlock *)dependencyTable->findCandidateWithChainAndLoader(reloRuntime->comp(), classChainForInlinedMethod(reloTarget),
classChainIdentifyingLoader);
}
}

if (inlinedCodeClass)
Expand Down
17 changes: 12 additions & 5 deletions runtime/compiler/runtime/SymbolValidationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <string.h>
#include "env/VMJ9.h"
#include "env/ClassLoaderTable.hpp"
#include "env/DependencyTable.hpp"
#include "env/JSR292Methods.h"
#include "env/PersistentCHTable.hpp"
#include "env/VMAccessCriticalSection.hpp"
Expand Down Expand Up @@ -1255,13 +1256,19 @@ bool
TR::SymbolValidationManager::validateProfiledClassRecord(uint16_t classID, void *classChainIdentifyingLoader,
void *classChainForClassBeingValidated)
{
TR_OpaqueClassBlock *clazz = NULL;
J9ClassLoader *classLoader = (J9ClassLoader *)_fej9->sharedCache()->lookupClassLoaderAssociatedWithClassChain(classChainIdentifyingLoader);
if (classLoader == NULL)
return false;
if (classLoader)
{
clazz = _fej9->sharedCache()->lookupClassFromChainAndLoader(static_cast<uintptr_t *>(classChainForClassBeingValidated), classLoader, _comp);
}

if (!clazz)
{
if (auto dependencyTable = _comp->getPersistentInfo()->getAOTDependencyTable())
clazz = (TR_OpaqueClassBlock *)dependencyTable->findCandidateWithChainAndLoader(_comp, (uintptr_t *)classChainForClassBeingValidated, classChainIdentifyingLoader);
}

TR_OpaqueClassBlock *clazz = _fej9->sharedCache()->lookupClassFromChainAndLoader(
static_cast<uintptr_t *>(classChainForClassBeingValidated), classLoader, _comp
);
return validateSymbol(classID, clazz);
}

Expand Down

0 comments on commit 3aadacf

Please sign in to comment.