Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Track JIT body invalidation reasons as bit flags #21050

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion runtime/compiler/control/HookedByTheJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2595,7 +2595,9 @@ void jitClassesRedefined(J9VMThread * currentThread, UDATA classCount, J9JITRede
if (bodyInfo)
{
reportHookDetail(currentThread, "jitClassesRedefined", " Invalidate method body stale=%p startPC=%p", staleMethod, startPC);
TR::Recompilation::invalidateMethodBody(startPC, fe);
TR::Recompilation::invalidateMethodBody(
startPC, fe, TR_JitBodyInvalidations::HCR);

bodyInfo->setDisableSampling(true);
TR_PersistentMethodInfo *pmi = bodyInfo->getMethodInfo();
if (pmi)
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/control/J9CompilationStrategy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ TR_OptimizationPlan *J9::CompilationStrategy::processEvent(TR_MethodEvent *event
hotnessLevel = bodyInfo->getHotness();
plan = TR_OptimizationPlan::alloc(hotnessLevel);
*newPlanCreated = true;
bodyInfo->getMethodInfo()->incrementNumberOfInvalidations();
bodyInfo->getMethodInfo()->addInvalidationReasons(bodyInfo->invalidationReasons());

// the following is just for compatibility with older implementation
//bodyInfo->getMethodInfo()->setNextCompileLevel(hotnessLevel, false); // no profiling
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 @@ -33,6 +33,7 @@
#endif

#include "control/OMRCompilationStrategy.hpp"
#include "control/RecompilationInfo.hpp"
#include "compile/CompilationTypes.hpp"
#include "runtime/CodeCacheManager.hpp"

Expand Down
5 changes: 2 additions & 3 deletions runtime/compiler/control/J9Recompilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ TR_PersistentMethodInfo::TR_PersistentMethodInfo(TR::Compilation *comp) :
_bestProfileInfo(0),
_optimizationPlan(0),
_catchBlockCounter(0),
_numberOfInvalidations(0),
_numberOfPreexistenceInvalidations(0),
_numberOfInlinedMethodRedefinition(0),
_numPrexAssumptions(0)
{
Expand Down Expand Up @@ -619,7 +619,7 @@ TR_PersistentMethodInfo::TR_PersistentMethodInfo(TR_OpaqueMethodBlock *methodInf
_bestProfileInfo(0),
_optimizationPlan(0),
_catchBlockCounter(0),
_numberOfInvalidations(0),
_numberOfPreexistenceInvalidations(0),
_numberOfInlinedMethodRedefinition(0),
_numPrexAssumptions(0)
{
Expand Down Expand Up @@ -654,7 +654,6 @@ TR_PersistentJittedBodyInfo::TR_PersistentJittedBodyInfo(
_flags(0),
_sampleIntervalCount(0),
_startCount(0),
_isInvalidated(false),
_aggressiveRecompilationChances((uint8_t)TR::Options::_aggressiveRecompilationChances),
_startPCAfterPreviousCompile(0),
_longRunningInterpreted(false),
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/control/J9Recompilation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class Recompilation : public OMR::RecompilationConnector

static bool isAlreadyBeingCompiled(TR_OpaqueMethodBlock *methodInfo, void *startPC, TR_FrontEnd *fe);
static void methodCannotBeRecompiled(void *oldStartPC, TR_FrontEnd *fe);
static void invalidateMethodBody(void *startPC, TR_FrontEnd *fe);
static void invalidateMethodBody(void *startPC, TR_FrontEnd *fe, TR_JitBodyInvalidations::Reason reason);

// Called at runtime to sample a method
//
Expand Down
5 changes: 2 additions & 3 deletions runtime/compiler/control/OptionsPostRestore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,8 @@ J9::OptionsPostRestore::invalidateCompiledMethod(J9Method *method, TR_J9VMBase *
}

TR_PersistentMethodInfo *pmi = bodyInfo->getMethodInfo();
pmi->setIsExcludedPostRestore();

TR::Recompilation::invalidateMethodBody(startPC, fej9);
TR::Recompilation::invalidateMethodBody(
startPC, fej9, TR_JitBodyInvalidations::PostRestoreExclude);

// TODO: add method to a list to check the stack of java threads to print out message
}
Expand Down
67 changes: 54 additions & 13 deletions runtime/compiler/control/RecompilationInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,25 @@ static int32_t profilingFreqTable [] = { 19, 29, 47, 47, 47, 53 }; /
namespace OMR { class Recompilation; }
namespace J9 { class Recompilation; }

class TR_JitBodyInvalidations
{
public:
enum Reason
{
HCR, // outermost method has been obsoleted by HCR
Preexistence, // preexistence assumption has been invalidated
PostRestoreExclude, // method is excluded post-restore, should be interpreted
};

bool isEmpty() const { return _flags.getValue() == 0; }
bool contains(Reason reason) const { return _flags.testAny(1 << reason); }
void add(Reason reason) { _flags.set(1 << reason); }
void add(TR_JitBodyInvalidations reasons) { _flags.set(reasons._flags.getValue()); }

private:
flags8_t _flags;
};

// Persistent information associated with a method for recompilation
//
class TR_PersistentMethodInfo
Expand Down Expand Up @@ -157,8 +176,16 @@ class TR_PersistentMethodInfo

bool doesntKillAnything() { return _flags.testAll(RefinedAliasesMask); }

bool isExcludedPostRestore() { return _flags.testAny(IsExcludedPostRestore); }
void setIsExcludedPostRestore(bool b = true) { _flags.set(IsExcludedPostRestore, b); }
bool isExcludedPostRestore()
{
return _invalidationReasons.contains(TR_JitBodyInvalidations::PostRestoreExclude);
}

/**
* \brief Get the set of all reasons for prior invalidations of JIT bodies
* belonging to this method.
*/
TR_JitBodyInvalidations invalidationReasons() { return _invalidationReasons; }

uint16_t getTimeStamp() { return _timeStamp; }

Expand All @@ -167,13 +194,21 @@ class TR_PersistentMethodInfo
uint32_t getCatchBlockCounter() const { return _catchBlockCounter; }
uint32_t *getCatchBlockCounterAddress() { return &_catchBlockCounter; }
void incrementCatchBlockCounter() { _catchBlockCounter++; }
uint8_t getNumberOfInvalidations() {return _numberOfInvalidations;}
void incrementNumberOfInvalidations() {_numberOfInvalidations++;}
uint8_t getNumberOfPreexistenceInvalidations() {return _numberOfPreexistenceInvalidations;}
uint8_t getNumberOfInlinedMethodRedefinition() {return _numberOfInlinedMethodRedefinition;}
void incrementNumberOfInlinedMethodRedefinition() {_numberOfInlinedMethodRedefinition++;}
int16_t getNumPrexAssumptions() {return _numPrexAssumptions;}
void incNumPrexAssumptions() {_numPrexAssumptions++;}

void addInvalidationReasons(TR_JitBodyInvalidations reasons)
{
_invalidationReasons.add(reasons);
if (reasons.contains(TR_JitBodyInvalidations::Preexistence))
{
_numberOfPreexistenceInvalidations++;
}
}

enum InfoBits
{
// Normally set by the previous compilation to indicate that the next
Expand Down Expand Up @@ -245,10 +280,6 @@ class TR_PersistentMethodInfo
WasScannedForInlining = 0x00400000, // New scanning for warm method inlining
IsInDataCache = 0x00800000, // This TR_PersistentMethodInfo is stored in the datacache for AOT

IsExcludedPostRestore = 0x01000000, // Post-restore, if a method should be excluded, this bit will allow
// J9::Recompilation::methodCannotBeRecompiled to patch the startPC
// to call the interpreter

lastFlag = 0x80000000
};

Expand Down Expand Up @@ -295,9 +326,10 @@ class TR_PersistentMethodInfo
TR_OptimizationPlan *_optimizationPlan;
uint32_t _catchBlockCounter; // how many times a catch block was executed
uint16_t _timeStamp;
uint8_t _numberOfInvalidations; // how many times this method has been invalidated
uint8_t _numberOfPreexistenceInvalidations; // how many times this method has been invalidated due to preexistence
uint8_t _numberOfInlinedMethodRedefinition; // how many times this method triggers recompilation because of its inlined callees being redefined
int16_t _numPrexAssumptions;
TR_JitBodyInvalidations _invalidationReasons;

TR_PersistentProfileInfo *_bestProfileInfo;
TR_PersistentProfileInfo *_recentProfileInfo;
Expand All @@ -306,7 +338,6 @@ class TR_PersistentMethodInfo
void setForSharedInfo(TR_PersistentProfileInfo** ptr, TR_PersistentProfileInfo *newInfo);
};


// This information is kept for every jitted method that can be recompiled
// It may be garbage collected along with the jitted method
// The only way to get the following information is via a pointer that is kept
Expand Down Expand Up @@ -346,8 +377,18 @@ class TR_PersistentJittedBodyInfo
void setSamplingRecomp() { _flags.set(SamplingRecomp, true); }
bool getIsPushedForRecompilation(){ return _flags.testAny(IsPushedForRecompilation); }
void setIsPushedForRecompilation(){ _flags.set(IsPushedForRecompilation, true); }
bool getIsInvalidated() { return _isInvalidated; }
void setIsInvalidated() { _isInvalidated = true; }

/**
* \brief Get the set of all reasons (there may be multiple) for which this
* JIT body has been invalidated.
*/
TR_JitBodyInvalidations invalidationReasons() { return _invalidationReasons; }

bool getIsInvalidated() { return !_invalidationReasons.isEmpty(); }
void setIsInvalidated(TR_JitBodyInvalidations::Reason reason)
{
_invalidationReasons.add(reason);
}

bool getFastHotRecompilation() { return _flags.testAny(FastHotRecompilation); }
void setFastHotRecompilation(bool b){ _flags.set(FastHotRecompilation, b); }
Expand Down Expand Up @@ -472,7 +513,7 @@ class TR_PersistentJittedBodyInfo
uint8_t _aggressiveRecompilationChances;
TR_Hotness _hotness;
uint8_t _numScorchingIntervals; // How many times we reached scorching recompilation decision points
bool _isInvalidated;
TR_JitBodyInvalidations _invalidationReasons;
bool _longRunningInterpreted; // This cannot be moved into _flags due to synchronization issues
TR_PersistentProfileInfo * _profileInfo;
public:
Expand Down
2 changes: 1 addition & 1 deletion runtime/compiler/control/rossa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ j9jit_testarossa_err(
// Obsolete method bodies are invalid.
//
TR::Recompilation::fixUpMethodCode(oldStartPC);
jbi->setIsInvalidated();
jbi->setIsInvalidated(TR_JitBodyInvalidations::HCR);
}

if (jbi->getIsInvalidated())
Expand Down
10 changes: 5 additions & 5 deletions runtime/compiler/runtime/JitRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,14 +237,14 @@ J9::Recompilation::sampleMethod(
}
}

void J9::Recompilation::invalidateMethodBody(void *startPC, TR_FrontEnd *fe)
void J9::Recompilation::invalidateMethodBody(
void *startPC, TR_FrontEnd *fe, TR_JitBodyInvalidations::Reason reason)
{
// Pre-existence assumptions for this method have been violated. Make the
// method no-longer runnable and schedule it for sync recompilation
//
// Make the method no longer runnable and schedule it for sync recompilation
// or switch to interpreter
J9::PrivateLinkage::LinkageInfo *linkageInfo = J9::PrivateLinkage::LinkageInfo::get(startPC);
TR_PersistentJittedBodyInfo *bodyInfo = getJittedBodyInfoFromPC(startPC);
bodyInfo->setIsInvalidated(); // bodyInfo must exist
bodyInfo->setIsInvalidated(reason); // bodyInfo must exist

// If the compilation has been attempted before then we are fine (in case of success,
// each caller is being re-directed to the new method -- in case if failure, all callers
Expand Down
3 changes: 2 additions & 1 deletion runtime/compiler/runtime/RuntimeAssumptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ TR_PreXRecompile::compensate(TR_FrontEnd *fe, bool, void *)
TR_J9VMBase *fej9 = (TR_J9VMBase *)fe;

#if (defined(TR_HOST_X86) || defined(TR_HOST_POWER) || defined(TR_HOST_S390) || defined(TR_HOST_ARM) || defined(TR_HOST_ARM64))
TR::Recompilation::invalidateMethodBody(_startPC, fe);
TR::Recompilation::invalidateMethodBody(
_startPC, fe, TR_JitBodyInvalidations::Preexistence);
// Generate a trace point
fej9->reportPrexInvalidation(_startPC);
#else
Expand Down