commit 12a29323d51ed8da544013b280ff824ab889480e
parent edc1a996fb42b1106098c9604a263285a247098c
Author: Nazım Can Altınova <canaltinova@gmail.com>
Date: Wed, 26 Nov 2025 10:52:44 +0000
Bug 2002397 - Consolidate max inlining depth constants r=iain
The maximum inlining depth was duplicated across multiple locations with
some magic numbers (8, 64) that were difficult to keep synchronized.
The actual max inlining depth used by Ion/Warp is 8. This is now defined
as InlineScriptTree::MaxDepth and used directly in multiple places.
Previously the profiler code was using 64 as the inlining depth, which
was overly conservative. Now we properly use 8 there as well.
In addition to InlineScriptTree::MaxDepth, we had to keep
ProfiledFrameRange::MaxInliningDepth in the public header since it
cannot include the private InlineScriptTree.h header. However, added a
static_assert which guarantees that it stays synchronized with
InlineScriptTree::MaxDepth.
Trial inlining uses a smaller depth of 4 (now named MaxICScriptDepth) because
it only creates private IC sets up to that depth. Beyond depth 4, inlining can
still reach depth 8 by reusing shared IC data. A static_assert ensures
MaxICScriptDepth never exceeds InlineScriptTree::MaxDepth.
Differential Revision: https://phabricator.services.mozilla.com/D274057
Diffstat:
6 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/js/public/ProfilingFrameIterator.h b/js/public/ProfilingFrameIterator.h
@@ -305,8 +305,11 @@ class ProfiledFrameRange {
JSRuntime* rt_;
void* addr_;
js::jit::JitcodeGlobalEntry* entry_;
- // Assume maximum inlining depth is <64
- js::jit::CallStackFrameInfo frames_[64];
+ // Maximum inlining depth. This must match InlineScriptTree::MaxDepth.
+ // We can't use InlineScriptTree::MaxDepth directly here because this is a
+ // public header and InlineScriptTree.h is private.
+ static constexpr uint32_t MaxInliningDepth = 8;
+ js::jit::CallStackFrameInfo frames_[MaxInliningDepth];
uint32_t depth_;
};
diff --git a/js/src/jit/InlineScriptTree.h b/js/src/jit/InlineScriptTree.h
@@ -22,6 +22,13 @@ namespace jit {
// To support this, use a tree that records the inlinings done during
// compilation.
class InlineScriptTree {
+ public:
+ // Maximum inlining depth. This is the depth used by Ion/Warp compilation.
+ // Trial inlining uses a smaller depth (see MaxICScriptDepth in
+ // TrialInlining.cpp).
+ static constexpr uint32_t MaxDepth = 8;
+
+ private:
// InlineScriptTree for the caller
InlineScriptTree* caller_;
diff --git a/js/src/jit/JitcodeMap.cpp b/js/src/jit/JitcodeMap.cpp
@@ -996,6 +996,13 @@ JS_PUBLIC_API uint32_t JS::ProfiledFrameHandle::sourceId() const {
JS_PUBLIC_API JS::ProfiledFrameRange JS::GetProfiledFrames(JSContext* cx,
void* addr) {
+ // Ensure ProfiledFrameRange::MaxInliningDepth matches
+ // InlineScriptTree::MaxDepth. Please keep them in sync.
+ static_assert(ProfiledFrameRange::MaxInliningDepth ==
+ js::jit::InlineScriptTree::MaxDepth,
+ "ProfiledFrameRange::MaxInliningDepth must match "
+ "InlineScriptTree::MaxDepth");
+
JSRuntime* rt = cx->runtime();
js::jit::JitcodeGlobalTable* table =
rt->jitRuntime()->getJitcodeGlobalTable();
diff --git a/js/src/jit/TrialInlining.cpp b/js/src/jit/TrialInlining.cpp
@@ -15,6 +15,7 @@
#include "jit/CacheIRCloner.h"
#include "jit/CacheIRHealth.h"
#include "jit/CacheIRWriter.h"
+#include "jit/InlineScriptTree.h"
#include "jit/Ion.h" // TooManyFormalArguments
#include "vm/BytecodeLocation-inl.h"
@@ -72,8 +73,13 @@ bool DoTrialInlining(JSContext* cx, BaselineFrame* frame) {
return true;
}
- const uint32_t MAX_INLINING_DEPTH = 4;
- if (icScript->depth() > MAX_INLINING_DEPTH) {
+ // Maximum trial inlining depth for ICScripts. This is smaller than
+ // InlineScriptTree::MaxDepth because we can reach the bigger number if we are
+ // doing monomorphic inlining using shared IC data.
+ const uint32_t MaxICScriptDepth = 4;
+ static_assert(MaxICScriptDepth <= InlineScriptTree::MaxDepth,
+ "Trial inlining depth must not exceed max inlining depth");
+ if (icScript->depth() > MaxICScriptDepth) {
return true;
}
diff --git a/js/src/jit/WarpOracle.cpp b/js/src/jit/WarpOracle.cpp
@@ -1326,9 +1326,8 @@ AbortReasonOr<bool> WarpScriptOracle::maybeInlineCall(
// This is just a cheap check to limit the damage we can do to ourselves if
// we try to monomorphically inline an indirectly recursive call.
- const uint32_t maxInliningDepth = 8;
if (!isTrialInlined &&
- info_->inlineScriptTree()->depth() > maxInliningDepth) {
+ info_->inlineScriptTree()->depth() > InlineScriptTree::MaxDepth) {
return false;
}
diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp
@@ -13,6 +13,7 @@
#include <stdint.h> // uint8_t, uint32_t
#include "gc/Tracer.h" // js::TraceRoot
+#include "jit/InlineScriptTree.h"
#include "jit/JitcodeMap.h"
#include "jit/JitRuntime.h"
#include "js/friend/ErrorMessages.h" // JSMSG_*
@@ -761,8 +762,8 @@ uint32_t JS::ProfilingFrameIterator::extractStack(Frame* frames,
return 1;
}
- // Extract the stack for the entry. Assume maximum inlining depth is <64
- jit::CallStackFrameInfo frameInfos[64];
+ // Extract the stack for the entry.
+ jit::CallStackFrameInfo frameInfos[jit::InlineScriptTree::MaxDepth];
uint32_t depth = entry->callStackAtAddr(cx_->runtime(),
jsJitIter().resumePCinCurrentFrame(),
frameInfos, std::size(frameInfos));