-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Detect cold CallTarget invalidation and reset its profile; Limit number of recompilations within a time period #11610
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
base: master
Are you sure you want to change the base?
Changes from 5 commits
ec0c74f
b4d6789
138dbde
5825caf
ef73c05
982855e
456d142
aba94d3
1c6c89f
af50258
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,11 +176,24 @@ private Lazy lazy() { | |
|
||
private final HotSpotVMConfigAccess vmConfigAccess; | ||
|
||
/** | ||
* This constant is used to detect when a method was invalidated by HotSpot because the code | ||
* cache heuristic considered it cold. | ||
*/ | ||
private final int coldMethodInvalidationReason; | ||
|
||
/** | ||
* This constant is used when Truffle invalidates an installed code. | ||
*/ | ||
private final int jvmciReplacedMethodInvalidationReason; | ||
|
||
public HotSpotTruffleRuntime(TruffleCompilationSupport compilationSupport) { | ||
super(compilationSupport, Arrays.asList(HotSpotOptimizedCallTarget.class, InstalledCode.class, HotSpotThreadLocalHandshake.class, HotSpotTruffleRuntime.class)); | ||
installCallBoundaryMethods(null); | ||
|
||
this.vmConfigAccess = new HotSpotVMConfigAccess(HotSpotJVMCIRuntime.runtime().getConfigStore()); | ||
this.jvmciReplacedMethodInvalidationReason = vmConfigAccess.getConstant("nmethod::InvalidationReason::JVMCI_REPLACED_WITH_NEW_CODE", Integer.class, -1); | ||
this.coldMethodInvalidationReason = vmConfigAccess.getConstant("nmethod::InvalidationReason::UNLOADING_COLD", Integer.class, -1); | ||
|
||
int jvmciReservedReference0Offset = vmConfigAccess.getFieldOffset("JavaThread::_jvmci_reserved_oop0", Integer.class, "oop", -1); | ||
if (jvmciReservedReference0Offset == -1) { | ||
|
@@ -644,6 +657,10 @@ protected int getObjectAlignment() { | |
return getVMOptionValue("ObjectAlignmentInBytes", Integer.class); | ||
} | ||
|
||
public int getJVMCIReplacedMethodInvalidationReason() { | ||
return this.jvmciReplacedMethodInvalidationReason; | ||
} | ||
|
||
@Override | ||
protected int getArrayIndexScale(Class<?> componentType) { | ||
MetaAccessProvider meta = getMetaAccess(); | ||
|
@@ -736,4 +753,25 @@ private static CompilationActivityMode resolveHotSpotActivityMode(int i) { | |
default -> throw CompilerDirectives.shouldNotReachHere("Invalid CompilationActivityMode " + i); | ||
}; | ||
} | ||
|
||
/** | ||
* When running as part of HotSpot we should pay special attention to CallTargets (CTs) that | ||
* have been flushed from the code cache because they were cold (According to Code Cache's | ||
* heuristics). Truffle's CallTargets' Profile counter don't decay. For that reason, we need | ||
* special handling for cold (according to code cache heuristics) CTs that were flushed from the | ||
* code cache. Otherwise, we can enter a recompilation cycle because Truffle will always see the | ||
* method as hot (because the profile counters never reset). To handle this case we reset the CT | ||
* profile whenever its prior compilation was invalidated because it was cold. | ||
*/ | ||
@Override | ||
protected boolean shouldAbortCompilation(OptimizedCallTarget callTarget) { | ||
HotSpotOptimizedCallTarget hsCallTarget = (HotSpotOptimizedCallTarget) callTarget; | ||
if (hsCallTarget.getInvalidationReason() == this.coldMethodInvalidationReason) { | ||
hsCallTarget.resetCompilationProfile(); | ||
hsCallTarget.resetInstalledCode(); | ||
|
||
listeners.onProfileReset(hsCallTarget); | ||
return true; | ||
} | ||
return false; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.