Skip to content

Commit

Permalink
Merge pull request #14056 from mpirvu/limitQSZ
Browse files Browse the repository at this point in the history
Impose a limit on the compilation queue size
  • Loading branch information
dsouzai committed Dec 2, 2021
2 parents 376e221 + 4d00e79 commit 3cbebb1
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
30 changes: 23 additions & 7 deletions runtime/compiler/control/CompilationRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ struct TR_SignatureCountPair
int32_t count;
};

#ifndef J9_INVOCATION_COUNT_MASK
#define J9_INVOCATION_COUNT_MASK 0x00000000FFFFFFFF
#endif

class TR_LowPriorityCompQueue
{
Expand Down Expand Up @@ -514,6 +511,8 @@ class CompilationInfo
return (((uintptr_t)method->constantPool) & J9_STARTPC_JNI_NATIVE) != 0;
}

static const intptr_t J9_INVOCATION_COUNT_MASK = 0xffffffff;

static int32_t getInvocationCount(J9Method *method)
{
#if defined(J9VM_OPT_JITSERVER)
Expand Down Expand Up @@ -600,8 +599,6 @@ class CompilationInfo
TR_ASSERT_FATAL(!TR::CompilationInfo::getStream(), "not yet implemented for JITServer");
#endif /* defined(J9VM_OPT_JITSERVER) */
intptr_t oldValue = (intptr_t)method->extra;
//intptr_t newValue = oldValue & (intptr_t)~J9_INVOCATION_COUNT_MASK;
//newValue |= (intptr_t)value;
intptr_t newValue = (intptr_t)value;
return setJ9MethodExtraAtomic(method, oldValue, newValue);
}
Expand Down Expand Up @@ -644,6 +641,25 @@ class CompilationInfo
}
return success;
}
// If the invocation count is 0, set it to the value indicated by newCount
static bool replenishInvocationCountIfExpired(J9Method *method, int32_t newCount)
{
intptr_t oldMethodExtra = (intptr_t) method->extra;
if ((oldMethodExtra & J9_STARTPC_NOT_TRANSLATED) == 0)
return false; // Do not touch compiled methods

int32_t oldCount = (int32_t)oldMethodExtra;
if (oldCount < 0)
return false; // Do not touch uncountable methods
oldCount >>= 1; // Eliminate the J9_STARTPC_NOT_TRANSLATED bit
if (oldCount != 0)
return false; // Only replenish invocation count if it expired
// Prepare the new method->extra
intptr_t oldMethodExtraUpperPart = oldMethodExtra & (~J9_INVOCATION_COUNT_MASK);
newCount = (newCount << 1) | J9_STARTPC_NOT_TRANSLATED;
intptr_t newMethodExtra = oldMethodExtraUpperPart | newCount;
return setJ9MethodExtraAtomic(method, oldMethodExtra, newMethodExtra);
}
static void setInitialInvocationCountUnsynchronized(J9Method *method, int32_t value)
{
#if defined(J9VM_OPT_JITSERVER)
Expand Down Expand Up @@ -726,12 +742,12 @@ class CompilationInfo
* Stops a compilation thread by issuing an interruption request at the threads next yield point and by changing
* its state to signal termination. Note that there can be a delay between making this request and the thread
* state changing to `COMPTHREAD_STOPPED`.
*
*
* \param compInfoPT
* The thread to be stopped.
*/
void stopCompilationThread(CompilationInfoPerThread* compInfoPT);

void suspendCompilationThread();
void resumeCompilationThread();
void purgeMethodQueue(TR_CompilationErrorCode errorCode);
Expand Down
29 changes: 29 additions & 0 deletions runtime/compiler/control/CompilationThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5891,6 +5891,35 @@ void *TR::CompilationInfo::compileOnSeparateThread(J9VMThread * vmThread, TR::Il
*compErrCode = compilationInProgress;
return 0; // mark that compilation is not yet done
}
// When the compilation queue is very large, it may be better to postpone
// the asynchronous compilations by replenishing the invocation counter.
// This avoids the overhead associated with searching the right place to
// insert into the compilation queue (which is a priority queue)
if (getMethodQueueSize() >= TR::Options::_qszLimit &&
oldStartPC == 0 && // Only look at interpreted methods
details.isOrdinaryMethod()) // Do not apply this optimization to DLT
{
J9ROMMethod *romMethod = J9_ROM_METHOD_FROM_RAM_METHOD(method);
if (!(romMethod->modifiers & J9AccNative)) // We are not allowed to change the invocation count for native methods
{
int32_t newCount = J9ROMMETHOD_HAS_BACKWARDS_BRANCHES(romMethod) ? TR_DEFAULT_INITIAL_BCOUNT : TR_DEFAULT_INITIAL_COUNT;
bool success = TR::CompilationInfo::replenishInvocationCountIfExpired(method, newCount);
if (success)
{
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance))
{
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "Reencoding count=%d for j9m=%p because Q_SZ is too large", newCount, method);
}
// Release the compilation lock and return
debugPrint(vmThread, "\tapplication thread releasing compilation monitor - comp.req. in progress\n");
debugPrint(vmThread, "-CM\n");
releaseCompMonitor(vmThread);
if (compErrCode)
*compErrCode = compilationNotNeeded;
return 0; // mark that compilation is not yet done
}
}
}
}
}
else
Expand Down
3 changes: 3 additions & 0 deletions runtime/compiler/control/J9Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ int32_t J9::Options::_qszThresholdToDowngradeOptLevel = -1; // not yet set
int32_t J9::Options::_qsziThresholdToDowngradeDuringCLP = 0; // -1 or 0 disables the feature and reverts to old behavior
int32_t J9::Options::_qszThresholdToDowngradeOptLevelDuringStartup = 100000; // a large number disables the feature
int32_t J9::Options::_cpuUtilThresholdForStarvation = 25; // 25%
int32_t J9::Options::_qszLimit = 5000; // when limit is reached the JIT will postpone new compilation requests

// If too many GCR are queued we stop counting.
// Use a large value to disable the feature. 400 is a good default
Expand Down Expand Up @@ -725,6 +726,8 @@ TR::OptionTable OMR::Options::_feOptions[] = {
{"compilationPriorityQSZThreshold=", "M<nnn>\tCompilation queue size threshold when priority of post-profiling"
"compilation requests is increased",
TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_compPriorityQSZThreshold , 0, "F%d", NOT_IN_SUBSET},
{"compilationQueueSizeLimit=", "R<nnn>\tWhen limit is reached, first-time compilations are postponed by replenishing the invocation count",
TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_qszLimit, 0, "F%d", NOT_IN_SUBSET},
{"compilationThreadAffinityMask=", "M<nnn>\taffinity mask for compilation threads. Use hexa without 0x",
TR::Options::setStaticHexadecimal, (intptr_t)&TR::Options::_compThreadAffinityMask, 0, "F%d", NOT_IN_SUBSET},
{"compilationYieldStatsHeartbeatPeriod=", "M<nnn>\tperiodically print stats about compilation yield points "
Expand Down
3 changes: 2 additions & 1 deletion runtime/compiler/control/J9Options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class OMR_EXTENSIBLE Options : public OMR::OptionsConnector

static int32_t _veryHighActiveThreadThreshold;
static int32_t getVeryHighActiveThreadThreshold() {return _veryHighActiveThreadThreshold;}

static int32_t _maxCheckcastProfiledClassTests;
static int32_t getCheckcastMaxProfiledClassTests() {return _maxCheckcastProfiledClassTests;}

Expand Down Expand Up @@ -252,6 +252,7 @@ class OMR_EXTENSIBLE Options : public OMR::OptionsConnector
static int32_t _qsziThresholdToDowngradeDuringCLP;
static int32_t _qszThresholdToDowngradeOptLevelDuringStartup;
static int32_t _cpuUtilThresholdForStarvation;
static int32_t _qszLimit; // maximum size of the compilation queue
static int32_t _compPriorityQSZThreshold;
static int32_t _GCRQueuedThresholdForCounting; // if too many GCR are queued we stop counting
static int32_t _minimumSuperclassArraySize; //size of the minimum superclass array
Expand Down

0 comments on commit 3cbebb1

Please sign in to comment.