From 87efa9e22e4e0d3df0dbe2a506bd7af6af111b02 Mon Sep 17 00:00:00 2001 From: Eman Elsabban Date: Fri, 19 Jun 2020 08:37:52 -0700 Subject: [PATCH] Stored the ram classes before sending the compilationreq to server Stored the ramClasses in an unordered_set before sending the compilation request to the server. I check if the ram class (clazz) is cached in the set. if it is not stored then it will be cached in the set and will send the corresponding ROM by setting the serializeClass bool to true. If the clazz is already in the cache set this means it has already been sent to the server. So send the clazz again but with empty ROM class (empty string for ROM Class) by setting serializeClass bool to false. issue: #9708 Signed-off-by: Eman Elsabban --- .../compiler/control/CompilationRuntime.hpp | 5 ++++ .../compiler/control/CompilationThread.cpp | 2 ++ runtime/compiler/control/HookedByTheJit.cpp | 5 ++++ .../control/JITClientCompilationThread.cpp | 24 ++++++++++++++++--- .../control/JITServerCompilationThread.cpp | 17 +++++++++++-- runtime/compiler/control/JITServerHelpers.cpp | 13 ++++++++-- runtime/compiler/control/JITServerHelpers.hpp | 3 ++- runtime/compiler/net/CommunicationStream.hpp | 2 +- 8 files changed, 62 insertions(+), 9 deletions(-) diff --git a/runtime/compiler/control/CompilationRuntime.hpp b/runtime/compiler/control/CompilationRuntime.hpp index f4be1edb64f..beeae8e08e4 100644 --- a/runtime/compiler/control/CompilationRuntime.hpp +++ b/runtime/compiler/control/CompilationRuntime.hpp @@ -41,6 +41,7 @@ #include "control/rossa.h" #include "runtime/RelocationRuntime.hpp" #if defined(J9VM_OPT_JITSERVER) +#include "control/JITServerHelpers.hpp" #include "env/PersistentCollections.hpp" #include "net/ServerStream.hpp" #endif /* defined(J9VM_OPT_JITSERVER) */ @@ -1009,6 +1010,7 @@ class CompilationInfo } void setNewlyExtendedClasses(PersistentUnorderedMap *it) { _newlyExtendedClasses = it; } + TR::Monitor *getclassesCachedAtServerMonitor() const { return _classesCachedAtServerMonitor; } TR::Monitor *getSequencingMonitor() const { return _sequencingMonitor; } uint32_t getCompReqSeqNo() const { return _compReqSeqNo; } uint32_t incCompReqSeqNo() { return ++_compReqSeqNo; } @@ -1017,6 +1019,7 @@ class CompilationInfo uint8_t getCHTableUpdateDone() const { return _chTableUpdateFlags; } const PersistentVector &getJITServerSslKeys() const { return _sslKeys; } + PersistentUnorderedSet & getclassesCachedAtServer() { return _classesCachedAtServer; } void addJITServerSslKey(const std::string &key) { _sslKeys.push_back(key); } const PersistentVector &getJITServerSslCerts() const { return _sslCerts; } void addJITServerSslCert(const std::string &cert) { _sslCerts.push_back(cert); } @@ -1227,6 +1230,8 @@ class CompilationInfo #if defined(J9VM_OPT_JITSERVER) ClientSessionHT *_clientSessionHT; // JITServer hashtable that holds session information about JITClients + PersistentUnorderedSet _classesCachedAtServer; + TR::Monitor *_classesCachedAtServerMonitor; PersistentVector *_unloadedClassesTempList; // JITServer list of classes unloaded PersistentVector *_illegalFinalFieldModificationList; // JITServer list of classes that have J9ClassHasIllegalFinalFieldModifications is set TR::Monitor *_sequencingMonitor; // Used for ordering outgoing messages at the client diff --git a/runtime/compiler/control/CompilationThread.cpp b/runtime/compiler/control/CompilationThread.cpp index 287d0def09e..2c16cc72134 100644 --- a/runtime/compiler/control/CompilationThread.cpp +++ b/runtime/compiler/control/CompilationThread.cpp @@ -1058,6 +1058,7 @@ TR::CompilationInfo::CompilationInfo(J9JITConfig *jitConfig) : #if defined(J9VM_OPT_JITSERVER) _sslKeys(decltype(_sslKeys)::allocator_type(TR::Compiler->persistentAllocator())), _sslCerts(decltype(_sslCerts)::allocator_type(TR::Compiler->persistentAllocator())), + _classesCachedAtServer(decltype(_classesCachedAtServer)::allocator_type(TR::Compiler->persistentAllocator())), #endif /* defined(J9VM_OPT_JITSERVER) */ _persistentMemory(pointer_cast(jitConfig->scratchSegment)), _sharedCacheReloRuntime(jitConfig), @@ -1158,6 +1159,7 @@ TR::CompilationInfo::CompilationInfo(J9JITConfig *jitConfig) : _illegalFinalFieldModificationList = NULL; _newlyExtendedClasses = NULL; _sequencingMonitor = TR::Monitor::create("JIT-SequencingMonitor"); + _classesCachedAtServerMonitor = TR::Monitor::create("JIT-ClassesCachedAtServerMonitor"); _compReqSeqNo = 0; _chTableUpdateFlags = 0; _localGCCounter = 0; diff --git a/runtime/compiler/control/HookedByTheJit.cpp b/runtime/compiler/control/HookedByTheJit.cpp index d78cefca02e..1a1e23b0696 100644 --- a/runtime/compiler/control/HookedByTheJit.cpp +++ b/runtime/compiler/control/HookedByTheJit.cpp @@ -2115,7 +2115,12 @@ static void jitHookClassUnload(J9HookInterface * * hookInterface, UDATA eventNum #if defined(J9VM_OPT_JITSERVER) // Add to JITServer unload list if (compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::CLIENT) + { compInfo->getUnloadedClassesTempList()->push_back(clazz); + // Loop through the set to find the class that needs to be purged. + // Once found erase from the set. + compInfo->getclassesCachedAtServer().erase(unloadedEvent->clazz); + } #endif } #endif /* defined (J9VM_GC_DYNAMIC_CLASS_UNLOADING)*/ diff --git a/runtime/compiler/control/JITClientCompilationThread.cpp b/runtime/compiler/control/JITClientCompilationThread.cpp index 29973289f89..e3a5d218b8a 100644 --- a/runtime/compiler/control/JITClientCompilationThread.cpp +++ b/runtime/compiler/control/JITClientCompilationThread.cpp @@ -44,7 +44,6 @@ #include "vmaccess.h" extern TR::Monitor *assumptionTableMutex; - // TODO: This method is copied from runtime/jit_vm/ctsupport.c, // in the future it's probably better to make that method publicly accessible static UDATA @@ -162,6 +161,7 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes J9VMThread *vmThread = compInfoPT->getCompilationThread(); TR_Memory *trMemory = compInfoPT->getCompilation()->trMemory(); TR::Compilation *comp = compInfoPT->getCompilation(); + TR::CompilationInfo *compInfo = compInfoPT->getCompilationInfo(); TR_ASSERT(TR::MonitorTable::get()->getClassUnloadMonitorHoldCount(compInfoPT->getCompThreadId()) == 0, "Must not hold classUnloadMonitor"); TR::MonitorTable *table = TR::MonitorTable::get(); @@ -216,6 +216,10 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes std::string encoded = FlatPersistentClassInfo::serializeHierarchy(table); client->write(response, ranges, unloadedClasses->getMaxRanges(), encoded); + { + OMR::CriticalSection romClassCache(compInfo->getclassesCachedAtServerMonitor()); + compInfo->getclassesCachedAtServer().clear(); + } break; } @@ -1137,7 +1141,7 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes case MessageType::ResolvedMethod_getRemoteROMClassAndMethods: { J9Class *clazz = std::get<0>(client->getRecvData()); - client->write(response, JITServerHelpers::packRemoteROMClassInfo(clazz, fe->vmThread(), trMemory)); + client->write(response, JITServerHelpers::packRemoteROMClassInfo(clazz, fe->vmThread(), trMemory, true)); } break; case MessageType::ResolvedMethod_isJNINative: @@ -3135,7 +3139,21 @@ remoteCompile( if (compiler->isOptServer()) compiler->setOption(TR_Server); - auto classInfoTuple = JITServerHelpers::packRemoteROMClassInfo(clazz, compiler->fej9vm()->vmThread(), compiler->trMemory()); + + // Check the _classesCachedAtServer set to determine whether JITServer is likely to have this class already cached. + // If so, do not send the ROMClass content to save network traffic. + bool serializeClass = false; + { + OMR::CriticalSection romClassCache(compInfo->getclassesCachedAtServerMonitor()); + if (compInfo->getclassesCachedAtServer().find(clazz) == compInfo->getclassesCachedAtServer().end()) + { + // clazz not found. Send the romClass to JITServer. + compInfo->getclassesCachedAtServer().insert(clazz); + serializeClass = true; + } + } + + auto classInfoTuple = JITServerHelpers::packRemoteROMClassInfo(clazz, compiler->fej9vm()->vmThread(), compiler->trMemory(), serializeClass); std::string optionsStr = TR::Options::packOptions(compiler->getOptions()); std::string recompMethodInfoStr = compiler->isRecompilationEnabled() ? std::string((char *) compiler->getRecompilationInfo()->getMethodInfo(), sizeof(TR_PersistentMethodInfo)) : std::string(); diff --git a/runtime/compiler/control/JITServerCompilationThread.cpp b/runtime/compiler/control/JITServerCompilationThread.cpp index f9d38c036d1..7a1edca38a4 100644 --- a/runtime/compiler/control/JITServerCompilationThread.cpp +++ b/runtime/compiler/control/JITServerCompilationThread.cpp @@ -525,10 +525,23 @@ TR::CompilationInfoPerThreadRemote::processEntry(TR_MethodToBeCompiled &entry, J } // Get the ROMClass for the method to be compiled if it is already cached // Or read it from the compilation request and cache it otherwise - J9ROMClass *romClass = NULL; + J9ROMClass *romClass = NULL; if (!(romClass = JITServerHelpers::getRemoteROMClassIfCached(clientSession, clazz))) { - romClass = JITServerHelpers::romClassFromString(std::get<0>(classInfoTuple), compInfo->persistentMemory()); + // Check whether the first argument of the classInfoTuple is an empty string + // If it's an empty string then I dont't need to cache it + if(!(std::get<0>(classInfoTuple).empty())) + { + romClass = JITServerHelpers::romClassFromString(std::get<0>(classInfoTuple), compInfo->persistentMemory()); + } + else + { + // When I receive an empty string I need to check whether the server had the class caches + // It could be a renewed connection, so that's a new server because old one was shutdown + // When the server receives an empty ROM class it would check if it actually has this class cached, + // And if it it's not cached, send a request to the client + romClass = JITServerHelpers::getRemoteROMClass(clazz, stream, compInfo->persistentMemory(), &classInfoTuple); + } JITServerHelpers::cacheRemoteROMClass(getClientData(), clazz, romClass, &classInfoTuple); } diff --git a/runtime/compiler/control/JITServerHelpers.cpp b/runtime/compiler/control/JITServerHelpers.cpp index fb636025e83..70748c844cb 100644 --- a/runtime/compiler/control/JITServerHelpers.cpp +++ b/runtime/compiler/control/JITServerHelpers.cpp @@ -282,7 +282,7 @@ JITServerHelpers::getRemoteROMClassIfCached(ClientSessionData *clientSessionData } JITServerHelpers::ClassInfoTuple -JITServerHelpers::packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, TR_Memory *trMemory) +JITServerHelpers::packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, TR_Memory *trMemory, bool serializeClass) { // Always use the base VM here. // If this method is called inside AOT compilation, TR_J9SharedCacheVM will @@ -324,7 +324,7 @@ JITServerHelpers::packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, T uintptr_t classChainOffsetOfIdentifyingLoaderForClazz = fe->sharedCache() ? fe->sharedCache()->getClassChainOffsetOfIdentifyingLoaderForClazzInSharedCacheNoFail((TR_OpaqueClassBlock *)clazz) : 0; - return std::make_tuple(packROMClass(clazz->romClass, trMemory), methodsOfClass, baseClass, numDims, parentClass, + return std::make_tuple(serializeClass ? packROMClass(clazz->romClass, trMemory) : std::string(), methodsOfClass, baseClass, numDims, parentClass, TR::Compiler->cls.getITable((TR_OpaqueClassBlock *) clazz), methodTracingInfo, classHasFinalFields, classDepthAndFlags, classInitialized, byteOffsetToLockword, leafComponentClass, classLoader, hostClass, componentClass, arrayClass, totalInstanceSize, @@ -350,6 +350,15 @@ JITServerHelpers::getRemoteROMClass(J9Class *clazz, JITServer::ServerStream *str return romClassFromString(std::get<0>(*classInfoTuple), trMemory->trPersistentMemory()); } +J9ROMClass * +JITServerHelpers::getRemoteROMClass(J9Class *clazz, JITServer::ServerStream *stream, TR_PersistentMemory *trMemory, ClassInfoTuple *classInfoTuple) + { + stream->write(JITServer::MessageType::ResolvedMethod_getRemoteROMClassAndMethods, clazz); + const auto &recv = stream->read(); + *classInfoTuple = std::get<0>(recv); + return romClassFromString(std::get<0>(*classInfoTuple), trMemory); + } + // Return true if able to get data from cache, return false otherwise. bool JITServerHelpers::getAndCacheRAMClassInfo(J9Class *clazz, ClientSessionData *clientSessionData, JITServer::ServerStream *stream, ClassInfoDataType dataType, void *data) diff --git a/runtime/compiler/control/JITServerHelpers.hpp b/runtime/compiler/control/JITServerHelpers.hpp index 3632ff4e291..1aa5dbffd4a 100644 --- a/runtime/compiler/control/JITServerHelpers.hpp +++ b/runtime/compiler/control/JITServerHelpers.hpp @@ -71,11 +71,12 @@ class JITServerHelpers uintptr_t, std::vector // 20: _classChainOffsetOfIdentifyingLoaderForClazz 21. _origROMMethods >; - static ClassInfoTuple packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, TR_Memory *trMemory); + static ClassInfoTuple packRemoteROMClassInfo(J9Class *clazz, J9VMThread *vmThread, TR_Memory *trMemory, bool serializeClass); static void cacheRemoteROMClass(ClientSessionData *clientSessionData, J9Class *clazz, J9ROMClass *romClass, ClassInfoTuple *classInfoTuple); static void cacheRemoteROMClass(ClientSessionData *clientSessionData, J9Class *clazz, J9ROMClass *romClass, ClassInfoTuple *classInfoTuple, ClientSessionData::ClassInfo &classInfo); static J9ROMClass *getRemoteROMClassIfCached(ClientSessionData *clientSessionData, J9Class *clazz); static J9ROMClass *getRemoteROMClass(J9Class *, JITServer::ServerStream *stream, TR_Memory *trMemory, ClassInfoTuple *classInfoTuple); + static J9ROMClass *getRemoteROMClass(J9Class *, JITServer::ServerStream *stream, TR_PersistentMemory *trMemory, ClassInfoTuple *classInfoTuple); static J9ROMClass *romClassFromString(const std::string &romClassStr, TR_PersistentMemory *trMemory); static bool getAndCacheRAMClassInfo(J9Class *clazz, ClientSessionData *clientSessionData, JITServer::ServerStream *stream, ClassInfoDataType dataType, void *data); static bool getAndCacheRAMClassInfo(J9Class *clazz, ClientSessionData *clientSessionData, JITServer::ServerStream *stream, ClassInfoDataType dataType1, void *data1, diff --git a/runtime/compiler/net/CommunicationStream.hpp b/runtime/compiler/net/CommunicationStream.hpp index 675050d4ad6..e5afed202ce 100644 --- a/runtime/compiler/net/CommunicationStream.hpp +++ b/runtime/compiler/net/CommunicationStream.hpp @@ -102,7 +102,7 @@ class CommunicationStream ClientMessage _cMsg; static const uint8_t MAJOR_NUMBER = 1; - static const uint16_t MINOR_NUMBER = 7; + static const uint16_t MINOR_NUMBER = 8; static const uint8_t PATCH_NUMBER = 0; static uint32_t CONFIGURATION_FLAGS;