Skip to content

Commit 96b4e54

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 d51176e commit 96b4e54

12 files changed

+392
-35
lines changed

runtime/compiler/control/HookedByTheJit.cpp

Lines changed: 87 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
@@ -385,6 +388,27 @@ static uint32_t initializeSendTargetHelperFuncHashValueForSpreading(J9Method* me
385388

386389
static bool highCodeCacheOccupancyThresholdReached = false;
387390

391+
#if defined(J9VM_OPT_JITSERVER)
392+
static int32_t calculateCountForMethodCachedAtServer(J9ROMMethod * romMethod,
393+
TR::Options * optionsJIT,
394+
TR::Options * optionsAOT)
395+
{
396+
int32_t scount = TR_INITIAL_SCOUNT;
397+
if (optionsAOT)
398+
{
399+
scount = optionsAOT->getInitialSCount();
400+
if ((scount == TR_QUICKSTART_INITIAL_SCOUNT) || (scount == TR_INITIAL_SCOUNT))
401+
{
402+
// If scount is not user specified (coarse way due to info being lost
403+
// from options parsing)
404+
scount= std::min(getCount(romMethod, optionsJIT, optionsAOT),
405+
optionsAOT->getInitialSCount());
406+
}
407+
}
408+
return scount;
409+
}
410+
#endif // J9VM_OPT_JITSERVER
411+
388412
static void jitHookInitializeSendTarget(J9HookInterface * * hook, UDATA eventNum, void * eventData, void * userData)
389413
{
390414
J9VMInitializeSendTargetEvent * event = (J9VMInitializeSendTargetEvent *)eventData;
@@ -425,6 +449,44 @@ static void jitHookInitializeSendTarget(J9HookInterface * * hook, UDATA eventNum
425449
}
426450
}
427451

452+
#if defined(J9VM_OPT_JITSERVER)
453+
bool methodCachedAtServer = false;
454+
PersistentUnorderedSet<std::string> *serverAOTMethodSet =
455+
(PersistentUnorderedSet<std::string> *) jitConfig->serverAOTMethodSet;
456+
457+
if (serverAOTMethodSet != NULL)
458+
{
459+
// Construct a signature
460+
J9UTF8 *className;
461+
J9UTF8 *name;
462+
J9UTF8 *signature;
463+
getClassNameSignatureFromMethod(method, className, name, signature);
464+
// SigLen calculation as used in TRJ9VMBase::printTruncatedSignature
465+
int32_t sigLen = J9UTF8_LENGTH(className) + J9UTF8_LENGTH(name) +
466+
J9UTF8_LENGTH(signature) + 2;
467+
468+
if (sigLen < 1024)
469+
{
470+
char sigC[1024];
471+
sigLen = sprintf(sigC, "%.*s.%.*s%.*s",
472+
J9UTF8_LENGTH(className), utf8Data(className),
473+
J9UTF8_LENGTH(name), utf8Data(name),
474+
J9UTF8_LENGTH(signature), utf8Data(signature));
475+
476+
// contains
477+
methodCachedAtServer =
478+
(serverAOTMethodSet->find(std::string(sigC)) != serverAOTMethodSet->end());
479+
480+
if (TR::Options::getVerboseOption(TR_VerboseJITServer)
481+
&& TR::Options::getVerboseOption(TR_VerboseCounts))
482+
if (methodCachedAtServer)
483+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
484+
"Method %s was cached at the server",
485+
sigC);
486+
}
487+
}
488+
#endif // J9VM_OPT_JITSERVER
489+
428490
if (TR::Options::getAOTCmdLineOptions()->anOptionSetContainsACountValue())
429491
{
430492
TR::OptionSet * optionSet = findOptionSet(method, true);
@@ -628,6 +690,21 @@ static void jitHookInitializeSendTarget(J9HookInterface * * hook, UDATA eventNum
628690
}
629691
#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))
630692
} // if (TR::Options::sharedClassCache())
693+
694+
#if defined(J9VM_OPT_JITSERVER)
695+
// If the method is cached at the server side, set the count to the lower number
696+
// regardless of whether the count has been set before
697+
if (methodCachedAtServer)
698+
{
699+
int32_t serverCount =
700+
calculateCountForMethodCachedAtServer(romMethod, optionsJIT, optionsAOT);
701+
if (count == -1)
702+
count = serverCount;
703+
else
704+
count = std::min(count, serverCount);
705+
}
706+
#endif // J9VM_OPT_JITSERVER
707+
631708
if (count == -1) // count didn't change yet
632709
{
633710
if (!TR::Options::getCountsAreProvidedByUser() &&
@@ -4181,6 +4258,16 @@ void JitShutdown(J9JITConfig * jitConfig)
41814258

41824259
TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);
41834260

4261+
#if defined(J9VM_OPT_JITSERVER)
4262+
PersistentUnorderedSet<std::string> *serverAOTMethodSet =
4263+
(PersistentUnorderedSet<std::string> *) jitConfig->serverAOTMethodSet;
4264+
if (serverAOTMethodSet)
4265+
{
4266+
serverAOTMethodSet->~unordered_set();
4267+
TR_Memory::jitPersistentFree((void *)serverAOTMethodSet);
4268+
}
4269+
#endif // J9VM_OPT_JITSERVER
4270+
41844271
#if defined(J9VM_OPT_CRIU_SUPPORT)
41854272
if (jitConfig->javaVM->internalVMFunctions->isCRaCorCRIUSupportEnabled(jitConfig->javaVM))
41864273
{

runtime/compiler/control/JITServerCompilationThread.cpp

Lines changed: 76 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,72 @@ 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+
1124+
// If the cache exists but is not loaded, get() will set
1125+
// pending to True and return NULL for aotCache;
1126+
// we treat this NULL as a failure like any other NULL
1127+
bool pending = false;
1128+
auto aotCache = aotCacheMap->get(aotCacheName, 0, pending);
1129+
1130+
std::vector<std::string> methodSignaturesV;
1131+
if (aotCache)
1132+
{
1133+
auto cachedMethodMonitor = aotCache->getCachedMethodMonitor();
1134+
try
1135+
{
1136+
{
1137+
OMR::CriticalSection cs(cachedMethodMonitor);
1138+
1139+
auto cachedAOTMethod = aotCache->getCachedMethodHead();
1140+
methodSignaturesV.reserve(aotCache->getCachedMethodMap().size());
1141+
1142+
for (;cachedAOTMethod != NULL;
1143+
cachedAOTMethod = cachedAOTMethod->getNextRecord())
1144+
{
1145+
const SerializedAOTMethod &serializedAOTMethod = cachedAOTMethod->data();
1146+
methodSignaturesV.push_back(std::string(serializedAOTMethod.signature()));
1147+
}
1148+
}
1149+
}
1150+
catch (const std::bad_alloc &e)
1151+
{
1152+
if (TR::Options::isAnyVerboseOptionSet(TR_VerboseJITServer))
1153+
TR_VerboseLog::writeLineLocked(TR_Vlog_FAILURE,
1154+
"std::bad_alloc: %s",
1155+
e.what());
1156+
}
1157+
1158+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
1159+
{
1160+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
1161+
"Sending the list of AOT methods size %d",
1162+
methodSignaturesV.size());
1163+
}
1164+
}
1165+
else // Failed getting aotCache, treat pending as a failure
1166+
{
1167+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
1168+
{
1169+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer, "Failed getting aotCache");
1170+
}
1171+
}
1172+
stream->write(JITServer::MessageType::AOTCacheMap_reply, methodSignaturesV);
1173+
1174+
abortCompilation = true;
1175+
deleteStream = true;
1176+
}
11041177

11051178
// Acquire VM access
11061179
//

runtime/compiler/control/rossa.cpp

Lines changed: 121 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_)
@@ -1921,6 +1924,83 @@ onLoadInternal(
19211924
return 0;
19221925
}
19231926

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

19252005
extern "C" int32_t
19262006
aboutToBootstrap(J9JavaVM * javaVM, J9JITConfig * jitConfig)
@@ -2191,6 +2271,47 @@ aboutToBootstrap(J9JavaVM * javaVM, J9JITConfig * jitConfig)
21912271
UT_MODULE_LOADED(J9_UTINTERFACE_FROM_VM(javaVM));
21922272
Trc_JIT_VMInitStages_Event1(curThread);
21932273
Trc_JIT_portableSharedCache_enabled_or_disabled(curThread, J9_ARE_ANY_BITS_SET(javaVM->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_ENABLE_PORTABLE_SHARED_CACHE) ? 1 : 0);
2274+
2275+
#if defined(J9VM_OPT_JITSERVER)
2276+
if (!persistentInfo->getJITServerUseAOTCache())
2277+
{
2278+
TR::Options::getCmdLineOptions()->setOption(TR_RequestJITServerCachedMethods, false);
2279+
}
2280+
2281+
jitConfig->serverAOTMethodSet = NULL;
2282+
if (TR::Options::getCmdLineOptions()->getOption(TR_RequestJITServerCachedMethods))
2283+
{
2284+
// Ask the server for its cached methods
2285+
if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::CLIENT)
2286+
{
2287+
if (JITServerHelpers::isServerAvailable())
2288+
{
2289+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
2290+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
2291+
"Creating a thread to ask the server for its cached methods");
2292+
2293+
IDATA result = javaVM->internalVMFunctions->createThreadWithCategory(
2294+
(omrthread_t *) &(jitConfig->serverAOTQueryThread),
2295+
javaVM->defaultOSStackSize,
2296+
J9THREAD_PRIORITY_NORMAL,
2297+
0,
2298+
&fetchServerCachedAOTMethods,
2299+
(void *) jitConfig,
2300+
J9THREAD_CATEGORY_SYSTEM_JIT_THREAD
2301+
);
2302+
2303+
if (result != J9THREAD_SUCCESS)
2304+
{
2305+
if (TR::Options::getVerboseOption(TR_VerboseJITServer))
2306+
TR_VerboseLog::writeLineLocked(TR_Vlog_JITServer,
2307+
"Query thread not created");
2308+
}
2309+
}
2310+
}
2311+
}
2312+
#endif // J9VM_OPT_JITSERVER
2313+
2314+
21942315
return 0;
21952316
}
21962317

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 = 68; // ID: +/QzEedP8cjGovxgYECy
131+
static const uint16_t MINOR_NUMBER = 69; // ID: zhVsTX9SmmM39Qf52qpp
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
@@ -258,6 +258,8 @@ const char *messageNames[] =
258258
"KnownObjectTable_getReferenceField",
259259
"KnownObjectTable_getKnownObjectTableDumpInfo",
260260
"AOTCache_getROMClassBatch",
261+
"AOTCacheMap_request",
262+
"AOTCacheMap_reply"
261263
};
262264

263265
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
@@ -285,6 +285,9 @@ enum MessageType : uint16_t
285285

286286
AOTCache_getROMClassBatch,
287287

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

0 commit comments

Comments
 (0)