Skip to content

Commit

Permalink
Recompile FSD Bodies generated pre-checkpoint under -XX:+DebugOnRestore
Browse files Browse the repository at this point in the history
Post-restore, recompile all methods that were compiled using FSD to
ensure steady state throughput is not impacted by the code quality of FSD
code. Additionally, attempt compilation of all methods that failed first
time compilation, as the failure is more than likely due to the
constraints imposed by FSD compilation (e.g., JNI methods).

Signed-off-by: Irwin D'Souza <[email protected]>
  • Loading branch information
dsouzai committed Apr 11, 2024
1 parent 1e9f472 commit 69956f0
Show file tree
Hide file tree
Showing 9 changed files with 462 additions and 13 deletions.
2 changes: 1 addition & 1 deletion runtime/compiler/control/CompilationRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ class CompilationInfo
static bool createCompilationInfo(J9JITConfig * jitConfig);
static void freeCompilationInfo(J9JITConfig *jitConfig);
static TR::CompilationInfo *get(J9JITConfig * = 0) { return _compilationRuntime; }
static bool shouldRetryCompilation(TR_MethodToBeCompiled *entry, TR::Compilation *comp);
static bool shouldRetryCompilation(J9VMThread *vmThread, TR_MethodToBeCompiled *entry, TR::Compilation *comp);
static bool shouldAbortCompilation(TR_MethodToBeCompiled *entry, TR::PersistentInfo *persistentInfo);
static bool canRelocateMethod(TR::Compilation * comp);
static int computeCompilationThreadPriority(J9JavaVM *vm);
Expand Down
55 changes: 52 additions & 3 deletions runtime/compiler/control/CompilationThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2229,7 +2229,7 @@ bool TR::CompilationInfo::shouldAbortCompilation(TR_MethodToBeCompiled *entry, T
// This method has side-effects, It modifies the optimization plan and persistentMethodInfo
// This method is executed with compilationMonitor in hand
//
bool TR::CompilationInfo::shouldRetryCompilation(TR_MethodToBeCompiled *entry, TR::Compilation *comp)
bool TR::CompilationInfo::shouldRetryCompilation(J9VMThread *vmThread, TR_MethodToBeCompiled *entry, TR::Compilation *comp)
{
// The JITServer should not retry compilations on it's own,
// it should let the client make that decision
Expand Down Expand Up @@ -2467,7 +2467,29 @@ bool TR::CompilationInfo::shouldRetryCompilation(TR_MethodToBeCompiled *entry, T
// don't carry the decision to generate AOT code to the next compilation
// because it may no longer be the right thing to do at that point
if (tryCompilingAgain)
{
entry->_useAotCompilation = false;
}
#if defined(J9VM_OPT_CRIU_SUPPORT)
else if (entry->_compErrCode != compilationOK)
{
J9JavaVM *javaVM = compInfo->getJITConfig()->javaVM;
if (javaVM->internalVMFunctions->isDebugOnRestoreEnabled(vmThread)
&& javaVM->internalVMFunctions->isCheckpointAllowed(vmThread)
&& !compInfo->getCRRuntime()->isCheckpointInProgress()
&& !compInfo->isInShutdownMode())
{
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCheckpointRestoreDetails))
TR_VerboseLog::writeLineLocked(TR_Vlog_CHECKPOINT_RESTORE, "Pushing failed compilation %p", entry->getMethodDetails().getMethod());

TR_FilterBST *filter = NULL;
OMR::CriticalSection pushFailedComp(compInfo->getCRRuntime()->getCRRuntimeMonitor());
if (comp && entry->_compInfoPT->methodCanBeCompiled(comp->trMemory(), comp->fej9(), comp->getMethodBeingCompiled(), filter))
compInfo->getCRRuntime()->pushFailedCompilation(entry->getMethodDetails().getMethod());
}
}
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */


return tryCompilingAgain;
}
Expand Down Expand Up @@ -2525,6 +2547,11 @@ void TR::CompilationInfo::purgeMethodQueue(TR_CompilationErrorCode errorCode)
getLowPriorityCompQueue().purgeLPQ();
// and from JProfiling queue
getJProfilingCompQueue().purge();

#if defined(J9VM_OPT_CRIU_SUPPORT)
// and from the memoized compilations lists
getCRRuntime()->purgeMemoizedCompilations();
#endif
}

void TR::CompilationInfoPerThread::suspendCompilationThread()
Expand Down Expand Up @@ -6855,7 +6882,7 @@ TR::CompilationInfoPerThreadBase::installAotCachedMethod(
{
entry->_compErrCode = returnCode;
entry->setAotCodeToBeRelocated(NULL); // reset if relocation failed
entry->_tryCompilingAgain = _compInfo.shouldRetryCompilation(entry, compiler); // this will set entry->_doNotUseAotCodeFromSharedCache = true;
entry->_tryCompilingAgain = _compInfo.shouldRetryCompilation(vmThread, entry, compiler); // this will set entry->_doNotUseAotCodeFromSharedCache = true;

// Feature [Defect 172216/180384]: Implement hints for failed AOT validations. The idea is that the failed validations are due to the
// fact that AOT methods are loaded at a lower count than when they were compiled so the JVM is given less opportunity to resolve things.
Expand Down Expand Up @@ -7943,7 +7970,7 @@ TR::CompilationInfoPerThreadBase::postCompilationTasks(J9VMThread * vmThread,
{
metaData = 0;
}
else if (TR::CompilationInfo::shouldRetryCompilation(entry, _compiler))
else if (TR::CompilationInfo::shouldRetryCompilation(vmThread, entry, _compiler))
{
startPC = entry->_oldStartPC; // startPC == oldStartPC means compilation failure
entry->_tryCompilingAgain = true;
Expand Down Expand Up @@ -10535,6 +10562,26 @@ TR::CompilationInfo::compilationEnd(J9VMThread * vmThread, TR::IlGeneratorMethod
else
{
jitMethodTranslated(vmThread, method, startPC);
#if defined(J9VM_OPT_CRIU_SUPPORT)
if (jitConfig->javaVM->internalVMFunctions->isCheckpointAllowed(vmThread)
&& jitConfig->javaVM->internalVMFunctions->isDebugOnRestoreEnabled(vmThread))
{
if (comp->getRecompilationInfo() && comp->getRecompilationInfo()->getJittedBodyInfo())
{
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCheckpointRestoreDetails))
TR_VerboseLog::writeLineLocked(TR_Vlog_CHECKPOINT_RESTORE, "Will force %p to be recompiled post-restore", method);

OMR::CriticalSection pushForcedRecomp(compInfo->getCRRuntime()->getCRRuntimeMonitor());
compInfo->getCRRuntime()->pushForcedRecompilation(method);
}
else
{
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerboseCheckpointRestoreDetails))
TR_VerboseLog::writeLineLocked(TR_Vlog_CHECKPOINT_RESTORE, "Cannot force %p to be recompiled post-restore because the bodyInfo does not exist", method);
}
}
#endif /* defined(J9VM_OPT_CRIU_SUPPORT) */

}
}
}
Expand Down Expand Up @@ -10876,6 +10923,8 @@ void TR::CompilationInfoPerThreadBase::logCompilationSuccess(
case TR_PersistentMethodInfo::RecompDueToEdo:
catchBlockCounter = bodyInfo->getMethodInfo()->getCatchBlockCounter();
recompReason = 'E'; break;
case TR_PersistentMethodInfo::RecompDueToCRIU:
recompReason = 'F'; break;
} // end switch
bodyInfo->getMethodInfo()->setReasonForRecompilation(0); // reset the flags
}
Expand Down
43 changes: 37 additions & 6 deletions runtime/compiler/control/HookedByTheJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,7 @@ static void jitHookClassesUnload(J9HookInterface * * hookInterface, UDATA eventN
J9VMThread * vmThread = unloadedEvent->currentThread;
J9JITConfig * jitConfig = vmThread->javaVM->jitConfig;

TR_J9VMBase * vmj9 = TR_J9VMBase::get(jitConfig, vmThread);
TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);
TR::PersistentInfo * persistentInfo = compInfo->getPersistentInfo();

Expand Down Expand Up @@ -2055,7 +2056,9 @@ static void jitHookAnonClassesUnload(J9HookInterface * * hookInterface, UDATA ev
}

J9JITConfig *jitConfig = vmThread->javaVM->jitConfig;
TR_J9VMBase * vmj9 = TR_J9VMBase::get(jitConfig, vmThread);
TR::CompilationInfo * compInfo = TR::CompilationInfo::get(jitConfig);

#if defined(J9VM_JIT_DYNAMIC_LOOP_TRANSFER)
compInfo->cleanDLTRecordOnUnload();
if (compInfo->getDLT_HT())
Expand All @@ -2068,7 +2071,6 @@ static void jitHookAnonClassesUnload(J9HookInterface * * hookInterface, UDATA ev
#if defined(J9VM_INTERP_PROFILING_BYTECODES)
if (!TR::Options::getCmdLineOptions()->getOption(TR_DisableIProfilerThread))
{
TR_J9VMBase * vmj9 = (TR_J9VMBase *)(TR_J9VMBase::get(jitConfig, vmThread));
TR_IProfiler *iProfiler = vmj9->getIProfiler();
if (iProfiler) // even if Iprofiler is disabled, there might be some buffers in the queue
{ // which need to be invalidated
Expand All @@ -2085,6 +2087,11 @@ static void jitHookAnonClassesUnload(J9HookInterface * * hookInterface, UDATA ev
for (J9Class* j9clazz = unloadedEvent->anonymousClassesToUnload; j9clazz; j9clazz = j9clazz->gcLink)
{
cgOnClassUnloading(j9clazz);

#if defined(J9VM_OPT_CRIU_SUPPORT)
compInfo->getCRRuntime()->removeMethodsFromMemoizedCompilations<J9Class>(j9clazz);
#endif // defined(J9VM_OPT_CRIU_SUPPORT)

j9clazz->classLoader = NULL;
}
}
Expand Down Expand Up @@ -2134,6 +2141,9 @@ static void jitHookClassUnload(J9HookInterface * * hookInterface, UDATA eventNum
// remove from compilation request queue any methods that belong to this class
fej9->acquireCompilationLock();
fej9->invalidateCompilationRequestsForUnloadedMethods(clazz, false);
#if defined(J9VM_OPT_CRIU_SUPPORT)
compInfo->getCRRuntime()->removeMethodsFromMemoizedCompilations<J9Class>(j9clazz);
#endif // defined(J9VM_OPT_CRIU_SUPPORT)
fej9->releaseCompilationLock();

J9Method * resolvedMethods = (J9Method *) fej9->getMethods((TR_OpaqueClassBlock*)j9clazz);
Expand Down Expand Up @@ -2412,6 +2422,10 @@ void jitClassesRedefined(J9VMThread * currentThread, UDATA classCount, J9JITRede
TR_ASSERT(0,"JIT HCR should make all methods recompilable, so startPC=%p should have a persistentBodyInfo", startPC);
}
}

#if defined(J9VM_OPT_CRIU_SUPPORT)
compInfo->getCRRuntime()->removeMethodsFromMemoizedCompilations<J9Method>(staleMethod);
#endif // defined(J9VM_OPT_CRIU_SUPPORT)
}
classPair = (J9JITRedefinedClass *) ((char *) classPair->methodList + (classPair->methodCount * sizeof(struct J9JITMethodEquivalence)));
}
Expand All @@ -2424,8 +2438,13 @@ void jitClassesRedefined(J9VMThread * currentThread, UDATA classCount, J9JITRede
reportHookDetail(currentThread, "jitClassesRedefined", " Invalidate all compilation requests");
fe->invalidateCompilationRequestsForUnloadedMethods(NULL, true);

//clean up the trampolines
// clean up the trampolines
TR::CodeCacheManager::instance()->onFSDDecompile();

#if defined(J9VM_OPT_CRIU_SUPPORT)
// purge memoized compilations
compInfo->getCRRuntime()->purgeMemoizedCompilations();
#endif
}

fe->releaseCompilationLock();
Expand Down Expand Up @@ -6204,7 +6223,11 @@ static int32_t J9THREAD_PROC samplerThreadProc(void * entryarg)
CompilationDensity compDensity;
#endif /* defined(J9VM_OPT_JITSERVER) */

TR_J9VMBase *fe = TR_J9VMBase::get(jitConfig, 0);
#if defined(J9VM_OPT_CRIU_SUPPORT)
bool forcedRecompilations = false;
#endif

TR_J9VMBase *fe = TR_J9VMBase::get(jitConfig, samplerThread);

j9thread_set_name(j9thread_self(), "JIT Sampler");
while (!shutdownSamplerThread)
Expand All @@ -6218,7 +6241,8 @@ static int32_t J9THREAD_PROC samplerThreadProc(void * entryarg)
crtTime += samplingPeriod;

#if defined(J9VM_OPT_CRIU_SUPPORT)
if (vm->internalVMFunctions->isCheckpointAllowed(samplerThread)
if (vm->internalVMFunctions->isCheckpointAllowed(samplerThread))
{
/* It's ok to not acquire the comp monitor here. Even if at this
* point a checkpoint isn't in progress but later it is, the
* checkpoint will not complete until the sampler thread suspends
Expand All @@ -6230,9 +6254,16 @@ static int32_t J9THREAD_PROC samplerThreadProc(void * entryarg)
* isn't true (e.g., due to shutdown), then the sampler thread will
* not suspend itself.
*/
&& compInfo->getCRRuntime()->shouldSuspendThreadsForCheckpoint())
if (compInfo->getCRRuntime()->shouldSuspendThreadsForCheckpoint())
suspendSamplerThreadForCheckpoint(samplerThread,jitConfig, compInfo);
}
else if (vm->internalVMFunctions->isDebugOnRestoreEnabled(samplerThread))
{
suspendSamplerThreadForCheckpoint(samplerThread,jitConfig, compInfo);
if (!forcedRecompilations && jitConfig->javaVM->phase == J9VM_PHASE_NOT_STARTUP)
{
forcedRecompilations = true;
compInfo->getCRRuntime()->recompileMethodsCompiledPreCheckpoint();
}
}
#endif // #if defined(J9VM_OPT_CRIU_SUPPORT)

Expand Down
7 changes: 7 additions & 0 deletions runtime/compiler/control/J9CompilationStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@ TR_OptimizationPlan *J9::CompilationStrategy::processEvent(TR_MethodEvent *event
*newPlanCreated = true;
}
break;
case TR_MethodEvent::ForcedRecompilationPostRestore:
{
hotnessLevel = warm;
plan = TR_OptimizationPlan::alloc(hotnessLevel);
*newPlanCreated = true;
}
break;
default:
TR_ASSERT(0, "Bad event type %d", event->_eventType);
}
Expand Down
1 change: 1 addition & 0 deletions runtime/compiler/control/J9CompilationStrategy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class TR_MethodEvent
JitCompilationInducedByDLT,
HWPRecompilationTrigger,
CompilationBeforeCheckpoint,
ForcedRecompilationPostRestore,
NumEvents // must be the last one
};
int32_t _eventType;
Expand Down
5 changes: 5 additions & 0 deletions runtime/compiler/control/OptionsPostRestore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,8 @@ J9::OptionsPostRestore::invalidateCompiledMethodsIfNeeded(bool invalidateAll)
shouldInvalidateCompiledMethod(method, fej9, compilationFiltersExist))
{
invalidateCompiledMethod(method, fej9);
if (!invalidateAll)
_compInfo->getCRRuntime()->removeMethodsFromMemoizedCompilations<J9Method>(method);
}
}
}
Expand All @@ -510,6 +512,9 @@ J9::OptionsPostRestore::invalidateCompiledMethodsIfNeeded(bool invalidateAll)
}
javaVM->internalVMFunctions->allClassesEndDo(&classWalkState);

if (invalidateAll)
_compInfo->getCRRuntime()->purgeMemoizedCompilations();

j9nls_printf(PORTLIB, (UDATA) J9NLS_WARNING, J9NLS_JIT_CHECKPOINT_RESTORE_CODE_INVALIDATED);
}
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/compiler/control/RecompilationInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ class TR_PersistentMethodInfo
RecompDueToRI = 0x000A0000,
RecompDueToJProfiling = 0x000B0000,
RecompDueToInlinedMethodRedefinition = 0x000C0000,
RecompDueToCRIU = 0x000D0000,

// NOTE: recompilations due to EDO decrementation cannot be tracked precisely
// because they are triggered from a snippet (must change the code for snippet)
// Also, the recompilations after a profiling step cannot be marked as such.
Expand Down
Loading

0 comments on commit 69956f0

Please sign in to comment.