From c98e8827161be87d5abe233a1e40e5aab2635e91 Mon Sep 17 00:00:00 2001 From: Marius Pirvu Date: Fri, 7 Apr 2023 17:04:41 -0400 Subject: [PATCH] Provide JITServer implementation for CRIU specific FE queries Two frontend queries that are specific to CRIU, `inSnapshotMode()` and `isSnapshotModeEnabled()` need to be overridden with JITServer specific implementation that fetches the required information from the client. Three new fields were added to the `ClientSessionData.VMInfo` struct which caches information per client: bool _inSnapshotMode; bool _isSnapshotModeEnabled; bool _isNonPortableRestoreMode; `_isSnapshotModeEnabled` and `_isNonPortableRestoreMode` can be cached from the very first response of the client, because they get set when the VM is initialized and never change their value. `_inSnapshotMode` requires special handling: if the client runs in portable restore mode, then this field is always true. If the client runs in non-portable restore mode, then this field starts as true, but after a restore, it transitions to false and it stays false until the end of the JVM. While this field returns 'true', the server must always inquire the client about the value of this field. After it transitions to `false`, the server can cache its value and refrain from asking the client again. For this purpose, a new message type was introduced, `VM_inSnapshotMode` and the `MINOR_NUMBER` of JITServer has been incremented. Issue: #17117 Signed-off-by: Marius Pirvu --- .../control/JITClientCompilationThread.cpp | 28 +++++++++---- runtime/compiler/env/VMJ9.h | 4 +- runtime/compiler/env/VMJ9Server.cpp | 41 +++++++++++++++++++ runtime/compiler/env/VMJ9Server.hpp | 2 + runtime/compiler/net/CommunicationStream.hpp | 2 +- runtime/compiler/net/MessageTypes.cpp | 1 + runtime/compiler/net/MessageTypes.hpp | 1 + runtime/compiler/runtime/JITClientSession.hpp | 6 +++ 8 files changed, 75 insertions(+), 10 deletions(-) diff --git a/runtime/compiler/control/JITClientCompilationThread.cpp b/runtime/compiler/control/JITClientCompilationThread.cpp index 08a12bff495..50faa97c97a 100644 --- a/runtime/compiler/control/JITClientCompilationThread.cpp +++ b/runtime/compiler/control/JITClientCompilationThread.cpp @@ -20,6 +20,9 @@ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception *******************************************************************************/ +#include "j9cfg.h" +#include "jitprotos.h" +#include "vmaccess.h" #include "codegen/CodeGenerator.hpp" #include "codegen/PicHelpers.hpp" #include "control/CompilationRuntime.hpp" @@ -30,24 +33,22 @@ #include "env/J2IThunk.hpp" #include "env/j9methodServer.hpp" #include "env/JITServerPersistentCHTable.hpp" +#include "env/JSR292Methods.h" +#include "env/TypeLayout.hpp" #include "env/ut_j9jit.h" +#include "env/VerboseLog.hpp" #include "env/VMAccessCriticalSection.hpp" #include "env/VMJ9.h" -#include "env/VerboseLog.hpp" #include "net/ClientStream.hpp" #include "optimizer/TransformUtil.hpp" -#include "runtime/CodeCacheExceptions.hpp" #include "runtime/CodeCache.hpp" +#include "runtime/CodeCacheExceptions.hpp" #include "runtime/CodeCacheManager.hpp" #include "runtime/J9VMAccess.hpp" #include "runtime/JITClientSession.hpp" #include "runtime/JITServerAOTDeserializer.hpp" #include "runtime/JITServerIProfiler.hpp" #include "runtime/RelocationTarget.hpp" -#include "env/TypeLayout.hpp" -#include "env/JSR292Methods.h" -#include "jitprotos.h" -#include "vmaccess.h" extern TR::Monitor *assumptionTableMutex; @@ -519,7 +520,13 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes TR_ASSERT_FATAL(header, "Must have valid AOT header stored in SCC by now"); vmInfo._aotHeader = *header; } - + vmInfo._inSnapshotMode = fe->inSnapshotMode(); + vmInfo._isSnapshotModeEnabled = fe->isSnapshotModeEnabled(); +#if defined(J9VM_OPT_CRIU_SUPPORT) + vmInfo._isNonPortableRestoreMode = javaVM->internalVMFunctions->isNonPortableRestoreMode(vmThread); +#else + vmInfo._isNonPortableRestoreMode = false; +#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */ client->write(response, vmInfo, listOfCacheDescriptors, comp->getPersistentInfo()->getJITServerAOTCacheName()); } break; @@ -1205,6 +1212,13 @@ handleServerMessage(JITServer::ClientStream *client, TR_J9VM *fe, JITServer::Mes client->write(response, isStable); } break; + case MessageType::VM_inSnapshotMode: + { + client->getRecvData(); + client->write(response, fe->inSnapshotMode()); + } + break; + case MessageType::mirrorResolvedJ9Method: { // allocate a new TR_ResolvedJ9Method on the heap, to be used as a mirror for performing actions which are only diff --git a/runtime/compiler/env/VMJ9.h b/runtime/compiler/env/VMJ9.h index b03ea9bc64c..944c615df24 100644 --- a/runtime/compiler/env/VMJ9.h +++ b/runtime/compiler/env/VMJ9.h @@ -1351,7 +1351,7 @@ class TR_J9VMBase : public TR_FrontEnd * \return True if snapshots can be taken, false if no snapshots that will include this * body are allowed. */ - bool inSnapshotMode(); + virtual bool inSnapshotMode(); /** * \brief Answers whether checkpoint and restore mode is enabled (but not necessarily @@ -1359,7 +1359,7 @@ class TR_J9VMBase : public TR_FrontEnd * * \return True if checkpoint and restore mode is enabled, false otherwise. */ - bool isSnapshotModeEnabled(); + virtual bool isSnapshotModeEnabled(); protected: diff --git a/runtime/compiler/env/VMJ9Server.cpp b/runtime/compiler/env/VMJ9Server.cpp index fdc1d99e530..a3b5c1b6a94 100644 --- a/runtime/compiler/env/VMJ9Server.cpp +++ b/runtime/compiler/env/VMJ9Server.cpp @@ -2434,6 +2434,47 @@ TR_J9ServerVM::isPortableSCCEnabled() return J9_ARE_ANY_BITS_SET(vmInfo->_extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_ENABLE_PORTABLE_SHARED_CACHE); } +bool +TR_J9ServerVM::inSnapshotMode() + { + JITServer::ServerStream *stream = _compInfoPT->getMethodBeingCompiled()->_stream; + auto *vmInfo = _compInfoPT->getClientData()->getOrCacheVMInfo(stream); + if (vmInfo->_isSnapshotModeEnabled) + { + if (vmInfo->_isNonPortableRestoreMode) + { + // The VM starts in snapshot mode, but after a restore it will exit snapshot mode + if (vmInfo->_inSnapshotMode) + { + // Must ask confirmation from client that it is still running in snapshot mode + stream->write(JITServer::MessageType::VM_inSnapshotMode, JITServer::Void()); + vmInfo->_inSnapshotMode = std::get<0>(stream->read()); // cache the response + return vmInfo->_inSnapshotMode; + } + else // Once false, it will never be true again + { + return false; + } + } + else // If we are NOT in portable CRIU mode, then we are always in snapshot mode + { + return true; + } + } + else // If CRIU is disabled we cannot be in snapshot mode + { + return false; + } + } + +bool +TR_J9ServerVM::isSnapshotModeEnabled() + { + JITServer::ServerStream *stream = _compInfoPT->getMethodBeingCompiled()->_stream; + auto *vmInfo = _compInfoPT->getClientData()->getOrCacheVMInfo(stream); + return vmInfo->_isSnapshotModeEnabled; + } + bool TR_J9SharedCacheServerVM::isClassLibraryMethod(TR_OpaqueMethodBlock *method, bool vettedForAOT) { diff --git a/runtime/compiler/env/VMJ9Server.hpp b/runtime/compiler/env/VMJ9Server.hpp index f2c3b54e4c5..6e12e24a28d 100644 --- a/runtime/compiler/env/VMJ9Server.hpp +++ b/runtime/compiler/env/VMJ9Server.hpp @@ -244,6 +244,8 @@ class TR_J9ServerVM: public TR_J9VM #endif virtual TR::KnownObjectTable::Index getMemberNameFieldKnotIndexFromMethodHandleKnotIndex(TR::Compilation *comp, TR::KnownObjectTable::Index mhIndex, char *fieldName) override; virtual bool isMethodHandleExpectedType(TR::Compilation *comp, TR::KnownObjectTable::Index mhIndex, TR::KnownObjectTable::Index expectedTypeIndex) override; + virtual bool inSnapshotMode() override; + virtual bool isSnapshotModeEnabled() override; private: bool instanceOfOrCheckCastHelper(J9Class *instanceClass, J9Class* castClass, bool cacheUpdate); diff --git a/runtime/compiler/net/CommunicationStream.hpp b/runtime/compiler/net/CommunicationStream.hpp index dc958ead9f1..7d7b1f495a3 100644 --- a/runtime/compiler/net/CommunicationStream.hpp +++ b/runtime/compiler/net/CommunicationStream.hpp @@ -97,7 +97,7 @@ class CommunicationStream ClientMessage _cMsg; static const uint8_t MAJOR_NUMBER = 1; - static const uint16_t MINOR_NUMBER = 42; + static const uint16_t MINOR_NUMBER = 43; static const uint8_t PATCH_NUMBER = 0; static uint32_t CONFIGURATION_FLAGS; diff --git a/runtime/compiler/net/MessageTypes.cpp b/runtime/compiler/net/MessageTypes.cpp index 1f4525382a2..4a50e34e369 100644 --- a/runtime/compiler/net/MessageTypes.cpp +++ b/runtime/compiler/net/MessageTypes.cpp @@ -190,6 +190,7 @@ const char *messageNames[] = "VM_delegatingMethodHandleTarget", "VM_getVMTargetOffset", "VM_getVMIndexOffset", + "VM_inSnapshotMode", "CompInfo_isCompiled", "CompInfo_getPCIfCompiled", "CompInfo_getInvocationCount", diff --git a/runtime/compiler/net/MessageTypes.hpp b/runtime/compiler/net/MessageTypes.hpp index 54c81f4753e..0ed8896f3cd 100644 --- a/runtime/compiler/net/MessageTypes.hpp +++ b/runtime/compiler/net/MessageTypes.hpp @@ -199,6 +199,7 @@ enum MessageType : uint16_t VM_delegatingMethodHandleTarget, VM_getVMTargetOffset, VM_getVMIndexOffset, + VM_inSnapshotMode, // For static TR::CompilationInfo methods CompInfo_isCompiled, diff --git a/runtime/compiler/runtime/JITClientSession.hpp b/runtime/compiler/runtime/JITClientSession.hpp index 264140a2e69..61c6b16432c 100644 --- a/runtime/compiler/runtime/JITClientSession.hpp +++ b/runtime/compiler/runtime/JITClientSession.hpp @@ -319,6 +319,12 @@ class ClientSessionData TR_AOTHeader _aotHeader; TR_OpaqueClassBlock *_JavaLangObject; TR_OpaqueClassBlock *_JavaStringObject; + // The following three fields refer to CRIU support + // Do not protect them with #if defined(J9VM_OPT_CRIU_SUPPORT) because we want JITServer to be + // able to handle all clients whether or not they have CRIU support enabled + bool _inSnapshotMode; + bool _isSnapshotModeEnabled; + bool _isNonPortableRestoreMode; }; // struct VMInfo /**