Skip to content

Commit 4e352c0

Browse files
authored
Merge pull request #22755 from jdmpapin/jitserver-permanent-loaders-consistency
Make client and server agree on exact permanent loaders
2 parents 4d0c65c + 03efb95 commit 4e352c0

19 files changed

+179
-207
lines changed

runtime/compiler/compile/Compilation.hpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ class OMR_EXTENSIBLE Compilation : public J9::CompilationConnector
5050
TR_Memory *memory,
5151
TR_OptimizationPlan *optimizationPlan,
5252
TR_RelocationRuntime *reloRuntime,
53-
TR::Environment *target = NULL) :
53+
TR::Environment *target
54+
#if defined(J9VM_OPT_JITSERVER)
55+
, size_t numPermanentLoaders
56+
#endif
57+
) :
5458
J9::CompilationConnector(
5559
compThreadId,
5660
j9vmThread,
@@ -62,7 +66,11 @@ class OMR_EXTENSIBLE Compilation : public J9::CompilationConnector
6266
memory,
6367
optimizationPlan,
6468
reloRuntime,
65-
target)
69+
target
70+
#if defined(J9VM_OPT_JITSERVER)
71+
, numPermanentLoaders
72+
#endif
73+
)
6674
{}
6775

6876
~Compilation() {}

runtime/compiler/compile/J9Compilation.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,11 @@ J9::Compilation::Compilation(int32_t id,
150150
TR_Memory *m,
151151
TR_OptimizationPlan *optimizationPlan,
152152
TR_RelocationRuntime *reloRuntime,
153-
TR::Environment *target)
153+
TR::Environment *target
154+
#if defined(J9VM_OPT_JITSERVER)
155+
, size_t numPermanentLoaders
156+
#endif
157+
)
154158
: OMR::CompilationConnector(
155159
id,
156160
j9vmThread->omrVMThread,
@@ -208,6 +212,7 @@ J9::Compilation::Compilation(int32_t id,
208212
_ignoringLocalSCC(false),
209213
_serializationRecords(decltype(_serializationRecords)::allocator_type(heapMemoryRegion)),
210214
_thunkRecords(decltype(_thunkRecords)::allocator_type(heapMemoryRegion)),
215+
_numPermanentLoaders(numPermanentLoaders),
211216
#endif /* defined(J9VM_OPT_JITSERVER) */
212217
#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED)
213218
_aotMethodDependencies(decltype(_aotMethodDependencies)::allocator_type(heapMemoryRegion)),
@@ -1612,8 +1617,12 @@ J9::Compilation::permanentLoaders()
16121617
#if defined(J9VM_OPT_JITSERVER)
16131618
if (self()->isOutOfProcessCompilation())
16141619
{
1620+
TR_ASSERT_FATAL(
1621+
_numPermanentLoaders != SIZE_MAX, "missing _numPermanentLoaders");
1622+
16151623
ClientSessionData *clientData = self()->getClientData();
1616-
clientData->getPermanentLoaders(_permanentLoaders);
1624+
clientData->getPermanentLoaders(
1625+
_permanentLoaders, _numPermanentLoaders, getStream());
16171626
}
16181627
else
16191628
#endif

runtime/compiler/compile/J9Compilation.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector
101101
TR_Memory *,
102102
TR_OptimizationPlan *optimizationPlan,
103103
TR_RelocationRuntime *reloRuntime,
104-
TR::Environment *target = NULL);
104+
TR::Environment *target
105+
#if defined(J9VM_OPT_JITSERVER)
106+
, size_t numPermanentLoaders
107+
#endif
108+
);
105109

106110
~Compilation();
107111

@@ -629,6 +633,9 @@ class OMR_EXTENSIBLE Compilation : public OMR::CompilationConnector
629633
Vector<std::pair<const AOTCacheRecord *, uintptr_t>> _serializationRecords;
630634
// Set of AOT cache thunk records that this compilation depends on; always empty at the client
631635
UnorderedSet<const AOTCacheThunkRecord *> _thunkRecords;
636+
// For the server, the number of permanent loaders the client has specified
637+
// we must use for this compilation.
638+
size_t _numPermanentLoaders;
632639
#endif /* defined(J9VM_OPT_JITSERVER) */
633640

634641
#if !defined(PERSISTENT_COLLECTIONS_UNSUPPORTED)

runtime/compiler/control/CompilationThread.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8399,6 +8399,9 @@ TR::CompilationInfoPerThreadBase::compile(J9VMThread * vmThread,
83998399
trMemory,
84008400
TR::CompileIlGenRequest(entry->getMethodDetails()),
84018401
entry->_checkpointInProgress
8402+
#if defined(J9VM_OPT_JITSERVER)
8403+
, entry->_numPermanentLoaders
8404+
#endif
84028405
);
84038406
if (TR::Options::getVerboseOption(TR_VerboseCompilationDispatch))
84048407
TR_VerboseLog::writeLineLocked(TR_Vlog_DISPATCH,
@@ -9278,7 +9281,11 @@ TR::CompilationInfoPerThreadBase::wrappedCompile(J9PortLibrary *portLib, void *
92789281
p->trMemory(),
92799282
p->_optimizationPlan,
92809283
reloRuntime,
9281-
&target);
9284+
&target
9285+
#if defined(J9VM_OPT_JITSERVER)
9286+
, p->_numPermanentLoaders
9287+
#endif
9288+
);
92829289

92839290
#if defined(J9VM_OPT_JITSERVER)
92849291
if (that->_methodBeingCompiled->isOutOfProcessCompReq())

runtime/compiler/control/CompilationThread.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ struct CompileParameters
103103
TR_Memory &trMemory,
104104
const TR::CompileIlGenRequest &ilGenRequest,
105105
bool checkpointInProgress
106+
#if defined(J9VM_OPT_JITSERVER)
107+
, size_t numPermanentLoaders
108+
#endif
106109
) :
107110
_compilationInfo(compilationInfo),
108111
_vm(vm),
@@ -114,6 +117,9 @@ struct CompileParameters
114117
_trMemory(trMemory),
115118
_ilGenRequest(ilGenRequest),
116119
_checkpointInProgress(checkpointInProgress)
120+
#if defined(J9VM_OPT_JITSERVER)
121+
, _numPermanentLoaders(numPermanentLoaders)
122+
#endif
117123
{}
118124

119125
TR_Memory *trMemory() { return &_trMemory; }
@@ -128,6 +134,10 @@ struct CompileParameters
128134
TR_Memory &_trMemory;
129135
TR::CompileIlGenRequest _ilGenRequest;
130136
bool _checkpointInProgress;
137+
138+
#if defined(J9VM_OPT_JITSERVER)
139+
size_t _numPermanentLoaders;
140+
#endif
131141
};
132142

133143
#if defined(TR_HOST_S390)

runtime/compiler/control/JITClientCompilationThread.cpp

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,6 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
282282
// Do not forbid AOT cache stores or loads (this server might be able to fulfill them)
283283
compInfo->getPersistentInfo()->setDoNotRequestJITServerAOTCacheLoad(false);
284284
compInfo->getPersistentInfo()->setDoNotRequestJITServerAOTCacheStore(false);
285-
286-
auto loaderTable = compInfo->getPersistentInfo()->getPersistentClassLoaderTable();
287-
OMR::CriticalSection lock(compInfo->getSequencingMonitor());
288-
loaderTable->resetPermanentLoadersSentToServer(compInfo);
289285
}
290286

291287
client->write(response, ranges, unloadedClasses->getMaxRanges(), serializedCHTable, dltedMethods);
@@ -298,6 +294,21 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
298294
}
299295
}
300296
break;
297+
case MessageType::ClientSessionData_getPermanentLoaders:
298+
{
299+
auto recv = client->getRecvData<size_t>();
300+
size_t serverCount = std::get<0>(recv);
301+
auto permanentLoaders = comp->permanentLoaders();
302+
std::vector<J9ClassLoader*> newPermanentLoaders;
303+
newPermanentLoaders.reserve(permanentLoaders.size() - serverCount);
304+
newPermanentLoaders.insert(
305+
newPermanentLoaders.end(),
306+
permanentLoaders.begin() + serverCount,
307+
permanentLoaders.end());
308+
309+
client->write(response, newPermanentLoaders);
310+
}
311+
break;
301312
case MessageType::VM_isClassLibraryMethod:
302313
{
303314
auto tup = client->getRecvData<TR_OpaqueMethodBlock*, bool>();
@@ -3454,11 +3465,9 @@ remoteCompile(J9VMThread *vmThread, TR::Compilation *compiler, TR_ResolvedMethod
34543465
std::vector<uintptr_t> newKnownIds = deserializer ? deserializer->getNewKnownIds(context) : std::vector<uintptr_t>();
34553466

34563467
auto chTable = (JITClientPersistentCHTable *)persistentInfo->getPersistentCHTable();
3457-
auto permanentLoaders = compiler->permanentLoaders();
34583468
std::vector<TR_OpaqueClassBlock *> unloadedClasses;
34593469
std::vector<TR_OpaqueClassBlock *> illegalModificationList;
34603470
std::pair<std::string, std::string> chtableUpdates("", "");
3461-
std::vector<J9ClassLoader *> newPermanentLoaders; // doesn't affect critical seq. no.
34623471
uint32_t seqNo = 0;
34633472
uint32_t lastCriticalSeqNo = 0;
34643473

@@ -3495,29 +3504,30 @@ remoteCompile(J9VMThread *vmThread, TR::Compilation *compiler, TR_ResolvedMethod
34953504
{
34963505
compInfo->setLastCriticalSeqNo(seqNo);
34973506
}
3498-
3499-
// Determine which permanent loaders (if any) to send to the server.
3500-
auto loaderTable = persistentInfo->getPersistentClassLoaderTable();
3501-
size_t numPermanentLoadersSent =
3502-
loaderTable->numPermanentLoadersSentToServer(compInfo);
3503-
3504-
// It's possible to have numPermanentLoadersSent > permanentLoaders.size()
3505-
// in some interleavings. Only send loaders if our permanentLoaders contains
3506-
// entries that haven't been sent yet. This also prevents the subtraction
3507-
// from overflowing.
3508-
if (numPermanentLoadersSent < permanentLoaders.size())
3509-
{
3510-
size_t n = permanentLoaders.size() - numPermanentLoadersSent;
3511-
newPermanentLoaders.reserve(n);
3512-
newPermanentLoaders.insert(
3513-
newPermanentLoaders.end(),
3514-
permanentLoaders.begin() + numPermanentLoadersSent,
3515-
permanentLoaders.end());
3516-
3517-
loaderTable->addPermanentLoadersSentToServer(n, compInfo);
3518-
}
35193507
}
35203508

3509+
// Determine the loaders to consider permanent for this compilation. From
3510+
// this point on, they are fixed.
3511+
//
3512+
// There will be at least two data structures that are sensitive to the
3513+
// set of permanent loaders. These could potentially allow the precise set
3514+
// of permanent loaders to vary between the client and server, but the
3515+
// reasoning needed to determine whether certain kinds of variation are
3516+
// allowed gets hairy very quickly. It's much simpler if there is only one
3517+
// set of permanent loaders that will be used for all purposes on both the
3518+
// client and the server.
3519+
//
3520+
// To ensure that for this compilation the server will use exactly the
3521+
// permanent loaders determined here, it suffices to tell the server how
3522+
// many there are, let's call it n. The server will know that this
3523+
// compilation is using the first n permanent loaders for this client. If it
3524+
// doesn't yet have all of the first n, then it will send a message to
3525+
// request the ones it's missing, and the response will preserve the
3526+
// ordering so that the first n on the server are the same as the first n on
3527+
// the client.
3528+
//
3529+
size_t numPermanentLoaders = compiler->permanentLoaders().size();
3530+
35213531
uint32_t statusCode = compilationFailure;
35223532
std::string codeCacheStr;
35233533
std::string dataCacheStr;
@@ -3549,7 +3559,7 @@ remoteCompile(J9VMThread *vmThread, TR::Compilation *compiler, TR_ResolvedMethod
35493559
detailsStr, details.getType(), unloadedClasses, illegalModificationList, classInfoTuple, optionsStr,
35503560
recompMethodInfoStr, chtableUpdates.first, chtableUpdates.second, useAotCompilation,
35513561
TR::Compiler->vm.isVMInStartupPhase(compInfoPT->getJitConfig()), aotCacheStore, aotCacheLoad, methodIndex,
3552-
classChainOffset, ramClassChain, uncachedRAMClasses, uncachedClassInfos, newKnownIds, newPermanentLoaders
3562+
classChainOffset, ramClassChain, uncachedRAMClasses, uncachedClassInfos, newKnownIds, numPermanentLoaders
35533563
);
35543564

35553565
JITServer::MessageType response;

runtime/compiler/control/JITServerCompilationThread.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,7 @@ TR::CompilationInfoPerThreadRemote::processCompilationRequest(CompilationRequest
591591
auto &uncachedRAMClasses = std::get<22>(req);
592592
auto &uncachedClassInfos = std::get<23>(req);
593593
auto &newKnownIds = std::get<24>(req);
594-
auto &newPermanentLoaders = std::get<25>(req);
594+
size_t numPermanentLoaders = std::get<25>(req);
595595

596596
TR_ASSERT_FATAL(TR::Compiler->persistentMemory() == compInfo->persistentMemory(),
597597
"per-client persistent memory must not be set at this point");
@@ -669,8 +669,6 @@ TR::CompilationInfoPerThreadRemote::processCompilationRequest(CompilationRequest
669669
clientSession->getAOTCacheKnownIds().insert(newKnownIds.begin(), newKnownIds.end());
670670
}
671671

672-
clientSession->addPermanentLoaders(newPermanentLoaders);
673-
674672
// We must process unloaded classes lists in the same order they were generated at the client
675673
// Use a sequencing scheme to re-order compilation requests
676674
//
@@ -909,6 +907,7 @@ TR::CompilationInfoPerThreadRemote::processCompilationRequest(CompilationRequest
909907
// If we want something then we need to increaseQueueWeightBy(weight) while holding compilation monitor
910908
entry._weight = 0;
911909
entry._jitStateWhenQueued = compInfo->getPersistentInfo()->getJitState();
910+
entry._numPermanentLoaders = numPermanentLoaders;
912911
entry._stream = stream; // Add the stream to the entry
913912

914913
auto aotCache = clientSession->getOrCreateAOTCache(stream);

runtime/compiler/control/JITServerCompilationThread.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ using CompilationRequest = std::tuple<
4141
J9::IlGeneratorMethodDetailsType, std::vector<TR_OpaqueClassBlock *>, std::vector<TR_OpaqueClassBlock *>,
4242
JITServerHelpers::ClassInfoTuple, std::string, std::string, std::string, std::string,
4343
bool, bool, bool, bool, uint32_t, uintptr_t, std::vector<J9Class *>, std::vector<J9Class *>,
44-
std::vector<JITServerHelpers::ClassInfoTuple>, std::vector<uintptr_t>, std::vector<J9ClassLoader *>
44+
std::vector<JITServerHelpers::ClassInfoTuple>, std::vector<uintptr_t>, size_t
4545
>;
4646

4747
void outOfProcessCompilationEnd(TR_MethodToBeCompiled *entry, TR::Compilation *comp);

runtime/compiler/control/MethodToBeCompiled.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ void TR_MethodToBeCompiled::initialize(TR::IlGeneratorMethodDetails &details, vo
9797
_doNotLoadFromJITServerAOTCache = false;
9898
_useAOTCacheCompilation = false;
9999
_origOptLevel = unknownHotness;
100+
_numPermanentLoaders = SIZE_MAX;
100101
_stream = NULL;
101102
#endif /* defined(J9VM_OPT_JITSERVER) */
102103

runtime/compiler/control/MethodToBeCompiled.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ struct TR_MethodToBeCompiled
171171
bool _useAOTCacheCompilation;
172172
// Cache original optLevel when transforming a remote sync compilation to a local cheap one
173173
TR_Hotness _origOptLevel;
174+
// On the server, the number of permanent loaders specified by the client for this compilation.
175+
size_t _numPermanentLoaders;
174176
// A non-NULL field denotes an out-of-process compilation request
175177
JITServer::ServerStream *_stream;
176178
#endif /* defined(J9VM_OPT_JITSERVER) */

0 commit comments

Comments
 (0)