Skip to content

Commit 4f059f1

Browse files
committed
Client Request Cached Methods List from JIT Server
Added an option that makes the client request a list of cached methods from the server on bootstrap, and set the count for those methods as scount to improve rampup Signed-off-by: Luke Li <[email protected]>
1 parent 445f858 commit 4f059f1

12 files changed

+366
-35
lines changed

runtime/compiler/control/HookedByTheJit.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
2121
*******************************************************************************/
2222

23+
#include <string>
24+
#include <unordered_set>
25+
2326
#include <algorithm>
2427
#include <limits.h>
2528
#ifdef LINUX
@@ -425,6 +428,44 @@ static void jitHookInitializeSendTarget(J9HookInterface * * hook, UDATA eventNum
425428
}
426429
}
427430

431+
#if defined(J9VM_OPT_JITSERVER)
432+
bool methodCachedAtServer = false;
433+
PersistentUnorderedSet<std::string> *serverAOTMethodSet =
434+
(PersistentUnorderedSet<std::string> *) jitConfig->serverAOTMethodSet;
435+
436+
if (serverAOTMethodSet != NULL)
437+
{
438+
// Construct a signature
439+
J9UTF8 *className;
440+
J9UTF8 *name;
441+
J9UTF8 *signature;
442+
getClassNameSignatureFromMethod(method, className, name, signature);
443+
// SigLen calculation as used in TRJ9VMBase::printTruncatedSignature
444+
int32_t sigLen = J9UTF8_LENGTH(className) + J9UTF8_LENGTH(name) +
445+
J9UTF8_LENGTH(signature) + 2;
446+
447+
if (sigLen < 1024)
448+
{
449+
char sigC[1024];
450+
sigLen = sprintf(sigC, "%.*s.%.*s%.*s",
451+
J9UTF8_LENGTH(className), utf8Data(className),
452+
J9UTF8_LENGTH(name), utf8Data(name),
453+
J9UTF8_LENGTH(signature), utf8Data(signature));
454+
455+
// contains
456+
methodCachedAtServer =
457+
(serverAOTMethodSet->find(std::string(sigC)) != serverAOTMethodSet->end());
458+
459+
if (TR::Options::getVerboseOption(TR_VerboseJITServer)
460+
&& TR::Options::getVerboseOption(TR_VerboseCounts))
461+
if (methodCachedAtServer)
462+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
463+
"Method %s was cached at the server",
464+
sigC);
465+
}
466+
}
467+
#endif // J9VM_OPT_JITSERVER
468+
428469
if (TR::Options::getAOTCmdLineOptions()->anOptionSetContainsACountValue())
429470
{
430471
TR::OptionSet * optionSet = findOptionSet(method, true);
@@ -628,6 +669,24 @@ static void jitHookInitializeSendTarget(J9HookInterface * * hook, UDATA eventNum
628669
}
629670
#endif // defined(J9VM_INTERP_AOT_COMPILE_SUPPORT) && defined(J9VM_OPT_SHARED_CLASSES) && (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))
630671
} // if (TR::Options::sharedClassCache())
672+
#if defined(J9VM_OPT_JITSERVER)
673+
else if (methodCachedAtServer) // Not cached in SCC but the server
674+
{
675+
int32_t scount = TR_INITIAL_SCOUNT;
676+
if (optionsAOT)
677+
{
678+
scount = optionsAOT->getInitialSCount();
679+
if ((scount == TR_QUICKSTART_INITIAL_SCOUNT) || (scount == TR_INITIAL_SCOUNT))
680+
{
681+
// If scount is not user specified (coarse way due to info being lost
682+
// from options parsing)
683+
scount= std::min(getCount(romMethod, optionsJIT, optionsAOT),
684+
optionsAOT->getInitialSCount());
685+
}
686+
}
687+
count = scount;
688+
}
689+
#endif // J9VM_OPT_JITSERVER
631690
if (count == -1) // count didn't change yet
632691
{
633692
if (!TR::Options::getCountsAreProvidedByUser() &&
@@ -4181,6 +4240,14 @@ void JitShutdown(J9JITConfig * jitConfig)
41814240

41824241
TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);
41834242

4243+
PersistentUnorderedSet<std::string> *serverAOTMethodSet =
4244+
(PersistentUnorderedSet<std::string> *) jitConfig->serverAOTMethodSet;
4245+
if (serverAOTMethodSet)
4246+
{
4247+
serverAOTMethodSet->~unordered_set();
4248+
TR_Memory::jitPersistentFree((void *)serverAOTMethodSet);
4249+
}
4250+
41844251
#if defined(J9VM_OPT_CRIU_SUPPORT)
41854252
if (jitConfig->javaVM->internalVMFunctions->isCRaCorCRIUSupportEnabled(vmThread))
41864253
{

runtime/compiler/control/JITServerCompilationThread.cpp

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
2121
*******************************************************************************/
2222

23+
#include <string.h>
24+
2325
#include "control/JITServerCompilationThread.hpp"
2426

2527
#include "codegen/CodeGenerator.hpp"
@@ -202,9 +204,14 @@ outOfProcessCompilationEnd(TR_MethodToBeCompiled *entry, TR::Compilation *comp)
202204
CachedAOTMethod *freshMethodRecord = NULL;
203205
if (!methodRecord)
204206
{
205-
freshMethodRecord = CachedAOTMethod::create(compInfoPT->getDefiningClassChainRecord(), compInfoPT->getMethodIndex(),
206-
entry->_optimizationPlan->getOptLevel(), clientData->getAOTHeaderRecord(),
207-
comp->getSerializationRecords(), codeCacheHeader, codeSize, dataCacheHeader, dataSize);
207+
freshMethodRecord = CachedAOTMethod::create(compInfoPT->getDefiningClassChainRecord(),
208+
compInfoPT->getMethodIndex(),
209+
entry->_optimizationPlan->getOptLevel(),
210+
clientData->getAOTHeaderRecord(),
211+
comp->getSerializationRecords(),
212+
codeCacheHeader, codeSize,
213+
dataCacheHeader, dataSize,
214+
comp->signature());
208215
methodRecord = freshMethodRecord;
209216
}
210217

@@ -1101,6 +1108,70 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J
11011108
stream->writeError(compilationLowPhysicalMemory, (uint64_t) computeServerMemoryState(getCompilationInfo()));
11021109
abortCompilation = true;
11031110
}
1111+
catch (const JITServer::StreamAotCacheMapRequest &e)
1112+
{
1113+
const std::string& aotCacheName = e.getCacheName();
1114+
1115+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
1116+
{
1117+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
1118+
"compThreadID=%d handling request for AOT cache %s method list",
1119+
getCompThreadId(), aotCacheName.c_str());
1120+
}
1121+
1122+
auto aotCacheMap = compInfo->getJITServerAOTCacheMap();
1123+
bool pending = false;
1124+
auto aotCache = aotCacheMap->get(aotCacheName, 0, pending);
1125+
1126+
std::vector<std::string> methodSignaturesV;
1127+
if (aotCache)
1128+
{
1129+
auto cachedAOTMethod = aotCache->getCachedMethodHead();
1130+
auto cachedMethodMonitor = aotCache->getCachedMethodMonitor();
1131+
1132+
methodSignaturesV.reserve(aotCache->getCachedMethodMap().size());
1133+
1134+
try
1135+
{
1136+
{
1137+
OMR::CriticalSection cs(cachedMethodMonitor);
1138+
1139+
for (;cachedAOTMethod != NULL;
1140+
cachedAOTMethod = cachedAOTMethod->getNextRecord())
1141+
{
1142+
const SerializedAOTMethod &serializedAOTMethod = cachedAOTMethod->data();
1143+
methodSignaturesV.push_back(std::string(serializedAOTMethod.signature()));
1144+
}
1145+
}
1146+
}
1147+
catch (const std::bad_alloc &e)
1148+
{
1149+
if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer,
1150+
TR_VerboseCompilationDispatch))
1151+
TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,
1152+
"std::bad_alloc: %s",
1153+
e.what());
1154+
}
1155+
1156+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
1157+
{
1158+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
1159+
"Sending the list of AOT methods size %d",
1160+
methodSignaturesV.size());
1161+
}
1162+
}
1163+
else // Failed getting aotCache, treat pending as a failure
1164+
{
1165+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
1166+
{
1167+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Failed getting aotCache");
1168+
}
1169+
}
1170+
stream->write(JITServer::MessageType::AOTCacheMap_reply, methodSignaturesV);
1171+
1172+
abortCompilation = true;
1173+
deleteStream = true;
1174+
}
11041175

11051176
// Acquire VM access
11061177
//

runtime/compiler/control/rossa.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#include <stdlib.h>
2525
#include <string.h>
2626

27+
#include <vector>
28+
#include <string>
29+
2730
#ifdef WINDOWS
2831
// Undefine the winsockapi because winsock2 defines it. Removes warnings.
2932
#if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
@@ -1917,6 +1920,83 @@ onLoadInternal(
19171920
return 0;
19181921
}
19191922

1923+
#if defined(J9VM_OPT_JITSERVER)
1924+
static int32_t J9THREAD_PROC fetchServerCachedAOTMethods(void * entryarg)
1925+
{
1926+
J9JITConfig *jitConfig = (J9JITConfig *) entryarg;
1927+
J9JavaVM *vm = jitConfig->javaVM;
1928+
TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);
1929+
TR::PersistentInfo *persistentInfo = compInfo->getPersistentInfo();
1930+
1931+
j9thread_t osThread = (j9thread_t) jitConfig->serverAOTQueryThread;
1932+
J9VMThread *vmThread = NULL;
1933+
1934+
int rc = vm->internalVMFunctions->internalAttachCurrentThread(vm, &vmThread, NULL,
1935+
J9_PRIVATE_FLAGS_DAEMON_THREAD | J9_PRIVATE_FLAGS_NO_OBJECT |
1936+
J9_PRIVATE_FLAGS_SYSTEM_THREAD | J9_PRIVATE_FLAGS_ATTACHED_THREAD,
1937+
osThread);
1938+
1939+
if (rc != JNI_OK)
1940+
{
1941+
return rc;
1942+
}
1943+
1944+
try
1945+
{
1946+
JITServer::ClientStream *client = new (PERSISTENT_NEW) JITServer::ClientStream(persistentInfo);
1947+
client->write(JITServer::MessageType::AOTCacheMap_request,
1948+
persistentInfo->getJITServerAOTCacheName());
1949+
1950+
client->read();
1951+
auto result = client->getRecvData<std::vector<std::string>>();
1952+
1953+
std::vector<std::string> cachedMethods = std::get<0>(result);
1954+
1955+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
1956+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Received %d methods",
1957+
cachedMethods.size());
1958+
1959+
PersistentUnorderedSet<std::string> *serverAOTMethodSet =
1960+
new (PERSISTENT_NEW) PersistentUnorderedSet<std::string>(
1961+
PersistentUnorderedSet<std::string>::allocator_type
1962+
(TR::Compiler->persistentAllocator()));
1963+
1964+
for (const auto &methodSig : cachedMethods)
1965+
{
1966+
serverAOTMethodSet->insert(methodSig);
1967+
}
1968+
1969+
client->~ClientStream();
1970+
TR_Memory::jitPersistentFree(client);
1971+
1972+
FLUSH_MEMORY(TR::Compiler->target.isSMP());
1973+
jitConfig->serverAOTMethodSet = (void *) serverAOTMethodSet;
1974+
}
1975+
catch (const JITServer::StreamFailure &e)
1976+
{
1977+
if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))
1978+
TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,
1979+
"JITServer::StreamFailure: %s",
1980+
e.what());
1981+
1982+
JITServerHelpers::postStreamFailure(
1983+
OMRPORT_FROM_J9PORT(vm->portLibrary),
1984+
compInfo, e.retryConnectionImmediately(), true);
1985+
}
1986+
catch (const std::bad_alloc &e)
1987+
{
1988+
if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer, TR_VerboseCompilationDispatch))
1989+
TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,
1990+
"std::bad_alloc: %s",
1991+
e.what());
1992+
}
1993+
1994+
vm->internalVMFunctions->DetachCurrentThread((JavaVM *) vm);
1995+
j9thread_exit(NULL);
1996+
1997+
return 0;
1998+
}
1999+
#endif // J9VM_OPT_JITSERVER
19202000

19212001
extern "C" int32_t
19222002
aboutToBootstrap(J9JavaVM * javaVM, J9JITConfig * jitConfig)
@@ -2184,6 +2264,43 @@ aboutToBootstrap(J9JavaVM * javaVM, J9JITConfig * jitConfig)
21842264
UT_MODULE_LOADED(J9_UTINTERFACE_FROM_VM(javaVM));
21852265
Trc_JIT_VMInitStages_Event1(curThread);
21862266
Trc_JIT_portableSharedCache_enabled_or_disabled(curThread, J9_ARE_ANY_BITS_SET(javaVM->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_ENABLE_PORTABLE_SHARED_CACHE) ? 1 : 0);
2267+
2268+
#if defined(J9VM_OPT_JITSERVER)
2269+
jitConfig->serverAOTMethodSet = NULL;
2270+
if (TR::Options::getCmdLineOptions()->getOption(TR_RequestJITServerCachedMethods))
2271+
{
2272+
// Ask the server for its cached methods
2273+
if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::CLIENT)
2274+
{
2275+
if (JITServerHelpers::isServerAvailable())
2276+
{
2277+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
2278+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
2279+
"Creating a thread to ask the server for its cached methods");
2280+
2281+
IDATA result = javaVM->internalVMFunctions->createThreadWithCategory(
2282+
(omrthread_t *) &(jitConfig->serverAOTQueryThread),
2283+
javaVM->defaultOSStackSize,
2284+
J9THREAD_PRIORITY_NORMAL,
2285+
0,
2286+
&fetchServerCachedAOTMethods,
2287+
(void *) jitConfig,
2288+
J9THREAD_CATEGORY_SYSTEM_JIT_THREAD
2289+
);
2290+
2291+
if (result != J9THREAD_SUCCESS)
2292+
{
2293+
jitConfig->serverAOTMethodSet = NULL;
2294+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
2295+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
2296+
"Query thread not created");
2297+
}
2298+
}
2299+
}
2300+
}
2301+
#endif // J9VM_OPT_JITSERVER
2302+
2303+
21872304
return 0;
21882305
}
21892306

runtime/compiler/net/CommunicationStream.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class CommunicationStream
128128
// likely to lose an increment when merging/rebasing/etc.
129129
//
130130
static const uint8_t MAJOR_NUMBER = 1;
131-
static const uint16_t MINOR_NUMBER = 65; // ID: YxVkiLqD7B1LhYMv58y8
131+
static const uint16_t MINOR_NUMBER = 66; // ID: KM2yGpoPgxfVKNeftLTB
132132
static const uint8_t PATCH_NUMBER = 0;
133133
static uint32_t CONFIGURATION_FLAGS;
134134

runtime/compiler/net/MessageTypes.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ const char *messageNames[] =
257257
"KnownObjectTable_getReferenceField",
258258
"KnownObjectTable_getKnownObjectTableDumpInfo",
259259
"AOTCache_getROMClassBatch",
260+
"AOTCacheMap_request",
261+
"AOTCacheMap_reply"
260262
};
261263

262264
static_assert(sizeof(messageNames) / sizeof(messageNames[0]) == MessageType_MAXTYPE,

runtime/compiler/net/MessageTypes.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ enum MessageType : uint16_t
284284

285285
AOTCache_getROMClassBatch,
286286

287+
AOTCacheMap_request,
288+
AOTCacheMap_reply,
289+
287290
MessageType_MAXTYPE
288291
};
289292
extern const char *messageNames[];

runtime/compiler/net/ServerStream.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ class ServerStream : public CommunicationStream
179179
{
180180
return getArgsRaw<T...>(_cMsg);
181181
}
182+
case MessageType::AOTCacheMap_request:
183+
{
184+
std::string cacheName = std::get<0>(getArgsRaw<std::string>(_cMsg));
185+
throw StreamAotCacheMapRequest(cacheName);
186+
}
182187
default:
183188
{
184189
throw StreamMessageTypeMismatch(MessageType::compilationRequest, _cMsg.type());

runtime/compiler/net/StreamExceptions.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,25 @@ class StreamClientSessionTerminate: public virtual std::exception
8181
uint64_t _clientId;
8282
};
8383

84+
85+
class StreamAotCacheMapRequest: public virtual std::exception
86+
{
87+
public:
88+
StreamAotCacheMapRequest(std::string cacheName) : _cacheName(cacheName)
89+
{
90+
}
91+
virtual const char* what() const throw()
92+
{
93+
return "Requesting AOT cache content";
94+
}
95+
const std::string& getCacheName() const
96+
{
97+
return _cacheName;
98+
}
99+
private:
100+
const std::string _cacheName;
101+
};
102+
84103
class StreamOOO : public virtual std::exception
85104
{
86105
public:

0 commit comments

Comments
 (0)