Skip to content

Commit 9187e8b

Browse files
committed
Eliminate VM_compiledAsDLTBefore message for JITServer
Recent changes in Inliner have added a check of whether a method has been DLTed before (DLT stands for Dynamic Loop Transfer). As a consequence, the number of `VM_compiledAsDLTBefore` messages sent by the server has increased a lot adding to compilation overhead. This commit eliminates all `VM_compiledAsDLTBefore` messages. The idea is for the server to keep track of all DLT compilations that it performs on behalf of a client. When the client connects for the first time to a new server, it will send the set of DLTed methods to the server, so that the server can initialize its own set. This action takes care of two possible situations: (1) The client connects to a server at a later point in time (because a server was not available from the very begining). (2) The client is connected to a server at the begining of its run, but later on, the connection is broken and the client is forced to connect to a different server. Signed-off-by: Marius Pirvu <[email protected]>
1 parent a6abd7e commit 9187e8b

10 files changed

+88
-21
lines changed

runtime/compiler/control/CompilationRuntime.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "control/rossa.h"
4141
#include "runtime/RelocationRuntime.hpp"
4242
#if defined(J9VM_OPT_JITSERVER)
43+
#include <vector>
4344
#include "control/JITServerHelpers.hpp"
4445
#include "env/PersistentCollections.hpp"
4546
#include "net/ServerStream.hpp"
@@ -788,6 +789,9 @@ class CompilationInfo
788789
void cleanDLTRecordOnUnload();
789790
DLTTracking *getDLT_HT() const { return _dltHT; }
790791
void setDLT_HT(DLTTracking *dltHT) { _dltHT = dltHT; }
792+
#if defined(J9VM_OPT_JITSERVER)
793+
std::vector<J9Method*> collectDLTedMethods();
794+
#endif /* defined(J9VM_OPT_JITSERVER) */
791795
#else
792796
DLTTracking *getDLT_HT() const { return NULL; }
793797
#endif // J9VM_JIT_DYNAMIC_LOOP_TRANSFER
@@ -1229,6 +1233,7 @@ class CompilationInfo
12291233
TR::Monitor *_dltMonitor;
12301234
struct DLT_record *_freeDLTRecord;
12311235
struct DLT_record *_dltHash[DLT_HASHSIZE];
1236+
int32_t _numDLTRecords;
12321237
#endif
12331238
DLTTracking *_dltHT;
12341239

runtime/compiler/control/CompilationThread.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3100,6 +3100,7 @@ TR::CompilationInfo::startCompilationThread(int32_t priority, int32_t threadId,
31003100
}
31013101

31023102
#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)
3103+
31033104
void *TR::CompilationInfo::searchForDLTRecord(J9Method *method, int32_t bcIndex)
31043105
{
31053106
int32_t hashVal = (intptr_t)method * bcIndex % DLT_HASHSIZE;
@@ -3187,6 +3188,7 @@ void TR::CompilationInfo::insertDLTRecord(J9Method *method, int32_t bcIndex, voi
31873188
// Doing this means we don't need locking when reading the _dltHash linked lists
31883189
FLUSH_MEMORY(TR::Compiler->target.isSMP());
31893190
_dltHash[hashVal] = myRecord;
3191+
_numDLTRecords++;
31903192
}
31913193
}
31923194

@@ -3213,14 +3215,37 @@ void TR::CompilationInfo::cleanDLTRecordOnUnload()
32133215
// FIXME: free the codeCache
32143216
curr->_next = _freeDLTRecord;
32153217
_freeDLTRecord = curr;
3218+
_numDLTRecords--;
32163219
}
32173220
else
32183221
prev = curr;
32193222
curr = next;
32203223
}
32213224
}
32223225
}
3223-
#endif
3226+
3227+
#if defined(J9VM_OPT_JITSERVER)
3228+
// Method executed by the client to gather all methods that have been DLTed before.
3229+
// The result is put into a vector of J9Method* which will be sent to the server.
3230+
// This operation is only needed when the client connects to a brand new server.
3231+
std::vector<J9Method*> TR::CompilationInfo::collectDLTedMethods()
3232+
{
3233+
std::vector<J9Method*> dltedMethods;
3234+
dltedMethods.reserve(_numDLTRecords); // overestimate
3235+
OMR::CriticalSection cs(_dltMonitor);
3236+
for (int32_t i = 0; i < DLT_HASHSIZE; i++)
3237+
{
3238+
struct DLT_record *dltPtr = _dltHash[i];
3239+
while (dltPtr)
3240+
{
3241+
dltedMethods.push_back(dltPtr->_method);
3242+
dltPtr = dltPtr->_next;
3243+
}
3244+
}
3245+
return dltedMethods;
3246+
}
3247+
#endif /* defined(J9VM_OPT_JITSERVER) */
3248+
#endif /* defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER) */
32243249

32253250
#ifdef INVOCATION_STATS
32263251
extern "C" J9Method * getNewInstancePrototype(J9VMThread * context);
@@ -10287,6 +10312,11 @@ TR::CompilationInfo::compilationEnd(J9VMThread * vmThread, TR::IlGeneratorMethod
1028710312
if (startPC) // compilation succeeded
1028810313
{
1028910314
outOfProcessCompilationEnd(entry, comp);
10315+
// Update the set of DLT compilations maintained by the server
10316+
ClientSessionData *clientSession = comp->getClientData();
10317+
J9Method *method = details.getMethod();
10318+
OMR::CriticalSection cs(clientSession->getDLTSetMonitor());
10319+
clientSession->getDLTedMethodSet().insert(method);
1029010320
}
1029110321
else if (entry) // failure
1029210322
{

runtime/compiler/control/JITClientCompilationThread.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
263263
compInfo->getclassesCachedAtServer().clear();
264264
}
265265

266+
// Add the list of methods that were DLTed
267+
#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)
268+
std::vector<J9Method*> dltedMethods = compInfo->collectDLTedMethods();
269+
#else
270+
std::vector<J9Method*> dltedMethods; // empty
271+
#endif /* defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER) */
272+
266273
// This is a connection to a new server after a previous disconnection
267274
if (hasEverConnectedToServer && (previousUID != serverUID))
268275
{
@@ -276,7 +283,7 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
276283
compInfo->getPersistentInfo()->setDoNotRequestJITServerAOTCacheStore(false);
277284
}
278285

279-
client->write(response, ranges, unloadedClasses->getMaxRanges(), serializedCHTable);
286+
client->write(response, ranges, unloadedClasses->getMaxRanges(), serializedCHTable, dltedMethods);
280287

281288
if ((previousUID != serverUID) && TR::Options::getVerboseOption(TR_VerboseJITServerConns))
282289
{
@@ -353,12 +360,6 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes
353360
client->write(response, declaringClass1, declaringClass2, f1, f2);
354361
};
355362
break;
356-
case MessageType::VM_compiledAsDLTBefore:
357-
{
358-
auto clazz = std::get<0>(client->getRecvData<TR_ResolvedMethod *>());
359-
client->write(response, fe->compiledAsDLTBefore(clazz));
360-
}
361-
break;
362363
case MessageType::VM_classHasBeenExtended:
363364
{
364365
auto clazz = std::get<0>(client->getRecvData<TR_OpaqueClassBlock *>());

runtime/compiler/control/JITServerCompilationThread.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,13 @@ outOfProcessCompilationEnd(TR_MethodToBeCompiled *entry, TR::Compilation *comp)
265265
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
266266
{
267267
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "compThreadID=%d has successfully compiled %s memoryState=%d",
268-
compInfoPT->getCompThreadId(), compInfoPT->getCompilation()->signature(), memoryState);
268+
compInfoPT->getCompThreadId(), comp->signature(), memoryState);
269269
}
270270
}
271271
compInfoPT->clearPerCompilationCaches();
272272

273273
Trc_JITServerCompileEnd(compInfoPT->getCompilationThread(), compInfoPT->getCompThreadId(),
274-
compInfoPT->getCompilation()->signature(), compInfoPT->getCompilation()->getHotnessName());
274+
comp->signature(), comp->getHotnessName());
275275

276276
// Check whether we need to save a copy of the AOTcache in a file
277277
if (compInfoPT->getCompilationInfo()->getPersistentInfo()->getJITServerUseAOTCachePersistence())
@@ -750,11 +750,12 @@ TR::CompilationInfoPerThreadRemote::processCompilationRequest(CompilationRequest
750750
getCompThreadId(), (unsigned long long)clientId);
751751

752752
stream->write(JITServer::MessageType::getUnloadedClassRangesAndCHTable, compInfo->getPersistentInfo()->getServerUID());
753-
auto response = stream->read<std::vector<TR_AddressRange>, int32_t, std::string>();
753+
auto response = stream->read<std::vector<TR_AddressRange>, int32_t, std::string, std::vector<J9Method*>>();
754754
// TODO: we could send JVM info that is global and does not change together with CHTable
755755
auto &unloadedClassRanges = std::get<0>(response);
756756
auto maxRanges = std::get<1>(response);
757757
std::string &serializedCHTable = std::get<2>(response);
758+
std::vector<J9Method*> &dltedMethods = std::get<3>(response);
758759

759760
clientSession->initializeUnloadedClassAddrRanges(unloadedClassRanges, maxRanges);
760761
if (!unloadedClasses.empty())
@@ -771,6 +772,13 @@ TR::CompilationInfoPerThreadRemote::processCompilationRequest(CompilationRequest
771772
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "compThreadID=%d will initialize CHTable for clientUID %llu size=%zu",
772773
getCompThreadId(), (unsigned long long)clientId, serializedCHTable.size());
773774
chTable->initializeCHTable(_vm, serializedCHTable);
775+
#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)
776+
{
777+
OMR::CriticalSection cs(clientSession->getDLTSetMonitor());
778+
clientSession->getDLTedMethodSet().insert(dltedMethods.begin(), dltedMethods.end());
779+
}
780+
#endif /* defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER) */
781+
774782
clientSession->setCachesAreCleared(false);
775783
initializedCHTable = true;
776784
}

runtime/compiler/env/VMJ9Server.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,11 +663,16 @@ TR_J9ServerVM::isGetImplAndRefersToInliningSupported()
663663
bool
664664
TR_J9ServerVM::compiledAsDLTBefore(TR_ResolvedMethod *method)
665665
{
666+
// The server keeps track of DLT compilations that have been performed,
667+
// so no messages need to be sent to the client
666668
#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)
667-
JITServer::ServerStream *stream = _compInfoPT->getMethodBeingCompiled()->_stream;
668-
auto mirror = static_cast<TR_ResolvedJ9JITServerMethod *>(method)->getRemoteMirror();
669-
stream->write(JITServer::MessageType::VM_compiledAsDLTBefore, static_cast<TR_ResolvedMethod *>(mirror));
670-
return std::get<0>(stream->read<bool>());
669+
TR_ResolvedJ9JITServerMethod *serverMethod = static_cast<TR_ResolvedJ9JITServerMethod*>(method);
670+
J9Method *j9method = serverMethod->ramMethod();
671+
672+
ClientSessionData *clientData = _compInfoPT->getClientData();
673+
auto &dltedMethodSet = clientData->getDLTedMethodSet();
674+
OMR::CriticalSection cs(clientData->getDLTSetMonitor());
675+
return dltedMethodSet.find(j9method) != dltedMethodSet.end();
671676
#else
672677
return 0;
673678
#endif

runtime/compiler/net/CommunicationStream.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class CommunicationStream
129129
// likely to lose an increment when merging/rebasing/etc.
130130
//
131131
static const uint8_t MAJOR_NUMBER = 1;
132-
static const uint16_t MINOR_NUMBER = 83; // ID: yInQ3zszluYaDVc6hSwi
132+
static const uint16_t MINOR_NUMBER = 84; // ID: gIq88QhwCmuOoBAlidaE
133133
static const uint8_t PATCH_NUMBER = 0;
134134
static uint32_t CONFIGURATION_FLAGS;
135135

runtime/compiler/net/MessageTypes.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ const char *messageNames[] =
106106
"VM_getClassFromSignature",
107107
"VM_jitFieldsOrStaticsAreSame",
108108
"VM_classHasBeenExtended",
109-
"VM_compiledAsDLTBefore",
110109
"VM_isThunkArchetype",
111110
"VM_printTruncatedSignature",
112111
"VM_getStaticHookAddress",

runtime/compiler/net/MessageTypes.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ enum MessageType : uint16_t
115115
VM_getClassFromSignature,
116116
VM_jitFieldsOrStaticsAreSame,
117117
VM_classHasBeenExtended,
118-
VM_compiledAsDLTBefore,
119118
VM_isThunkArchetype,
120119
VM_printTruncatedSignature,
121120
VM_getStaticHookAddress,

runtime/compiler/runtime/JITClientSession.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ ClientSessionData::ClientSessionData(uint64_t clientUID, uint32_t seqNo, TR_Pers
4747
_romClassMap(decltype(_romClassMap)::allocator_type(persistentMemory->_persistentAllocator.get())),
4848
_J9MethodMap(decltype(_J9MethodMap)::allocator_type(persistentMemory->_persistentAllocator.get())),
4949
_classBySignatureMap(decltype(_classBySignatureMap)::allocator_type(persistentMemory->_persistentAllocator.get())),
50+
_DLTedMethodSet(decltype(_DLTedMethodSet)::allocator_type(persistentMemory->_persistentAllocator.get())),
5051
_classChainDataMap(decltype(_classChainDataMap)::allocator_type(persistentMemory->_persistentAllocator.get())),
5152
_constantPoolToClassMap(decltype(_constantPoolToClassMap)::allocator_type(persistentMemory->_persistentAllocator.get())),
5253
_unloadedClassAddresses(NULL),
@@ -72,6 +73,7 @@ ClientSessionData::ClientSessionData(uint64_t clientUID, uint32_t seqNo, TR_Pers
7273
_numActiveThreads = 0;
7374
_romMapMonitor = TR::Monitor::create("JIT-JITServerROMMapMonitor");
7475
_classMapMonitor = TR::Monitor::create("JIT-JITServerClassMapMonitor");
76+
_DLTSetMonitor = TR::Monitor::create("JIT-JITServerDLTSetMonitor");
7577
_classChainDataMapMonitor = TR::Monitor::create("JIT-JITServerClassChainDataMapMonitor");
7678
_sequencingMonitor = TR::Monitor::create("JIT-JITServerSequencingMonitor");
7779
_cacheInitMonitor = TR::Monitor::create("JIT-JITServerCacheInitMonitor");
@@ -124,6 +126,7 @@ ClientSessionData::destroyMonitors()
124126
{
125127
TR::Monitor::destroy(_romMapMonitor);
126128
TR::Monitor::destroy(_classMapMonitor);
129+
TR::Monitor::destroy(_DLTSetMonitor);
127130
TR::Monitor::destroy(_classChainDataMapMonitor);
128131
TR::Monitor::destroy(_sequencingMonitor);
129132
TR::Monitor::destroy(_cacheInitMonitor);
@@ -230,7 +233,17 @@ ClientSessionData::processUnloadedClasses(const std::vector<TR_OpaqueClassBlock*
230233
}
231234

232235
J9Method *methods = it->second._methodsOfClass;
233-
// delete all the cached J9Methods belonging to this unloaded class
236+
{
237+
// Delete unloaded j9methods from the set of DLTed methods.
238+
OMR::CriticalSection cs(getDLTSetMonitor());
239+
for (size_t i = 0; i < romClass->romMethodCount; i++)
240+
{
241+
J9Method *j9method = methods + i;
242+
_DLTedMethodSet.erase(j9method);
243+
}
244+
} // end critical section getDLTSetMonitor()
245+
246+
// Delete all the cached J9Methods belonging to this unloaded class.
234247
for (size_t i = 0; i < romClass->romMethodCount; i++)
235248
{
236249
J9Method *j9method = methods + i;
@@ -260,7 +273,7 @@ ClientSessionData::processUnloadedClasses(const std::vector<TR_OpaqueClassBlock*
260273
{
261274
purgeCache(unloadedClasses, _classRecordMap, &ClassUnloadedData::_record);
262275
}
263-
}
276+
} // end critical section getROMMapMonitor()
264277

265278
// remove the class chain data from the cache for the unloaded class.
266279
{
@@ -1429,6 +1442,8 @@ ClientSessionData::clearCaches(bool locked)
14291442

14301443
_romClassMap.clear();
14311444

1445+
_DLTedMethodSet.clear();
1446+
14321447
_classChainDataMap.clear();
14331448
_constantPoolToClassMap.clear();
14341449

runtime/compiler/runtime/JITClientSession.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,13 +404,15 @@ class ClientSessionData
404404
PersistentUnorderedMap<J9Class *, ClassInfo> &getROMClassMap() { return _romClassMap; }
405405
PersistentUnorderedMap<J9Method *, J9MethodInfo> &getJ9MethodMap() { return _J9MethodMap; }
406406
PersistentUnorderedMap<ClassLoaderStringPair, TR_OpaqueClassBlock *> &getClassBySignatureMap() { return _classBySignatureMap; }
407+
PersistentUnorderedSet<J9Method*> &getDLTedMethodSet() { return _DLTedMethodSet; }
407408
PersistentUnorderedMap<J9Class *, ClassChainData> &getClassChainDataMap() { return _classChainDataMap; }
408409
PersistentUnorderedMap<J9ConstantPool *, TR_OpaqueClassBlock *> &getConstantPoolToClassMap() { return _constantPoolToClassMap; }
409410
void initializeUnloadedClassAddrRanges(const std::vector<TR_AddressRange> &unloadedClassRanges, int32_t maxRanges);
410411
void processUnloadedClasses(const std::vector<TR_OpaqueClassBlock*> &classes, bool updateUnloadedClasses);
411412
void processIllegalFinalFieldModificationList(const std::vector<TR_OpaqueClassBlock*> &classes);
412413
TR::Monitor *getROMMapMonitor() { return _romMapMonitor; }
413414
TR::Monitor *getClassMapMonitor() { return _classMapMonitor; }
415+
TR::Monitor *getDLTSetMonitor() { return _DLTSetMonitor; }
414416
TR::Monitor *getClassChainDataMapMonitor() { return _classChainDataMapMonitor; }
415417
TR_IPBytecodeHashTableEntry *getCachedIProfilerInfo(TR_OpaqueMethodBlock *method, uint32_t byteCodeIndex, bool *methodInfoPresent);
416418
bool cacheIProfilerInfo(TR_OpaqueMethodBlock *method, uint32_t byteCodeIndex, TR_IPBytecodeHashTableEntry *entry, bool isCompiled);
@@ -421,7 +423,7 @@ class ClientSessionData
421423
bool loadBytecodeDataFromSharedProfileCache(J9Method *method, bool stable, TR::Compilation *comp, const std::string &ipdata);
422424
bool storeBytecodeProfileInSharedRepository(TR_OpaqueMethodBlock *method, const std::string &ipdata, uint64_t numSamples, bool isStable, TR::Compilation *);
423425
VMInfo *getOrCacheVMInfo(JITServer::ServerStream *stream);
424-
void clearCaches(bool locked=false); // destroys _chTableClassMap, _romClassMap, _J9MethodMap and _unloadedClassAddresses
426+
void clearCaches(bool locked=false); // destroys _chTableClassMap, _romClassMap, _J9MethodMap, _unloadedClassAddresses and _DLTedMethodSet
425427
void clearCachesLocked(TR_J9VMBase *fe);
426428
bool cachesAreCleared() const { return _requestUnloadedClasses; }
427429
void setCachesAreCleared(bool b) { _requestUnloadedClasses = b; }
@@ -580,12 +582,15 @@ class ClientSessionData
580582
// The following hashtable caches <classname> --> <J9Class> mappings
581583
// All classes in here are loaded by the systemClassLoader so we know they cannot be unloaded
582584
PersistentUnorderedMap<ClassLoaderStringPair, TR_OpaqueClassBlock*> _classBySignatureMap;
585+
// The set of j9methods that have been DLTed. This may be queried by the Inliner. Protected by _DLTSetMonitor.
586+
PersistentUnorderedSet<J9Method*> _DLTedMethodSet;
583587

584588
PersistentUnorderedMap<J9Class *, ClassChainData> _classChainDataMap;
585589
//Constant pool to class map
586590
PersistentUnorderedMap<J9ConstantPool *, TR_OpaqueClassBlock *> _constantPoolToClassMap;
587591
TR::Monitor *_romMapMonitor;
588592
TR::Monitor *_classMapMonitor;
593+
TR::Monitor *_DLTSetMonitor; // Protects the set of methods that have been DLTed: _DLTedMethodSet
589594
TR::Monitor *_classChainDataMapMonitor;
590595
// The following monitor is used to protect access to _lastProcessedCriticalSeqNo and
591596
// the list of out-of-sequence compilation requests (_OOSequenceEntryList)

0 commit comments

Comments
 (0)