Skip to content

Commit

Permalink
Unify JITServer AOT cache read functions
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Despres <despresc@ibm.com>
  • Loading branch information
cjjdespres committed Nov 1, 2022
1 parent 6844bea commit b55a0cb
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 182 deletions.
235 changes: 85 additions & 150 deletions runtime/compiler/runtime/JITServerAOTCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,39 @@ AOTCacheRecord::free(void *ptr)
TR::Compiler->persistentGlobalMemory()->freePersistentMemory(ptr);
}

// Read a single AOT cache record R from a cache file
template<class R> R *
AOTCacheRecord::readRecord(JITServerAOTCacheReadContext &context)
{
typename R::SerializationRecord header;
if (1 != fread(&header, sizeof(header), 1, context._f))
return NULL;

if (!header.isValid(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, context._f))
{
AOTCacheRecord::free(record);
return NULL;
}
}

if (!record->setSubrecordPointers(context))
{
AOTCacheRecord::free(record);
return NULL;
}

return record;
}

bool
AOTSerializationRecord::isValid(AOTSerializationRecordType type) const
{
Expand Down Expand Up @@ -79,27 +112,6 @@ AOTCacheClassLoaderRecord::create(uintptr_t id, const uint8_t *name, size_t name
return new (ptr) AOTCacheClassLoaderRecord(id, name, nameLength);
}

AOTCacheClassLoaderRecord *
AOTCacheClassLoaderRecord::read(JITServerAOTCacheReadContext &context)
{
ClassLoaderSerializationRecord header;
if (1 != fread(&header, sizeof(header), 1, context._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, context._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),
Expand All @@ -115,15 +127,23 @@ ClassSerializationRecord::ClassSerializationRecord() :
{
}

bool
ClassSerializationRecord::isValid(const JITServerAOTCacheReadContext &context) const
{
return AOTSerializationRecord::isValid(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),
_data(id, classLoaderRecord->data().id(), hash, romClass)
{
}

AOTCacheClassRecord::AOTCacheClassRecord(const AOTCacheClassLoaderRecord *classLoaderRecord) :
_classLoaderRecord(classLoaderRecord)
AOTCacheClassRecord::AOTCacheClassRecord(const JITServerAOTCacheReadContext &context, const ClassSerializationRecord &header) :
_classLoaderRecord(context._classLoaderRecords[header.classLoaderId()])
{
}

Expand All @@ -141,29 +161,6 @@ AOTCacheClassRecord::subRecordsDo(const std::function<void(const AOTCacheRecord
f(_classLoaderRecord);
}

AOTCacheClassRecord *
AOTCacheClassRecord::read(JITServerAOTCacheReadContext &context)
{
ClassSerializationRecord header;
if (1 != fread(&header, sizeof(header), 1, context._f))
return NULL;

if (!header.isValid() ||
(header.classLoaderId() >= 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, context._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)
Expand All @@ -176,15 +173,23 @@ MethodSerializationRecord::MethodSerializationRecord() :
{
}

bool
MethodSerializationRecord::isValid(const JITServerAOTCacheReadContext &context) const
{
return AOTSerializationRecord::isValid(AOTSerializationRecordType::Method) &&
(definingClassId() < context._classRecords.size()) &&
context._classRecords[definingClassId()];
}

AOTCacheMethodRecord::AOTCacheMethodRecord(uintptr_t id, const AOTCacheClassRecord *definingClassRecord,
uint32_t index) :
_definingClassRecord(definingClassRecord),
_data(id, definingClassRecord->data().id(), index)
{
}

AOTCacheMethodRecord::AOTCacheMethodRecord(const AOTCacheClassRecord *definingClassRecord) :
_definingClassRecord(definingClassRecord)
AOTCacheMethodRecord::AOTCacheMethodRecord(const JITServerAOTCacheReadContext &context, const MethodSerializationRecord &header) :
_definingClassRecord(context._classRecords[header.definingClassId()])
{
}

Expand All @@ -201,24 +206,6 @@ AOTCacheMethodRecord::subRecordsDo(const std::function<void(const AOTCacheRecord
f(_definingClassRecord);
}

AOTCacheMethodRecord *
AOTCacheMethodRecord::read(JITServerAOTCacheReadContext &context)
{
MethodSerializationRecord header;
if (1 != fread(&header, sizeof(header), 1, context._f))
return NULL;

if (!header.isValid() ||
(header.definingClassId() >= 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<class D, class R, typename... Args>
AOTCacheListRecord<D, R, Args...>::AOTCacheListRecord(uintptr_t id, const R *const *records,
size_t length, Args... args) :
Expand All @@ -236,37 +223,19 @@ AOTCacheListRecord<D, R, Args...>::subRecordsDo(const std::function<void(const A
f(records()[i]);
}

template<class D, class R, typename... Args> AOTCacheListRecord<D, R, Args...>*
AOTCacheListRecord<D, R, Args...>::read(FILE *f, const Vector<R *> &cacheRecords)
template<class D, class R, typename... Args> bool
AOTCacheListRecord<D, R, Args...>::setSubrecordPointers(const Vector<R *> &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))
for (size_t i = 0; i < data().list().length(); ++i)
{
AOTCacheRecord::free(record);
return NULL;
}

for (size_t i = 0; i < header.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) :
Expand Down Expand Up @@ -335,22 +304,6 @@ AOTCacheAOTHeaderRecord::create(uintptr_t id, const TR_AOTHeader *header)
return new (ptr) AOTCacheAOTHeaderRecord(id, header);
}

AOTCacheAOTHeaderRecord *
AOTCacheAOTHeaderRecord::read(JITServerAOTCacheReadContext &context)
{
AOTHeaderSerializationRecord header;
if (1 != fread(&header, sizeof(header), 1, context._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) :
Expand All @@ -372,9 +325,12 @@ SerializedAOTMethod::SerializedAOTMethod() :
}

bool
SerializedAOTMethod::isValid() const
SerializedAOTMethod::isValid(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()];
}

CachedAOTMethod::CachedAOTMethod(const AOTCacheClassChainRecord *definingClassChainRecord, uint32_t index,
Expand All @@ -394,9 +350,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()])
{
}

Expand All @@ -411,68 +367,47 @@ CachedAOTMethod::create(const AOTCacheClassChainRecord *definingClassChainRecord
records, code, codeSize, data, dataSize);
}

CachedAOTMethod *
CachedAOTMethod::read(JITServerAOTCacheReadContext &context)
bool
CachedAOTMethod::setSubrecordPointers(JITServerAOTCacheReadContext &context)
{
SerializedAOTMethod header;
if (1 != fread(&header, sizeof(header), 1, context._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, context._f))
goto error;

for (size_t i = 0; i < header.numRecords(); ++i)
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
Expand Down Expand Up @@ -1257,7 +1192,7 @@ JITServerAOTCache::readRecords(JITServerAOTCacheReadContext &context,
if (!JITServerAOTCacheMap::cacheHasSpace())
return false;

V *record = V::read(context);
V *record = AOTCacheRecord::readRecord<V>(context);
if (!record)
return false;

Expand Down Expand Up @@ -1323,7 +1258,7 @@ JITServerAOTCache::readCache(FILE *f, const JITServerAOTCacheHeader &header, TR_
if (!JITServerAOTCacheMap::cacheHasSpace())
return false;

auto record = CachedAOTMethod::read(context);
auto record = AOTCacheRecord::readRecord<CachedAOTMethod>(context);

if (!record || !aotHeaderRecords[record->data().aotHeaderId()])
return false;
Expand Down
Loading

0 comments on commit b55a0cb

Please sign in to comment.