diff --git a/runtime/compiler/control/CompilationThread.cpp b/runtime/compiler/control/CompilationThread.cpp
index 59b073d70c3..a6888b5905c 100644
--- a/runtime/compiler/control/CompilationThread.cpp
+++ b/runtime/compiler/control/CompilationThread.cpp
@@ -7444,13 +7444,15 @@ TR::CompilationInfoPerThreadBase::generatePerfToolEntry()
}
if (getPerfFile())
{
- j9jit_fprintf(getPerfFile(), "%p %lX %s_%s\n", getMetadata()->startPC, getMetadata()->endWarmPC - getMetadata()->startPC,
- getCompilation()->signature(), getCompilation()->getHotnessName(getCompilation()->getMethodHotness()));
+ j9jit_fprintf(getPerfFile(), "%p %lX %s_%s%s\n", getMetadata()->startPC, getMetadata()->endWarmPC - getMetadata()->startPC,
+ getCompilation()->signature(), getCompilation()->getHotnessName(getCompilation()->getMethodHotness()),
+ getMetadata()->flags & JIT_METADATA_IS_FSD_COMP ? "_fsd" : "");
// If there is a cold section, add another line
if (getMetadata()->startColdPC)
{
- j9jit_fprintf(getPerfFile(), "%p %lX %s_%s\n", getMetadata()->startColdPC, getMetadata()->endPC - getMetadata()->startColdPC,
- getCompilation()->signature(), getCompilation()->getHotnessName(getCompilation()->getMethodHotness())); // should we change the name of the method?
+ j9jit_fprintf(getPerfFile(), "%p %lX %s_%s%s\n", getMetadata()->startColdPC, getMetadata()->endPC - getMetadata()->startColdPC,
+ getCompilation()->signature(), getCompilation()->getHotnessName(getCompilation()->getMethodHotness()),
+ getMetadata()->flags & JIT_METADATA_IS_FSD_COMP ? "_fsd" : ""); // should we change the name of the method?
}
// Flushing degrades performance, but ensures that we have the data
// written even if the JVM is abruptly terminated
@@ -9259,6 +9261,7 @@ TR::CompilationInfoPerThreadBase::wrappedCompile(J9PortLibrary *portLib, void *
{
options->setInsertGCRTrees(); // This is a recommendation not a directive
}
+
// Disable some expensive optimizations
if (options->getOptLevel() <= warm && !options->getOption(TR_EnableExpensiveOptsAtWarm))
{
@@ -11252,6 +11255,9 @@ void TR::CompilationInfoPerThreadBase::logCompilationSuccess(
if (isJniNative)
TR_VerboseLog::write(" JNI"); // flag JNI compilations
+ if (compiler->getOption(TR_FullSpeedDebug))
+ TR_VerboseLog::write(" FSD");
+
if (compiler->getOption(TR_EnableOSR))
TR_VerboseLog::write(" OSR");
diff --git a/runtime/compiler/control/J9Options.cpp b/runtime/compiler/control/J9Options.cpp
index e4da13c7b19..ef20c4d3bcd 100644
--- a/runtime/compiler/control/J9Options.cpp
+++ b/runtime/compiler/control/J9Options.cpp
@@ -69,6 +69,7 @@ bool enableCompiledMethodLoadHookOnly = false;
// Static data initialization
// -----------------------------------------------------------------------------
+J9::Options::FSDInitStatus J9::Options::_fsdInitStatus = J9::Options::FSDInitStatus::FSDInit_NotInitialized;
bool J9::Options::_doNotProcessEnvVars = false; // set through XX options in Java
bool J9::Options::_reportByteCodeInfoAtCatchBlock = false;
int32_t J9::Options::_samplingFrequencyInIdleMode = 1000; // ms
@@ -2872,6 +2873,60 @@ J9::Options::fePostProcessAOT(void * base)
return true;
}
+bool
+J9::Options::isFSDNeeded(J9JavaVM *javaVM, J9HookInterface **vmHooks)
+ {
+ return
+#if defined(J9VM_JIT_FULL_SPEED_DEBUG)
+ (javaVM->requiredDebugAttributes & J9VM_DEBUG_ATTRIBUTE_CAN_ACCESS_LOCALS) ||
+#endif
+#if defined (J9VM_INTERP_HOT_CODE_REPLACEMENT)
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_POP_FRAMES_INTERRUPT) ||
+#endif
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_BREAKPOINT) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_FRAME_POPPED) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_FRAME_POP) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_GET_FIELD) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_PUT_FIELD) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_GET_STATIC_FIELD) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_PUT_STATIC_FIELD) ||
+ (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_SINGLE_STEP);
+ }
+
+J9::Options::FSDInitStatus
+J9::Options::initializeFSDIfNeeded(J9JavaVM *javaVM, J9HookInterface **vmHooks, bool &doAOT)
+ {
+ if (self()->isFSDNeeded(javaVM, vmHooks))
+ {
+ static bool TR_DisableFullSpeedDebug = (feGetEnv("TR_DisableFullSpeedDebug") != NULL);
+ static bool TR_DisableFullSpeedDebugAOT = (feGetEnv("TR_DisableFullSpeedDebugAOT") != NULL);
+#if defined(J9VM_JIT_FULL_SPEED_DEBUG)
+ if (TR_DisableFullSpeedDebug)
+ {
+ return FSDInitStatus::FSDInit_Error;
+ }
+ else if (TR_DisableFullSpeedDebugAOT)
+ {
+ doAOT = false;
+ }
+
+ self()->setOption(TR_FullSpeedDebug);
+ self()->setOption(TR_DisableDirectToJNI);
+ //setOption(TR_DisableNoVMAccess);
+ //setOption(TR_DisableAsyncCompilation);
+ //setOption(TR_DisableInterpreterProfiling, true);
+
+ initializeFSD(javaVM);
+
+ _fsdInitStatus = FSDInitStatus::FSDInit_Initialized;
+#else
+ _fsdInitStatus = FSDInitStatus::FSDInit_Error;
+#endif
+ }
+
+ return _fsdInitStatus;
+ }
+
bool J9::Options::feLatePostProcess(void * base, TR::OptionSet * optionSet)
{
// vmPostProcess is called indirectly from the JIT_INITIALIZED phase
@@ -2887,6 +2942,7 @@ bool J9::Options::feLatePostProcess(void * base, TR::OptionSet * optionSet)
J9JITConfig * jitConfig = (J9JITConfig*)base;
J9JavaVM * javaVM = jitConfig->javaVM;
J9HookInterface * * vmHooks = javaVM->internalVMFunctions->getVMHookInterface(javaVM);
+ J9VMThread * vmThread = javaVM->internalVMFunctions->currentVMThread(javaVM);
TR_J9VMBase * vm = TR_J9VMBase::get(jitConfig, 0);
TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);
@@ -2915,46 +2971,19 @@ bool J9::Options::feLatePostProcess(void * base, TR::OptionSet * optionSet)
#endif
// Determine whether or not to call the hooked helpers
- //
- if (
-#if defined(J9VM_JIT_FULL_SPEED_DEBUG)
- (javaVM->requiredDebugAttributes & J9VM_DEBUG_ATTRIBUTE_CAN_ACCESS_LOCALS) ||
-#endif
-#if defined (J9VM_INTERP_HOT_CODE_REPLACEMENT)
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_POP_FRAMES_INTERRUPT) ||
-#endif
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_BREAKPOINT) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_FRAME_POPPED) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_FRAME_POP) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_GET_FIELD) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_PUT_FIELD) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_GET_STATIC_FIELD) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_PUT_STATIC_FIELD) ||
- (*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_SINGLE_STEP))
- {
- static bool TR_DisableFullSpeedDebug = (feGetEnv("TR_DisableFullSpeedDebug") != NULL);
- static bool TR_DisableFullSpeedDebugAOT = (feGetEnv("TR_DisableFullSpeedDebugAOT") != NULL);
-#if defined(J9VM_JIT_FULL_SPEED_DEBUG)
- if (TR_DisableFullSpeedDebug)
- {
- return false;
- }
- else if (TR_DisableFullSpeedDebugAOT)
- {
- doAOT = false;
- }
-
- self()->setOption(TR_FullSpeedDebug);
- self()->setOption(TR_DisableDirectToJNI);
- //setOption(TR_DisableNoVMAccess);
- //setOption(TR_DisableAsyncCompilation);
- //setOption(TR_DisableInterpreterProfiling, true);
-
- initializeFSD(javaVM);
-#else
- return false;
-#endif
+ FSDInitStatus fsdStatus = initializeFSDIfNeeded(javaVM, vmHooks, doAOT);
+ if (fsdStatus == FSDInitStatus::FSDInit_Error)
+ {
+ return false;
}
+#if defined(J9VM_OPT_CRIU_SUPPORT)
+ else if (fsdStatus == FSDInitStatus::FSDInit_NotInitialized
+ && javaVM->internalVMFunctions->isDebugOnRestoreEnabled(vmThread))
+ {
+ self()->setOption(TR_FullSpeedDebug);
+ self()->setOption(TR_DisableDirectToJNI);
+ }
+#endif
bool exceptionEventHooked = false;
if ((*vmHooks)->J9HookDisable(vmHooks, J9HOOK_VM_EXCEPTION_CATCH))
@@ -3593,3 +3622,53 @@ J9::Options::closeLogFileForClientOptions()
}
}
#endif /* defined(J9VM_OPT_JITSERVER) */
+
+#if defined(J9VM_OPT_CRIU_SUPPORT)
+void
+J9::Options::resetFSDOptions()
+ {
+ // TODO: Need to handle if these options were set/unset as part of
+ // the post restore options processing.
+
+ setOption(TR_EnableHCR);
+
+ setOption(TR_FullSpeedDebug, false);
+ setOption(TR_DisableDirectToJNI, false);
+
+ setReportByteCodeInfoAtCatchBlock(false);
+ setOption(TR_DisableProfiling, false);
+ setOption(TR_DisableNewInstanceImplOpt, false);
+ setDisabled(OMR::redundantGotoElimination, false);
+ setDisabled(OMR::loopReplicator, false);
+ setOption(TR_DisableMethodHandleThunks, false);
+ }
+
+void
+J9::Options::resetFSDOptionsForAll()
+ {
+ resetFSDOptions();
+ for (auto optionSet = _optionSets; optionSet; optionSet = optionSet->getNext())
+ {
+ optionSet->getOptions()->resetFSDOptions();
+ }
+ }
+
+J9::Options::FSDInitStatus
+J9::Options::resetFSD(J9JavaVM *vm, J9VMThread *vmThread, bool &doAOT)
+ {
+ J9HookInterface ** vmHooks = vm->internalVMFunctions->getVMHookInterface(vm);
+ auto fsdStatusJIT = getCmdLineOptions()->initializeFSDIfNeeded(vm, vmHooks, doAOT);
+ auto fsdStatusAOT = getAOTCmdLineOptions()->initializeFSDIfNeeded(vm, vmHooks, doAOT);
+ TR_ASSERT_FATAL (fsdStatusJIT == fsdStatusAOT, "fsdStatusJIT=%d != fsdStatusAOT=%d!\n", fsdStatusJIT, fsdStatusAOT);
+
+ if (fsdStatusJIT == TR::Options::FSDInitStatus::FSDInit_NotInitialized
+ && !vm->internalVMFunctions->isCheckpointAllowed(vmThread)
+ && vm->internalVMFunctions->isDebugOnRestoreEnabled(vmThread))
+ {
+ getCmdLineOptions()->resetFSDOptionsForAll();
+ getAOTCmdLineOptions()->resetFSDOptionsForAll();
+ }
+
+ return fsdStatusJIT;
+ }
+#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */
diff --git a/runtime/compiler/control/J9Options.hpp b/runtime/compiler/control/J9Options.hpp
index 7427e95e5bf..9e8fce4231c 100644
--- a/runtime/compiler/control/J9Options.hpp
+++ b/runtime/compiler/control/J9Options.hpp
@@ -147,7 +147,14 @@ class OMR_EXTENSIBLE Options : public OMR::OptionsConnector
Options(TR::Options &other) : OMR::OptionsConnector(other) {}
+ enum FSDInitStatus
+ {
+ FSDInit_Error,
+ FSDInit_NotInitialized,
+ FSDInit_Initialized
+ };
+ static FSDInitStatus _fsdInitStatus;
static bool _doNotProcessEnvVars;
@@ -611,6 +618,9 @@ class OMR_EXTENSIBLE Options : public OMR::OptionsConnector
bool showPID();
void openLogFiles(J9JITConfig *jitConfig);
+ bool isFSDNeeded(J9JavaVM *javaVM, J9HookInterface **vmHooks);
+ FSDInitStatus initializeFSDIfNeeded(J9JavaVM *javaVM, J9HookInterface **vmHooks, bool &doAOT);
+
#if defined(J9VM_OPT_JITSERVER)
void setupJITServerOptions();
@@ -623,6 +633,12 @@ class OMR_EXTENSIBLE Options : public OMR::OptionsConnector
void closeLogFileForClientOptions();
#endif /* defined(J9VM_OPT_JITSERVER) */
+#if defined(J9VM_OPT_CRIU_SUPPORT)
+ static FSDInitStatus resetFSD(J9JavaVM *vm, J9VMThread *vmThread, bool &doAOT);
+ void resetFSDOptions();
+ void resetFSDOptionsForAll();
+#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */
+
private:
#if defined(J9VM_OPT_JITSERVER)
diff --git a/runtime/compiler/control/OptionsPostRestore.cpp b/runtime/compiler/control/OptionsPostRestore.cpp
index 92e0072a232..5f48bff7192 100644
--- a/runtime/compiler/control/OptionsPostRestore.cpp
+++ b/runtime/compiler/control/OptionsPostRestore.cpp
@@ -702,6 +702,16 @@ J9::OptionsPostRestore::postProcessInternalCompilerOptions()
disableAOT = true;
}
+ bool doAOT = !disableAOT;
+ TR::Options::FSDInitStatus fsdStatus = TR::Options::resetFSD(vm, _vmThread, doAOT);
+ disableAOT = !doAOT;
+
+ if (fsdStatus == TR::Options::FSDInitStatus::FSDInit_Error)
+ {
+ invalidateAll = true;
+ disableAOT = true;
+ }
+
// Invalidate method bodies if needed
invalidateCompiledMethodsIfNeeded(invalidateAll);
diff --git a/runtime/compiler/runtime/J9Runtime.hpp b/runtime/compiler/runtime/J9Runtime.hpp
index c5611c94d0a..a0f9c116bb7 100644
--- a/runtime/compiler/runtime/J9Runtime.hpp
+++ b/runtime/compiler/runtime/J9Runtime.hpp
@@ -198,6 +198,7 @@ typedef struct TR_AOTMethodHeader {
#define TR_AOTMethodHeader_IsNotCapableOfExceptionHook 0x00000100
#define TR_AOTMethodHeader_UsesOSR 0x00000200
#define TR_AOTMethodHeader_MethodTracingEnabled 0x00000400
+#define TR_AOTMethodHeader_UsesFSD 0x00000800
typedef struct TR_AOTInliningStats
diff --git a/runtime/compiler/runtime/MetaData.cpp b/runtime/compiler/runtime/MetaData.cpp
index 453b3889c5c..3ff2a15fd21 100644
--- a/runtime/compiler/runtime/MetaData.cpp
+++ b/runtime/compiler/runtime/MetaData.cpp
@@ -1621,6 +1621,11 @@ createMethodMetaData(
aotMethodHeaderEntry->flags |= TR_AOTMethodHeader_TMDisabled;
}
+ if (comp->getOption(TR_FullSpeedDebug))
+ {
+ aotMethodHeaderEntry->flags |= TR_AOTMethodHeader_UsesFSD;
+ }
+
// totalAllocated space is in comp object
TR_ASSERT(comp->getTotalNeededDataCacheSpace() == aotMethodHeaderEntry->compileMethodDataSize, "Size missmatach");
}
diff --git a/runtime/compiler/runtime/RelocationRuntime.cpp b/runtime/compiler/runtime/RelocationRuntime.cpp
index 1b790ca6b68..65b7472b462 100644
--- a/runtime/compiler/runtime/RelocationRuntime.cpp
+++ b/runtime/compiler/runtime/RelocationRuntime.cpp
@@ -695,7 +695,7 @@ TR_RelocationRuntime::relocateAOTCodeAndData(U_8 *tempDataStart,
excptEntry32->ramMethod = actualMethod;
excptEntry32++;
- if (_comp->getOption(TR_FullSpeedDebug))
+ if (_aotMethodHeaderEntry->flags & TR_AOTMethodHeader_UsesFSD)
excptEntry32 = (J9JIT32BitExceptionTableEntry *) ((uint8_t *) excptEntry32 + 4);
numExcptionRanges--;
diff --git a/test/functional/cmdLineTests/criu/playlist.xml b/test/functional/cmdLineTests/criu/playlist.xml
index e87824e9c6a..06638eaedcc 100644
--- a/test/functional/cmdLineTests/criu/playlist.xml
+++ b/test/functional/cmdLineTests/criu/playlist.xml
@@ -104,6 +104,8 @@
-Xgcpolicy:optavgpause
-Xgcpolicy:gencon -Xgcthreads64 -XX:CheckpointGCThreads=1
-Xgcpolicy:gencon -Xgcthreads1
+ -XX:+DebugOnRestore -Xjit
+ -XX:+DebugOnRestore -Xjit:count=0
@@ -140,6 +142,7 @@
-Xgcpolicy:optavgpause
-Xgcpolicy:gencon -Xgcthreads64 -XX:CheckpointGCThreads=1
-Xgcpolicy:gencon -Xgcthreads1
+ -XX:+DebugOnRestore
@@ -174,6 +177,8 @@
-Xjit
-Xjit:count=0
-Xjit:vlog=vlog
+ -XX:+DebugOnRestore -Xjit
+ -XX:+DebugOnRestore -Xjit:count=0