Skip to content

Commit

Permalink
Merge pull request #20780 from cjjdespres/arbitrary-recovery
Browse files Browse the repository at this point in the history
Use dependency table as arbitrary class fallback
  • Loading branch information
mpirvu authored Dec 10, 2024
2 parents 6a1113a + 3aadacf commit 5329b1b
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 5329b1b

Please sign in to comment.