From 31696a05e024e1203eff8a685ba77ba4fe1df26e Mon Sep 17 00:00:00 2001 From: Christian Humer Date: Wed, 9 Jun 2021 21:50:31 +0200 Subject: [PATCH] Fix debug stepping can cause stack overflow errors for compiled call targets. (GR-31987) (cherry picked from commit 8234931ff5b53705a1b2bf995175b06ffb026ba6) --- .../truffle/runtime/OptimizedCallTarget.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java b/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java index 8ed2dde010cc..417cbbb32fc8 100644 --- a/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java +++ b/compiler/src/org.graalvm.compiler.truffle.runtime/src/org/graalvm/compiler/truffle/runtime/OptimizedCallTarget.java @@ -483,9 +483,11 @@ protected final Object callBoundary(Object[] args) { } private boolean interpreterCall() { + boolean bypassedInstalledCode = false; if (isValid()) { // Native entry stubs were deoptimized => reinstall. runtime().bypassedInstalledCode(this); + bypassedInstalledCode = true; } ensureInitialized(); int intCallCount = this.callCount; @@ -495,7 +497,16 @@ private boolean interpreterCall() { // Check if call target is hot enough to compile if (shouldCompileImpl(intCallCount, intLoopCallCount)) { - return compile(!engine.multiTier); + boolean isCompiled = compile(!engine.multiTier); + /* + * If we bypassed the installed code chances are high that the code is currently being + * debugged. This means that returning true for the interpreter call will retry the call + * boundary. If the call boundary is retried and debug stepping would invalidate the + * entry stub again then this leads to an inconvenient stack overflow error. In order to + * avoid this we just do not return true and wait for the second execution to jump to + * the optimized code. In practice the installed code should rarely be bypassed. + */ + return isCompiled && !bypassedInstalledCode; } return false; }