Skip to content

Commit

Permalink
Merge pull request #13962 from AlexeyKhrabrov/jitserver_aot_serializa…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
mpirvu committed Nov 25, 2021
2 parents 5cbb929 + 287721e commit 73dac1a
Show file tree
Hide file tree
Showing 23 changed files with 787 additions and 302 deletions.
17 changes: 10 additions & 7 deletions runtime/compiler/aarch64/codegen/J9AheadOfTimeCompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
{
Expand All @@ -64,19 +65,21 @@ 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;
relocationDataCursor += SIZEPOINTER;

if (useSVM)
{
TR::SymbolValidationManager *svm =
self()->comp()->getSymbolValidationManager();
void *offsets = const_cast<void*>(svm->wellKnownClassChainOffsets());
*(uintptr_t *)relocationDataCursor =
self()->offsetInSharedCacheFromPointer(fej9->sharedCache(), offsets);
TR::SymbolValidationManager *svm = comp->getSymbolValidationManager();
void *offsets = const_cast<void *>(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;
}

Expand Down
10 changes: 6 additions & 4 deletions runtime/compiler/arm/codegen/J9AheadOfTimeCompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ J9::ARM::AheadOfTimeCompile::initializePlatformSpecificAOTRelocationHeader(TR::I
TR_RelocationRecordArbitraryClassAddress *acaRecord = reinterpret_cast<TR_RelocationRecordArbitraryClassAddress *>(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();
Expand All @@ -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;

Expand Down
170 changes: 134 additions & 36 deletions runtime/compiler/codegen/J9AheadOfTimeCompile.cpp

Large diffs are not rendered by default.

110 changes: 106 additions & 4 deletions runtime/compiler/codegen/J9AheadOfTimeCompile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions runtime/compiler/compile/J9Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,12 @@ J9::Compilation::Compilation(int32_t id,
_remoteCompilation(false),
_serializedRuntimeAssumptions(getTypedAllocator<SerializedRuntimeAssumption *>(self()->allocator())),
_clientData(NULL),
_stream(NULL),
_globalMemory(*::trPersistentMemory, heapMemoryRegion),
_perClientMemory(_trMemory),
_methodsRequiringTrampolines(getTypedAllocator<TR_OpaqueMethodBlock *>(self()->allocator())),
_aotCacheStore(false),
_serializationRecords(decltype(_serializationRecords)::allocator_type(heapMemoryRegion)),
#endif /* defined(J9VM_OPT_JITSERVER) */
_osrProhibitedOverRangeOfTrees(false)
{
Expand Down Expand Up @@ -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) */
42 changes: 29 additions & 13 deletions runtime/compiler/compile/J9Compilation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -75,7 +80,6 @@ class ClientSessionData;
#define COMPILATION_AOT_RELOCATION_FAILED -20



namespace J9
{

Expand Down Expand Up @@ -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<SerializedRuntimeAssumption*>& getSerializedRuntimeAssumptions() { return _serializedRuntimeAssumptions; }

TR::list<SerializedRuntimeAssumption *> &getSerializedRuntimeAssumptions() { return _serializedRuntimeAssumptions; }

ClientSessionData *getClientData() const { return _clientData; }
void setClientData(ClientSessionData *clientData) { _clientData = clientData; }
void switchToPerClientMemory()
{
_trMemory = _perClientMemory;
}
void switchToGlobalMemory()
{
_trMemory = &_globalMemory;
}

TR::list<TR_OpaqueMethodBlock *>& 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<TR_OpaqueMethodBlock *> &getMethodsRequiringTrampolines() { return _methodsRequiringTrampolines; }

bool isAOTCacheStore() const { return _aotCacheStore; }
void setAOTCacheStore(bool store) { _aotCacheStore = store; }

Vector<std::pair<const AOTCacheRecord *, uintptr_t>> &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; }
Expand Down Expand Up @@ -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<SerializedRuntimeAssumption*> _serializedRuntimeAssumptions;
TR::list<SerializedRuntimeAssumption *> _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;
Expand All @@ -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;
Expand All @@ -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<std::pair<const AOTCacheRecord *, uintptr_t>> _serializationRecords;
#endif /* defined(J9VM_OPT_JITSERVER) */

TR::SymbolValidationManager *_symbolValidationManager;
Expand Down
4 changes: 4 additions & 0 deletions runtime/compiler/control/CompilationThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,7 @@ TR::CompilationInfo::CompilationInfo(J9JITConfig *jitConfig) :
_activationPolicy = JITServer::CompThreadActivationPolicy::AGGRESSIVE;
_sharedROMClassCache = NULL;
_JITServerAOTCacheMap = NULL;
_JITServerAOTDeserializer = NULL;
#endif /* defined(J9VM_OPT_JITSERVER) */
}

Expand Down Expand Up @@ -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<TR::CompilationInfoPerThreadRemote *>(that);
compiler->setAOTCacheStore(compInfoPTRemote->isAOTCacheStore());
}
#endif /* defined(J9VM_OPT_JITSERVER) */

Expand Down

0 comments on commit 73dac1a

Please sign in to comment.