From 5837628d4d07e2257b25faecee5c6ecd5d4120b9 Mon Sep 17 00:00:00 2001 From: Christian Despres Date: Tue, 25 Oct 2022 15:30:44 +0000 Subject: [PATCH 1/2] Add a JITServer AOT cache read context Signed-off-by: Christian Despres --- .../compiler/runtime/JITServerAOTCache.cpp | 147 ++++++++---------- .../compiler/runtime/JITServerAOTCache.hpp | 72 ++------- 2 files changed, 72 insertions(+), 147 deletions(-) diff --git a/runtime/compiler/runtime/JITServerAOTCache.cpp b/runtime/compiler/runtime/JITServerAOTCache.cpp index d3543768466..ced715f83d2 100644 --- a/runtime/compiler/runtime/JITServerAOTCache.cpp +++ b/runtime/compiler/runtime/JITServerAOTCache.cpp @@ -27,6 +27,18 @@ #include "runtime/JITServerSharedROMClassCache.hpp" #include "net/CommunicationStream.hpp" +struct JITServerAOTCacheReadContext + { + JITServerAOTCacheReadContext(const JITServerAOTCacheHeader &header, TR::StackMemoryRegion &stackMemoryRegion); + + Vector _classLoaderRecords; + Vector _classRecords; + Vector _methodRecords; + Vector _classChainRecords; + Vector _wellKnownClassesRecords; + Vector _aotHeaderRecords; + }; + size_t JITServerAOTCacheMap::_cacheMaxBytes = 300 * 1024 * 1024; bool JITServerAOTCacheMap::_cacheIsFull = false; @@ -80,13 +92,7 @@ AOTCacheClassLoaderRecord::create(uintptr_t id, const uint8_t *name, size_t name } AOTCacheClassLoaderRecord * -AOTCacheClassLoaderRecord::read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) +AOTCacheClassLoaderRecord::read(FILE *f, const JITServerAOTCacheReadContext &context) { ClassLoaderSerializationRecord header; if (1 != fread(&header, sizeof(header), 1, f)) @@ -148,24 +154,18 @@ AOTCacheClassRecord::subRecordsDo(const std::function &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) +AOTCacheClassRecord::read(FILE *f, const JITServerAOTCacheReadContext &context) { ClassSerializationRecord header; if (1 != fread(&header, sizeof(header), 1, f)) return NULL; if (!header.isValid() || - (header.classLoaderId() >= classLoaderRecords.size()) || - !classLoaderRecords[header.classLoaderId()]) + (header.classLoaderId() >= context._classLoaderRecords.size()) || + !context._classLoaderRecords[header.classLoaderId()]) return NULL; - auto record = new (AOTCacheRecord::allocate(size(header.nameLength()))) AOTCacheClassRecord(classLoaderRecords[header.classLoaderId()]); + auto record = new (AOTCacheRecord::allocate(size(header.nameLength()))) AOTCacheClassRecord(context._classLoaderRecords[header.classLoaderId()]); memcpy((void *)record->dataAddr(), &header, sizeof(header)); if (1 != fread((uint8_t *)record->dataAddr() + sizeof(header), header.AOTSerializationRecord::size() - sizeof(header), 1, f)) { @@ -214,24 +214,18 @@ AOTCacheMethodRecord::subRecordsDo(const std::function &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) +AOTCacheMethodRecord::read(FILE *f, const JITServerAOTCacheReadContext &context) { MethodSerializationRecord header; if (1 != fread(&header, sizeof(header), 1, f)) return NULL; if (!header.isValid() || - (header.definingClassId() >= classRecords.size()) || - !classRecords[header.definingClassId()]) + (header.definingClassId() >= context._classRecords.size()) || + !context._classRecords[header.definingClassId()]) return NULL; - auto record = new (AOTCacheRecord::allocate(sizeof(AOTCacheMethodRecord))) AOTCacheMethodRecord(classRecords[header.definingClassId()]); + auto record = new (AOTCacheRecord::allocate(sizeof(AOTCacheMethodRecord))) AOTCacheMethodRecord(context._classRecords[header.definingClassId()]); memcpy((void *)record->dataAddr(), &header, sizeof(header)); return record; @@ -354,13 +348,7 @@ AOTCacheAOTHeaderRecord::create(uintptr_t id, const TR_AOTHeader *header) } AOTCacheAOTHeaderRecord * -AOTCacheAOTHeaderRecord::read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) +AOTCacheAOTHeaderRecord::read(FILE *f, const JITServerAOTCacheReadContext &context) { AOTHeaderSerializationRecord header; if (1 != fread(&header, sizeof(header), 1, f)) @@ -436,26 +424,20 @@ CachedAOTMethod::create(const AOTCacheClassChainRecord *definingClassChainRecord } CachedAOTMethod * -CachedAOTMethod::read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) +CachedAOTMethod::read(FILE *f, const JITServerAOTCacheReadContext &context) { SerializedAOTMethod header; if (1 != fread(&header, sizeof(header), 1, f)) return NULL; if ((!header.isValid()) || - (header.definingClassChainId() >= classChainRecords.size()) || - (header.aotHeaderId() >= aotHeaderRecords.size()) || - !classChainRecords[header.definingClassChainId()]) + (header.definingClassChainId() >= context._classChainRecords.size()) || + (header.aotHeaderId() >= context._aotHeaderRecords.size()) || + !context._classChainRecords[header.definingClassChainId()]) return NULL; auto record = new (AOTCacheRecord::allocate(size(header.numRecords(), header.codeSize(), header.dataSize()))) - CachedAOTMethod(classChainRecords[header.definingClassChainId()]); + CachedAOTMethod(context._classChainRecords[header.definingClassChainId()]); memcpy(&record->_data, &header, sizeof(header)); if (1 != fread(record->data().offsets(), sizeof(SerializedSCCOffset) * header.numRecords() + header.codeSize() + header.dataSize(), 1, f)) @@ -468,29 +450,29 @@ CachedAOTMethod::read(FILE *f, switch (sccOffset.recordType()) { case AOTSerializationRecordType::ClassLoader: - if ((sccOffset.recordId() >= classLoaderRecords.size()) || !classLoaderRecords[sccOffset.recordId()]) + if ((sccOffset.recordId() >= context._classLoaderRecords.size()) || !context._classLoaderRecords[sccOffset.recordId()]) goto error; - record->records()[i] = classLoaderRecords[sccOffset.recordId()]; + record->records()[i] = context._classLoaderRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::Class: - if ((sccOffset.recordId() >= classRecords.size()) || !classRecords[sccOffset.recordId()]) + if ((sccOffset.recordId() >= context._classRecords.size()) || !context._classRecords[sccOffset.recordId()]) goto error; - record->records()[i] = classRecords[sccOffset.recordId()]; + record->records()[i] = context._classRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::Method: - if ((sccOffset.recordId() >= methodRecords.size()) || !methodRecords[sccOffset.recordId()]) + if ((sccOffset.recordId() >= context._methodRecords.size()) || !context._methodRecords[sccOffset.recordId()]) goto error; - record->records()[i] = methodRecords[sccOffset.recordId()]; + record->records()[i] = context._methodRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::ClassChain: - if ((sccOffset.recordId() >= classChainRecords.size()) || !classChainRecords[sccOffset.recordId()]) + if ((sccOffset.recordId() >= context._classChainRecords.size()) || !context._classChainRecords[sccOffset.recordId()]) goto error; - record->records()[i] = classChainRecords[sccOffset.recordId()]; + record->records()[i] = context._classChainRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::WellKnownClasses: - if ((sccOffset.recordId() >= wellKnownClassesRecords.size()) || !wellKnownClassesRecords[sccOffset.recordId()]) + if ((sccOffset.recordId() >= context._wellKnownClassesRecords.size()) || !context._wellKnownClassesRecords[sccOffset.recordId()]) goto error; - record->records()[i] = wellKnownClassesRecords[sccOffset.recordId()]; + record->records()[i] = context._wellKnownClassesRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::AOTHeader: // never associated with an SCC offset default: @@ -736,6 +718,15 @@ JITServerAOTCache::~JITServerAOTCache() TR::Monitor::destroy(_cachedMethodMonitor); } +JITServerAOTCacheReadContext::JITServerAOTCacheReadContext(const JITServerAOTCacheHeader &header, TR::StackMemoryRegion &stackMemoryRegion) : + _classLoaderRecords(header._nextClassLoaderId, NULL, stackMemoryRegion), + _classRecords(header._nextClassId, NULL, stackMemoryRegion), + _methodRecords(header._nextMethodId, NULL, stackMemoryRegion), + _classChainRecords(header._nextClassChainId, NULL, stackMemoryRegion), + _wellKnownClassesRecords(header._nextWellKnownClassesId, NULL, stackMemoryRegion), + _aotHeaderRecords(header._nextAOTHeaderId, NULL, stackMemoryRegion) + { + } // Helper macros to make the code for printing class and method names to vlog more concise #define RECORD_NAME(record) (int)(record).nameLength(), (const char *)(record).name() @@ -1276,24 +1267,19 @@ JITServerAOTCache::readCache(FILE *f, const std::string &name, TR_Memory &trMemo // updating the map, record traversal, and scratch Vector associated with V. template bool JITServerAOTCache::readRecords(FILE *f, + JITServerAOTCacheReadContext &context, size_t numRecordsToRead, PersistentUnorderedMap &map, V *&traversalHead, V *&traversalTail, - Vector &records, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) + Vector &records) { for (size_t i = 0; i < numRecordsToRead; ++i) { if (!JITServerAOTCacheMap::cacheHasSpace()) return false; - V *record = V::read(f, classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords); + V *record = V::read(f, context); if (!record) return false; @@ -1330,30 +1316,20 @@ JITServerAOTCache::readCache(FILE *f, const JITServerAOTCacheHeader &header, TR_ _nextAOTHeaderId = header._nextAOTHeaderId; TR::StackMemoryRegion stackMemoryRegion(trMemory); - Vector classLoaderRecords(header._nextClassLoaderId, NULL, stackMemoryRegion); - Vector classRecords(header._nextClassId, NULL, stackMemoryRegion); - Vector methodRecords(header._nextMethodId, NULL, stackMemoryRegion); - Vector classChainRecords(header._nextClassChainId, NULL, stackMemoryRegion); - Vector wellKnownClassesRecords(header._nextWellKnownClassesId, NULL, stackMemoryRegion); - Vector aotHeaderRecords(header._nextAOTHeaderId, NULL, stackMemoryRegion); - - if (!readRecords(f, header._numClassLoaderRecords, _classLoaderMap, _classLoaderHead, _classLoaderTail, classLoaderRecords, - classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords)) + JITServerAOTCacheReadContext context(header, stackMemoryRegion); + + if (!readRecords(f, context, header._numClassLoaderRecords, _classLoaderMap, _classLoaderHead, _classLoaderTail, context._classLoaderRecords)) return false; - if (!readRecords(f, header._numClassRecords, _classMap, _classHead, _classTail, classRecords, - classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords)) + if (!readRecords(f, context, header._numClassRecords, _classMap, _classHead, _classTail, context._classRecords)) return false; - if (!readRecords(f, header._numMethodRecords, _methodMap, _methodHead, _methodTail, methodRecords, - classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords)) + if (!readRecords(f, context, header._numMethodRecords, _methodMap, _methodHead, _methodTail, context._methodRecords)) return false; - if (!readRecords(f, header._numClassChainRecords, _classChainMap, _classChainHead, _classChainTail, classChainRecords, - classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords)) + if (!readRecords(f, context, header._numClassChainRecords, _classChainMap, _classChainHead, _classChainTail, context._classChainRecords)) return false; - if (!readRecords(f, header._numWellKnownClassesRecords, _wellKnownClassesMap, _wellKnownClassesHead, _wellKnownClassesTail, wellKnownClassesRecords, - classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords)) + if (!readRecords(f, context, header._numWellKnownClassesRecords, _wellKnownClassesMap, _wellKnownClassesHead, + _wellKnownClassesTail, context._wellKnownClassesRecords)) return false; - if (!readRecords(f, header._numAOTHeaderRecords, _aotHeaderMap, _aotHeaderHead, _aotHeaderTail, aotHeaderRecords, - classLoaderRecords, classRecords, methodRecords, classChainRecords, wellKnownClassesRecords, aotHeaderRecords)) + if (!readRecords(f, context, header._numAOTHeaderRecords, _aotHeaderMap, _aotHeaderHead, _aotHeaderTail, context._aotHeaderRecords)) return false; for (size_t i = 0; i < header._numCachedAOTMethods; ++i) @@ -1361,16 +1337,15 @@ JITServerAOTCache::readCache(FILE *f, const JITServerAOTCacheHeader &header, TR_ if (!JITServerAOTCacheMap::cacheHasSpace()) return false; - auto record = CachedAOTMethod::read(f, classLoaderRecords, classRecords, methodRecords, - classChainRecords, wellKnownClassesRecords, aotHeaderRecords); + auto record = CachedAOTMethod::read(f, context); - if (!record || !aotHeaderRecords[record->data().aotHeaderId()]) + if (!record || !context._aotHeaderRecords[record->data().aotHeaderId()]) return false; CachedMethodKey key(record->definingClassChainRecord(), record->data().index(), record->data().optLevel(), - aotHeaderRecords[record->data().aotHeaderId()]); + context._aotHeaderRecords[record->data().aotHeaderId()]); if (!addToMap(_cachedMethodMap, _cachedMethodHead, _cachedMethodTail, key, record)) { diff --git a/runtime/compiler/runtime/JITServerAOTCache.hpp b/runtime/compiler/runtime/JITServerAOTCache.hpp index 35018af1f2c..96ed792e42b 100644 --- a/runtime/compiler/runtime/JITServerAOTCache.hpp +++ b/runtime/compiler/runtime/JITServerAOTCache.hpp @@ -126,13 +126,7 @@ class AOTCacheClassLoaderRecord final : public AOTCacheRecord static AOTCacheClassLoaderRecord *create(uintptr_t id, const uint8_t *name, size_t nameLength); - static AOTCacheClassLoaderRecord *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords); + static AOTCacheClassLoaderRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); private: AOTCacheClassLoaderRecord(uintptr_t id, const uint8_t *name, size_t nameLength); @@ -158,13 +152,7 @@ class AOTCacheClassRecord final : public AOTCacheRecord const JITServerROMClassHash &hash, const J9ROMClass *romClass); void subRecordsDo(const std::function &f) const override; - static AOTCacheClassRecord *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords); + static AOTCacheClassRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); private: AOTCacheClassRecord(uintptr_t id, const AOTCacheClassLoaderRecord *classLoaderRecord, @@ -191,13 +179,7 @@ class AOTCacheMethodRecord final : public AOTCacheRecord static AOTCacheMethodRecord *create(uintptr_t id, const AOTCacheClassRecord *definingClassRecord, uint32_t index); void subRecordsDo(const std::function &f) const override; - static AOTCacheMethodRecord *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords); + static AOTCacheMethodRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); private: AOTCacheMethodRecord(uintptr_t id, const AOTCacheClassRecord *definingClassRecord, uint32_t index); @@ -247,14 +229,8 @@ class AOTCacheClassChainRecord final : public AOTCacheListRecordclassLoaderRecord(); } - static AOTCacheClassChainRecord *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) - { return (AOTCacheClassChainRecord *)AOTCacheListRecord::read(f, classRecords); } + static AOTCacheClassChainRecord *read(FILE *f, const JITServerAOTCacheReadContext &context) + { return (AOTCacheClassChainRecord *)AOTCacheListRecord::read(f, context._classRecords); } private: using AOTCacheListRecord::AOTCacheListRecord; @@ -268,15 +244,9 @@ class AOTCacheWellKnownClassesRecord final : static AOTCacheWellKnownClassesRecord *create(uintptr_t id, const AOTCacheClassChainRecord *const *records, size_t length, uintptr_t includedClasses); - static AOTCacheWellKnownClassesRecord *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords) + static AOTCacheWellKnownClassesRecord *read(FILE *f, const JITServerAOTCacheReadContext &context) { return (AOTCacheWellKnownClassesRecord *) - AOTCacheListRecord::read(f, classChainRecords); } + AOTCacheListRecord::read(f, context._classChainRecords); } private: using AOTCacheListRecord::AOTCacheListRecord; @@ -291,13 +261,7 @@ class AOTCacheAOTHeaderRecord final : public AOTCacheRecord static AOTCacheAOTHeaderRecord *create(uintptr_t id, const TR_AOTHeader *header); - static AOTCacheAOTHeaderRecord *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords); + static AOTCacheAOTHeaderRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); private: AOTCacheAOTHeaderRecord(uintptr_t id, const TR_AOTHeader *header); @@ -328,15 +292,7 @@ class CachedAOTMethod const Vector> &records, const void *code, size_t codeSize, const void *data, size_t dataSize); - static CachedAOTMethod *read(FILE *f, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords); - - static CachedAOTMethod *read(FILE *f, const Vector &classChainRecords); + static CachedAOTMethod *read(FILE *f, const JITServerAOTCacheReadContext &context); CachedAOTMethod *getNextRecord() const { return _nextRecord; } void setNextRecord(CachedAOTMethod *record) { _nextRecord = record; } @@ -503,14 +459,8 @@ class JITServerAOTCache bool readCache(FILE *f, const JITServerAOTCacheHeader &header, TR_Memory &trMemory); template - static bool readRecords(FILE *f, size_t numRecordsToRead, PersistentUnorderedMap &map, V *&traversalHead, V *&traversalTail, - Vector &records, - const Vector &classLoaderRecords, - const Vector &classRecords, - const Vector &methodRecords, - const Vector &classChainRecords, - const Vector &wellKnownClassesRecords, - const Vector &aotHeaderRecords); + static bool readRecords(FILE *f, JITServerAOTCacheReadContext &context, size_t numRecordsToRead, + PersistentUnorderedMap &map, V *&traversalHead, V *&traversalTail, Vector &records); const std::string _name; From be39468dad4dcaf59a3db59b9d2bd3c5d648b081 Mon Sep 17 00:00:00 2001 From: Christian Despres Date: Mon, 31 Oct 2022 15:23:37 +0000 Subject: [PATCH 2/2] Unify JITServer AOT cache read functions Signed-off-by: Christian Despres --- .../compiler/runtime/JITServerAOTCache.cpp | 252 +++++++----------- .../compiler/runtime/JITServerAOTCache.hpp | 87 ++++-- .../JITServerAOTSerializationRecords.hpp | 39 ++- 3 files changed, 192 insertions(+), 186 deletions(-) diff --git a/runtime/compiler/runtime/JITServerAOTCache.cpp b/runtime/compiler/runtime/JITServerAOTCache.cpp index ced715f83d2..4b0c210168a 100644 --- a/runtime/compiler/runtime/JITServerAOTCache.cpp +++ b/runtime/compiler/runtime/JITServerAOTCache.cpp @@ -58,8 +58,41 @@ AOTCacheRecord::free(void *ptr) TR::Compiler->persistentGlobalMemory()->freePersistentMemory(ptr); } +// Read a single AOT cache record R from a cache file +template R * +AOTCacheRecord::readRecord(FILE *f, const JITServerAOTCacheReadContext &context) + { + typename R::SerializationRecord header; + if (1 != fread(&header, sizeof(header), 1, f)) + return NULL; + + if (!header.isValidHeader(context)) + return NULL; + + R *record = new (AOTCacheRecord::allocate(R::size(header))) R(context, header); + memcpy((void *)record->dataAddr(), &header, sizeof(header)); + + size_t variableDataBytes = record->dataAddr()->size() - sizeof(header); + if (0 != variableDataBytes) + { + if (1 != fread((uint8_t *)record->dataAddr() + sizeof(header), variableDataBytes, 1, f)) + { + AOTCacheRecord::free(record); + return NULL; + } + } + + if (!record->setSubrecordPointers(context)) + { + AOTCacheRecord::free(record); + return NULL; + } + + return record; + } + bool -AOTSerializationRecord::isValid(AOTSerializationRecordType type) const +AOTSerializationRecord::isValidHeader(AOTSerializationRecordType type) const { return (type == this->type()) && (0 != this->id()); @@ -91,27 +124,6 @@ AOTCacheClassLoaderRecord::create(uintptr_t id, const uint8_t *name, size_t name return new (ptr) AOTCacheClassLoaderRecord(id, name, nameLength); } -AOTCacheClassLoaderRecord * -AOTCacheClassLoaderRecord::read(FILE *f, const JITServerAOTCacheReadContext &context) - { - ClassLoaderSerializationRecord header; - if (1 != fread(&header, sizeof(header), 1, f)) - return NULL; - - if (!header.isValid()) - return NULL; - - auto record = new (AOTCacheRecord::allocate(size(header.nameLength()))) AOTCacheClassLoaderRecord(); - memcpy((void *)record->dataAddr(), &header, sizeof(header)); - if (1 != fread((uint8_t *)record->dataAddr() + sizeof(header), header.AOTSerializationRecord::size() - sizeof(header), 1, f)) - { - AOTCacheRecord::free(record); - return NULL; - } - - return record; - } - ClassSerializationRecord::ClassSerializationRecord(uintptr_t id, uintptr_t classLoaderId, const JITServerROMClassHash &hash, const J9ROMClass *romClass) : AOTSerializationRecord(size(J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass))), id, AOTSerializationRecordType::Class), @@ -127,6 +139,14 @@ ClassSerializationRecord::ClassSerializationRecord() : { } +bool +ClassSerializationRecord::isValidHeader(const JITServerAOTCacheReadContext &context) const + { + return AOTSerializationRecord::isValidHeader(AOTSerializationRecordType::Class) && + (classLoaderId() < context._classLoaderRecords.size()) && + context._classLoaderRecords[classLoaderId()]; + } + AOTCacheClassRecord::AOTCacheClassRecord(uintptr_t id, const AOTCacheClassLoaderRecord *classLoaderRecord, const JITServerROMClassHash &hash, const J9ROMClass *romClass) : _classLoaderRecord(classLoaderRecord), @@ -134,8 +154,8 @@ AOTCacheClassRecord::AOTCacheClassRecord(uintptr_t id, const AOTCacheClassLoader { } -AOTCacheClassRecord::AOTCacheClassRecord(const AOTCacheClassLoaderRecord *classLoaderRecord) : - _classLoaderRecord(classLoaderRecord) +AOTCacheClassRecord::AOTCacheClassRecord(const JITServerAOTCacheReadContext &context, const ClassSerializationRecord &header) : + _classLoaderRecord(context._classLoaderRecords[header.classLoaderId()]) { } @@ -153,29 +173,6 @@ AOTCacheClassRecord::subRecordsDo(const std::function= context._classLoaderRecords.size()) || - !context._classLoaderRecords[header.classLoaderId()]) - return NULL; - - auto record = new (AOTCacheRecord::allocate(size(header.nameLength()))) AOTCacheClassRecord(context._classLoaderRecords[header.classLoaderId()]); - memcpy((void *)record->dataAddr(), &header, sizeof(header)); - if (1 != fread((uint8_t *)record->dataAddr() + sizeof(header), header.AOTSerializationRecord::size() - sizeof(header), 1, f)) - { - AOTCacheRecord::free(record); - return NULL; - } - - return record; - } - MethodSerializationRecord::MethodSerializationRecord(uintptr_t id, uintptr_t definingClassId, uint32_t index) : AOTSerializationRecord(sizeof(*this), id, AOTSerializationRecordType::Method), _definingClassId(definingClassId), _index(index) @@ -188,6 +185,14 @@ MethodSerializationRecord::MethodSerializationRecord() : { } +bool +MethodSerializationRecord::isValidHeader(const JITServerAOTCacheReadContext &context) const + { + return AOTSerializationRecord::isValidHeader(AOTSerializationRecordType::Method) && + (definingClassId() < context._classRecords.size()) && + context._classRecords[definingClassId()]; + } + AOTCacheMethodRecord::AOTCacheMethodRecord(uintptr_t id, const AOTCacheClassRecord *definingClassRecord, uint32_t index) : _definingClassRecord(definingClassRecord), @@ -195,8 +200,8 @@ AOTCacheMethodRecord::AOTCacheMethodRecord(uintptr_t id, const AOTCacheClassReco { } -AOTCacheMethodRecord::AOTCacheMethodRecord(const AOTCacheClassRecord *definingClassRecord) : - _definingClassRecord(definingClassRecord) +AOTCacheMethodRecord::AOTCacheMethodRecord(const JITServerAOTCacheReadContext &context, const MethodSerializationRecord &header) : + _definingClassRecord(context._classRecords[header.definingClassId()]) { } @@ -213,24 +218,6 @@ AOTCacheMethodRecord::subRecordsDo(const std::function= context._classRecords.size()) || - !context._classRecords[header.definingClassId()]) - return NULL; - - auto record = new (AOTCacheRecord::allocate(sizeof(AOTCacheMethodRecord))) AOTCacheMethodRecord(context._classRecords[header.definingClassId()]); - memcpy((void *)record->dataAddr(), &header, sizeof(header)); - - return record; - } - template AOTCacheListRecord::AOTCacheListRecord(uintptr_t id, const R *const *records, size_t length, Args... args) : @@ -248,37 +235,19 @@ AOTCacheListRecord::subRecordsDo(const std::function AOTCacheListRecord* -AOTCacheListRecord::read(FILE *f, const Vector &cacheRecords) +template bool +AOTCacheListRecord::setSubrecordPointers(const Vector &cacheRecords) { - D header; - if (1 != fread(&header, sizeof(header), 1, f)) - return NULL; - - if (!header.isValid()) - return NULL; - - auto record = new (AOTCacheRecord::allocate(size(header.list().length()))) AOTCacheListRecord(); - memcpy((void *)record->dataAddr(), &header, sizeof(header)); - - if (1 != fread((uint8_t *)record->dataAddr() + sizeof(header), header.AOTSerializationRecord::size() - sizeof(header), 1, f)) - { - AOTCacheRecord::free(record); - return NULL; - } - - for (size_t i = 0; i < header.list().length(); ++i) + for (size_t i = 0; i < data().list().length(); ++i) { - uintptr_t id = record->data().list().ids()[i]; + uintptr_t id = data().list().ids()[i]; if ((id >= cacheRecords.size()) || !cacheRecords[id]) { - AOTCacheRecord::free(record); - return NULL; + return false; } - record->records()[i] = cacheRecords[id]; + records()[i] = cacheRecords[id]; } - - return record; + return true; } ClassChainSerializationRecord::ClassChainSerializationRecord(uintptr_t id, size_t length) : @@ -300,6 +269,11 @@ AOTCacheClassChainRecord::create(uintptr_t id, const AOTCacheClassRecord *const return new (ptr) AOTCacheClassChainRecord(id, records, length); } +bool +AOTCacheClassChainRecord::setSubrecordPointers(const JITServerAOTCacheReadContext &context) + { + return AOTCacheListRecord::setSubrecordPointers(context._classRecords); + } WellKnownClassesSerializationRecord::WellKnownClassesSerializationRecord(uintptr_t id, size_t length, uintptr_t includedClasses) : @@ -322,6 +296,11 @@ AOTCacheWellKnownClassesRecord::create(uintptr_t id, const AOTCacheClassChainRec return new (ptr) AOTCacheWellKnownClassesRecord(id, records, length, includedClasses); } +bool +AOTCacheWellKnownClassesRecord::setSubrecordPointers(const JITServerAOTCacheReadContext &context) + { + return AOTCacheListRecord::setSubrecordPointers(context._classChainRecords); + } AOTHeaderSerializationRecord::AOTHeaderSerializationRecord(uintptr_t id, const TR_AOTHeader *header) : AOTSerializationRecord(sizeof(*this), id, AOTSerializationRecordType::AOTHeader), @@ -347,22 +326,6 @@ AOTCacheAOTHeaderRecord::create(uintptr_t id, const TR_AOTHeader *header) return new (ptr) AOTCacheAOTHeaderRecord(id, header); } -AOTCacheAOTHeaderRecord * -AOTCacheAOTHeaderRecord::read(FILE *f, const JITServerAOTCacheReadContext &context) - { - AOTHeaderSerializationRecord header; - if (1 != fread(&header, sizeof(header), 1, f)) - return NULL; - - if (!header.isValid()) - return NULL; - - auto record = new (AOTCacheRecord::allocate(sizeof(AOTCacheAOTHeaderRecord))) AOTCacheAOTHeaderRecord(); - memcpy((void *)record->dataAddr(), &header, sizeof(header)); - - return record; - } - SerializedAOTMethod::SerializedAOTMethod(uintptr_t definingClassChainId, uint32_t index, TR_Hotness optLevel, uintptr_t aotHeaderId, size_t numRecords, const void *code, size_t codeSize, const void *data, size_t dataSize) : @@ -384,9 +347,13 @@ SerializedAOTMethod::SerializedAOTMethod() : } bool -SerializedAOTMethod::isValid() const +SerializedAOTMethod::isValidHeader(const JITServerAOTCacheReadContext &context) const { - return _optLevel < TR_Hotness::numHotnessLevels; + return _optLevel < TR_Hotness::numHotnessLevels && + (definingClassChainId() < context._classChainRecords.size()) && + (aotHeaderId() < context._aotHeaderRecords.size()) && + context._classChainRecords[definingClassChainId()] && + context._aotHeaderRecords[aotHeaderId()]; } CachedAOTMethod::CachedAOTMethod(const AOTCacheClassChainRecord *definingClassChainRecord, uint32_t index, @@ -406,9 +373,9 @@ CachedAOTMethod::CachedAOTMethod(const AOTCacheClassChainRecord *definingClassCh } } -CachedAOTMethod::CachedAOTMethod(const AOTCacheClassChainRecord *definingClassChainRecord) : +CachedAOTMethod::CachedAOTMethod(const JITServerAOTCacheReadContext &context, const SerializedAOTMethod &header) : _nextRecord(NULL), - _definingClassChainRecord(definingClassChainRecord) + _definingClassChainRecord(context._classChainRecords[header.definingClassChainId()]) { } @@ -423,68 +390,48 @@ CachedAOTMethod::create(const AOTCacheClassChainRecord *definingClassChainRecord records, code, codeSize, data, dataSize); } -CachedAOTMethod * -CachedAOTMethod::read(FILE *f, const JITServerAOTCacheReadContext &context) +bool +CachedAOTMethod::setSubrecordPointers(const JITServerAOTCacheReadContext &context) { - SerializedAOTMethod header; - if (1 != fread(&header, sizeof(header), 1, f)) - return NULL; - - if ((!header.isValid()) || - (header.definingClassChainId() >= context._classChainRecords.size()) || - (header.aotHeaderId() >= context._aotHeaderRecords.size()) || - !context._classChainRecords[header.definingClassChainId()]) - return NULL; - - auto record = new (AOTCacheRecord::allocate(size(header.numRecords(), header.codeSize(), header.dataSize()))) - CachedAOTMethod(context._classChainRecords[header.definingClassChainId()]); - memcpy(&record->_data, &header, sizeof(header)); - - if (1 != fread(record->data().offsets(), sizeof(SerializedSCCOffset) * header.numRecords() + header.codeSize() + header.dataSize(), 1, f)) - goto error; - - for (size_t i = 0; i < header.numRecords(); ++i) + // The defining class chain record pointer for the record will have been set by the CachedAOTMethod constructor at this point + for (size_t i = 0; i < data().numRecords(); ++i) { - const SerializedSCCOffset &sccOffset = record->data().offsets()[i]; + const SerializedSCCOffset &sccOffset = data().offsets()[i]; switch (sccOffset.recordType()) { case AOTSerializationRecordType::ClassLoader: if ((sccOffset.recordId() >= context._classLoaderRecords.size()) || !context._classLoaderRecords[sccOffset.recordId()]) - goto error; - record->records()[i] = context._classLoaderRecords[sccOffset.recordId()]; + return false; + records()[i] = context._classLoaderRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::Class: if ((sccOffset.recordId() >= context._classRecords.size()) || !context._classRecords[sccOffset.recordId()]) - goto error; - record->records()[i] = context._classRecords[sccOffset.recordId()]; + return false; + records()[i] = context._classRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::Method: if ((sccOffset.recordId() >= context._methodRecords.size()) || !context._methodRecords[sccOffset.recordId()]) - goto error; - record->records()[i] = context._methodRecords[sccOffset.recordId()]; + return false; + records()[i] = context._methodRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::ClassChain: if ((sccOffset.recordId() >= context._classChainRecords.size()) || !context._classChainRecords[sccOffset.recordId()]) - goto error; - record->records()[i] = context._classChainRecords[sccOffset.recordId()]; + return false; + records()[i] = context._classChainRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::WellKnownClasses: if ((sccOffset.recordId() >= context._wellKnownClassesRecords.size()) || !context._wellKnownClassesRecords[sccOffset.recordId()]) - goto error; - record->records()[i] = context._wellKnownClassesRecords[sccOffset.recordId()]; + return false; + records()[i] = context._wellKnownClassesRecords[sccOffset.recordId()]; break; case AOTSerializationRecordType::AOTHeader: // never associated with an SCC offset default: - goto error; + return false; } } - return record; - -error: - AOTCacheRecord::free(record); - return NULL; + return true; } bool @@ -1279,7 +1226,7 @@ JITServerAOTCache::readRecords(FILE *f, if (!JITServerAOTCacheMap::cacheHasSpace()) return false; - V *record = V::read(f, context); + V *record = AOTCacheRecord::readRecord(f, context); if (!record) return false; @@ -1337,9 +1284,8 @@ JITServerAOTCache::readCache(FILE *f, const JITServerAOTCacheHeader &header, TR_ if (!JITServerAOTCacheMap::cacheHasSpace()) return false; - auto record = CachedAOTMethod::read(f, context); - - if (!record || !context._aotHeaderRecords[record->data().aotHeaderId()]) + auto record = AOTCacheRecord::readRecord(f, context); + if (!record) return false; CachedMethodKey key(record->definingClassChainRecord(), diff --git a/runtime/compiler/runtime/JITServerAOTCache.hpp b/runtime/compiler/runtime/JITServerAOTCache.hpp index 96ed792e42b..f90ead18565 100644 --- a/runtime/compiler/runtime/JITServerAOTCache.hpp +++ b/runtime/compiler/runtime/JITServerAOTCache.hpp @@ -107,6 +107,8 @@ class AOTCacheRecord static void *allocate(size_t size); static void free(void *ptr); + template static R *readRecord(FILE *f, const JITServerAOTCacheReadContext &context); + AOTCacheRecord *getNextRecord() const { return _nextRecord; } void setNextRecord(AOTCacheRecord *record) { _nextRecord = record; } @@ -114,6 +116,10 @@ class AOTCacheRecord AOTCacheRecord() : _nextRecord(NULL) {} private: + // Set the subrecord pointers in the variable-length portion of a record if necessary. + // The subrecord pointers in the statically-sized portion of a record are set in the record constructors. + virtual bool setSubrecordPointers(const JITServerAOTCacheReadContext &context) { return true; } + AOTCacheRecord *_nextRecord; }; @@ -126,17 +132,21 @@ class AOTCacheClassLoaderRecord final : public AOTCacheRecord static AOTCacheClassLoaderRecord *create(uintptr_t id, const uint8_t *name, size_t nameLength); - static AOTCacheClassLoaderRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); - private: + using SerializationRecord = ClassLoaderSerializationRecord; + + friend AOTCacheClassLoaderRecord *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + AOTCacheClassLoaderRecord(uintptr_t id, const uint8_t *name, size_t nameLength); - AOTCacheClassLoaderRecord() {} + AOTCacheClassLoaderRecord(const JITServerAOTCacheReadContext &context, const ClassLoaderSerializationRecord &header) {} static size_t size(size_t nameLength) { return offsetof(AOTCacheClassLoaderRecord, _data) + ClassLoaderSerializationRecord::size(nameLength); } + static size_t size(const ClassLoaderSerializationRecord &header) { return size(header.nameLength()); } + const ClassLoaderSerializationRecord _data; }; @@ -152,18 +162,22 @@ class AOTCacheClassRecord final : public AOTCacheRecord const JITServerROMClassHash &hash, const J9ROMClass *romClass); void subRecordsDo(const std::function &f) const override; - static AOTCacheClassRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); - private: + using SerializationRecord = ClassSerializationRecord; + + friend AOTCacheClassRecord *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + AOTCacheClassRecord(uintptr_t id, const AOTCacheClassLoaderRecord *classLoaderRecord, const JITServerROMClassHash &hash, const J9ROMClass *romClass); - AOTCacheClassRecord(const AOTCacheClassLoaderRecord *classLoaderRecord); + AOTCacheClassRecord(const JITServerAOTCacheReadContext &context, const ClassSerializationRecord &header); static size_t size(size_t nameLength) { return offsetof(AOTCacheClassRecord, _data) + ClassSerializationRecord::size(nameLength); } + static size_t size(const ClassSerializationRecord &header) { return size(header.nameLength()); } + const AOTCacheClassLoaderRecord *const _classLoaderRecord; const ClassSerializationRecord _data; }; @@ -179,11 +193,15 @@ class AOTCacheMethodRecord final : public AOTCacheRecord static AOTCacheMethodRecord *create(uintptr_t id, const AOTCacheClassRecord *definingClassRecord, uint32_t index); void subRecordsDo(const std::function &f) const override; - static AOTCacheMethodRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); - private: + using SerializationRecord = MethodSerializationRecord; + + friend AOTCacheMethodRecord *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + AOTCacheMethodRecord(uintptr_t id, const AOTCacheClassRecord *definingClassRecord, uint32_t index); - AOTCacheMethodRecord(const AOTCacheClassRecord *definingClassRecord); + AOTCacheMethodRecord(const JITServerAOTCacheReadContext &context, const MethodSerializationRecord &header); + + static size_t size(const MethodSerializationRecord &header) { return sizeof(AOTCacheMethodRecord); } const AOTCacheClassRecord *const _definingClassRecord; const MethodSerializationRecord _data; @@ -205,17 +223,19 @@ class AOTCacheListRecord : public AOTCacheRecord void subRecordsDo(const std::function &f) const override; - static AOTCacheListRecord *read(FILE *f, const Vector &cacheRecords); - protected: AOTCacheListRecord(uintptr_t id, const R *const *records, size_t length, Args... args); - AOTCacheListRecord() {} + AOTCacheListRecord(const JITServerAOTCacheReadContext &context, const D &header) {} static size_t size(size_t length) { return offsetof(AOTCacheListRecord, _data) + D::size(length) + length * sizeof(R *); } + static size_t size(const D &header) { return size(header.list().length()); } + + bool setSubrecordPointers(const Vector &cacheRecords); + // Layout: struct D header, uintptr_t ids[length], const R *records[length] D _data; }; @@ -229,10 +249,13 @@ class AOTCacheClassChainRecord final : public AOTCacheListRecordclassLoaderRecord(); } - static AOTCacheClassChainRecord *read(FILE *f, const JITServerAOTCacheReadContext &context) - { return (AOTCacheClassChainRecord *)AOTCacheListRecord::read(f, context._classRecords); } - private: + using SerializationRecord = ClassChainSerializationRecord; + + friend AOTCacheClassChainRecord *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + + bool setSubrecordPointers(const JITServerAOTCacheReadContext &context) override; + using AOTCacheListRecord::AOTCacheListRecord; }; @@ -244,11 +267,13 @@ class AOTCacheWellKnownClassesRecord final : static AOTCacheWellKnownClassesRecord *create(uintptr_t id, const AOTCacheClassChainRecord *const *records, size_t length, uintptr_t includedClasses); - static AOTCacheWellKnownClassesRecord *read(FILE *f, const JITServerAOTCacheReadContext &context) - { return (AOTCacheWellKnownClassesRecord *) - AOTCacheListRecord::read(f, context._classChainRecords); } - private: + using SerializationRecord = WellKnownClassesSerializationRecord; + + friend AOTCacheWellKnownClassesRecord *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + + bool setSubrecordPointers(const JITServerAOTCacheReadContext &context) override; + using AOTCacheListRecord::AOTCacheListRecord; }; @@ -261,11 +286,15 @@ class AOTCacheAOTHeaderRecord final : public AOTCacheRecord static AOTCacheAOTHeaderRecord *create(uintptr_t id, const TR_AOTHeader *header); - static AOTCacheAOTHeaderRecord *read(FILE *f, const JITServerAOTCacheReadContext &context); - private: + using SerializationRecord = AOTHeaderSerializationRecord; + + friend AOTCacheAOTHeaderRecord *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + AOTCacheAOTHeaderRecord(uintptr_t id, const TR_AOTHeader *header); - AOTCacheAOTHeaderRecord() {} + AOTCacheAOTHeaderRecord(const JITServerAOTCacheReadContext &context, const AOTHeaderSerializationRecord &header) {} + + static size_t size(const AOTHeaderSerializationRecord &header) { return sizeof(AOTHeaderSerializationRecord); } const AOTHeaderSerializationRecord _data; }; @@ -292,17 +321,21 @@ class CachedAOTMethod const Vector> &records, const void *code, size_t codeSize, const void *data, size_t dataSize); - static CachedAOTMethod *read(FILE *f, const JITServerAOTCacheReadContext &context); - CachedAOTMethod *getNextRecord() const { return _nextRecord; } void setNextRecord(CachedAOTMethod *record) { _nextRecord = record; } private: + using SerializationRecord = SerializedAOTMethod; + + friend CachedAOTMethod *AOTCacheRecord::readRecord<>(FILE *f, const JITServerAOTCacheReadContext &context); + CachedAOTMethod(const AOTCacheClassChainRecord *definingClassChainRecord, uint32_t index, TR_Hotness optLevel, const AOTCacheAOTHeaderRecord *aotHeaderRecord, const Vector> &records, const void *code, size_t codeSize, const void *data, size_t dataSize); - CachedAOTMethod(const AOTCacheClassChainRecord *definingClassChainRecord); + CachedAOTMethod(const JITServerAOTCacheReadContext &context, const SerializedAOTMethod &header); + + SerializedAOTMethod *dataAddr() { return &_data; } static size_t size(size_t numRecords, size_t codeSize, size_t dataSize) { @@ -310,6 +343,10 @@ class CachedAOTMethod numRecords * sizeof(AOTCacheRecord *); } + static size_t size(const SerializedAOTMethod &header) { return size(header.numRecords(), header.codeSize(), header.dataSize()); } + + bool setSubrecordPointers(const JITServerAOTCacheReadContext &context); + CachedAOTMethod *_nextRecord; const AOTCacheClassChainRecord *const _definingClassChainRecord; SerializedAOTMethod _data; diff --git a/runtime/compiler/runtime/JITServerAOTSerializationRecords.hpp b/runtime/compiler/runtime/JITServerAOTSerializationRecords.hpp index 3afcfd244f5..dacca2db031 100644 --- a/runtime/compiler/runtime/JITServerAOTSerializationRecords.hpp +++ b/runtime/compiler/runtime/JITServerAOTSerializationRecords.hpp @@ -27,6 +27,7 @@ #include "runtime/JITServerROMClassHash.hpp" #include "runtime/RelocationRuntime.hpp" +struct JITServerAOTCacheReadContext; enum AOTSerializationRecordType { @@ -64,7 +65,6 @@ struct AOTSerializationRecord //NOTE: 0 signifies an invalid record ID uintptr_t id() const { return getId(_idAndType); } AOTSerializationRecordType type() const { return getType(_idAndType); } - bool isValid(AOTSerializationRecordType type) const; const uint8_t *end() const { return (const uint8_t *)this + size(); } static const AOTSerializationRecord *get(const std::string &str) @@ -96,6 +96,11 @@ struct AOTSerializationRecord AOTSerializationRecord(size_t size, uintptr_t id, AOTSerializationRecordType type) : _size(size), _idAndType(idAndType(id, type)) { } + // Check the well-formedness of the statically-sized portion of a serialization record. + // The variable-sized portion can't be checked here, only in setSubrecordPointers, as it + // is read based on the information in the statically-sized portion. + bool isValidHeader(AOTSerializationRecordType type) const; + private: static const uintptr_t idShift = 3; static const uintptr_t typeMask = (1 << idShift) - 1; @@ -111,9 +116,9 @@ struct ClassLoaderSerializationRecord : public AOTSerializationRecord public: size_t nameLength() const { return _nameLength; } const uint8_t *name() const { return _name; } - bool isValid() const { return AOTSerializationRecord::isValid(AOTSerializationRecordType::ClassLoader); } private: + friend class AOTCacheRecord; friend class AOTCacheClassLoaderRecord; ClassLoaderSerializationRecord(uintptr_t id, const uint8_t *name, size_t nameLength); @@ -124,6 +129,9 @@ struct ClassLoaderSerializationRecord : public AOTSerializationRecord return sizeof(ClassLoaderSerializationRecord) + OMR::alignNoCheck(nameLength, sizeof(size_t)); } + bool isValidHeader(const JITServerAOTCacheReadContext &context) const + { return AOTSerializationRecord::isValidHeader(AOTSerializationRecordType::ClassLoader); } + // Name of the 1st class loaded by the class loader const size_t _nameLength; uint8_t _name[]; @@ -138,9 +146,9 @@ struct ClassSerializationRecord : public AOTSerializationRecord uint32_t romClassSize() const { return _romClassSize; } size_t nameLength() const { return _nameLength; } const uint8_t *name() const { return _name; } - bool isValid() const { return AOTSerializationRecord::isValid(AOTSerializationRecordType::Class); } private: + friend class AOTCacheRecord; friend class AOTCacheClassRecord; ClassSerializationRecord(uintptr_t id, uintptr_t classLoaderId, @@ -152,6 +160,8 @@ struct ClassSerializationRecord : public AOTSerializationRecord return sizeof(ClassSerializationRecord) + OMR::alignNoCheck(nameLength, sizeof(size_t)); } + bool isValidHeader(const JITServerAOTCacheReadContext &context) const; + const uintptr_t _classLoaderId; const JITServerROMClassHash _hash; // Used to quickly detect class mismatches (without computing the hash) when ROMClass size is different @@ -167,14 +177,16 @@ struct MethodSerializationRecord : public AOTSerializationRecord public: uintptr_t definingClassId() const { return _definingClassId; } uint32_t index() const { return _index; } - bool isValid() const { return AOTSerializationRecord::isValid(AOTSerializationRecordType::Method); } private: + friend class AOTCacheRecord; friend class AOTCacheMethodRecord; MethodSerializationRecord(uintptr_t id, uintptr_t definingClassId, uint32_t index); MethodSerializationRecord(); + bool isValidHeader(const JITServerAOTCacheReadContext &context) const; + const uintptr_t _definingClassId; // Index in the array of methods of the defining class const uint32_t _index; @@ -202,9 +214,9 @@ struct ClassChainSerializationRecord : public AOTSerializationRecord { public: const IdList &list() const { return _list; } - bool isValid() const { return AOTSerializationRecord::isValid(AOTSerializationRecordType::ClassChain); } private: + friend class AOTCacheRecord; template friend class AOTCacheListRecord; ClassChainSerializationRecord(uintptr_t id, size_t length); @@ -217,6 +229,9 @@ struct ClassChainSerializationRecord : public AOTSerializationRecord return offsetof(ClassChainSerializationRecord, _list) + IdList::size(length); } + bool isValidHeader(const JITServerAOTCacheReadContext &context) const + { return AOTSerializationRecord::isValidHeader(AOTSerializationRecordType::ClassChain); } + // List of class IDs IdList _list; }; @@ -227,9 +242,9 @@ struct WellKnownClassesSerializationRecord : public AOTSerializationRecord public: uintptr_t includedClasses() const { return _includedClasses; } const IdList &list() const { return _list; } - bool isValid() const { return AOTSerializationRecord::isValid(AOTSerializationRecordType::WellKnownClasses); } private: + friend class AOTCacheRecord; template friend class AOTCacheListRecord; WellKnownClassesSerializationRecord(uintptr_t id, size_t length, uintptr_t includedClasses); @@ -242,6 +257,9 @@ struct WellKnownClassesSerializationRecord : public AOTSerializationRecord return offsetof(WellKnownClassesSerializationRecord, _list) + IdList::size(length); } + bool isValidHeader(const JITServerAOTCacheReadContext &context) const + { return AOTSerializationRecord::isValidHeader(AOTSerializationRecordType::WellKnownClasses); } + // Bit mask representing which classes out of the predefined well-known set are included const uintptr_t _includedClasses; // List of class chain IDs @@ -253,14 +271,17 @@ struct AOTHeaderSerializationRecord : public AOTSerializationRecord { public: const TR_AOTHeader *header() const { return &_header; } - bool isValid() const { return AOTSerializationRecord::isValid(AOTSerializationRecordType::AOTHeader); } private: + friend class AOTCacheRecord; friend class AOTCacheAOTHeaderRecord; AOTHeaderSerializationRecord(uintptr_t id, const TR_AOTHeader *header); AOTHeaderSerializationRecord(); + bool isValidHeader(const JITServerAOTCacheReadContext &context) const + { return AOTSerializationRecord::isValidHeader(AOTSerializationRecordType::AOTHeader); } + const TR_AOTHeader _header; }; @@ -307,7 +328,6 @@ struct SerializedAOTMethod const uint8_t *data() const { return code() + _codeSize; } uint8_t *data() { return (uint8_t *)(code() + _codeSize); } const uint8_t *end() const { return (const uint8_t *)this + size(); } - bool isValid() const; static SerializedAOTMethod *get(std::string &str) { @@ -317,6 +337,7 @@ struct SerializedAOTMethod } private: + friend class AOTCacheRecord; friend class CachedAOTMethod; SerializedAOTMethod(uintptr_t definingClassChainId, uint32_t index, @@ -330,6 +351,8 @@ struct SerializedAOTMethod OMR::alignNoCheck(codeSize + dataSize, sizeof(size_t)); } + bool isValidHeader(const JITServerAOTCacheReadContext &context) const; + const size_t _size; const uintptr_t _definingClassChainId; // Index in the array of methods of the defining class