1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jit_InlineScriptTree_h
8 #define jit_InlineScriptTree_h
10 #include "mozilla/Assertions.h"
12 #include "jit/JitAllocPolicy.h"
13 #include "js/TypeDecls.h"
18 // The compiler at various points needs to be able to store references to the
19 // current inline path (the sequence of scripts and call-pcs that lead to the
20 // current function being inlined).
22 // To support this, use a tree that records the inlinings done during
24 class InlineScriptTree
{
25 // InlineScriptTree for the caller
26 InlineScriptTree
* caller_
;
28 // PC in the caller corresponding to this script.
29 jsbytecode
* callerPc_
;
31 // Script for this entry.
34 // Child entries (linked together by nextCallee pointer)
35 InlineScriptTree
* children_
;
36 InlineScriptTree
* nextCallee_
;
38 // Whether this script is monomorphically inlined into its caller.
39 bool isMonomorphicallyInlined_
;
42 InlineScriptTree(InlineScriptTree
* caller
, jsbytecode
* callerPc
,
43 JSScript
* script
, bool isMonomorphicallyInlined
)
49 isMonomorphicallyInlined_(isMonomorphicallyInlined
) {}
51 static inline InlineScriptTree
* New(TempAllocator
* allocator
,
52 InlineScriptTree
* caller
,
53 jsbytecode
* callerPc
, JSScript
* script
,
54 bool isMonomorphicallyInlined
= false);
56 inline InlineScriptTree
* addCallee(TempAllocator
* allocator
,
58 JSScript
* calleeScript
,
59 bool isMonomorphicallyInlined
);
60 inline void removeCallee(InlineScriptTree
* callee
);
62 InlineScriptTree
* caller() const { return caller_
; }
64 bool isOutermostCaller() const { return caller_
== nullptr; }
65 bool hasCaller() const { return caller_
!= nullptr; }
67 jsbytecode
* callerPc() const { return callerPc_
; }
69 JSScript
* script() const { return script_
; }
71 bool hasChildren() const { return children_
!= nullptr; }
72 InlineScriptTree
* firstChild() const {
73 MOZ_ASSERT(hasChildren());
77 bool hasNextCallee() const { return nextCallee_
!= nullptr; }
78 InlineScriptTree
* nextCallee() const {
79 MOZ_ASSERT(hasNextCallee());
83 unsigned depth() const {
84 if (isOutermostCaller()) {
87 return 1 + caller_
->depth();
90 // Returns true if this script, or any of its callers in the
91 // inlining tree, was monomorphically inlined. If this is true,
92 // ICs transpiled into this compilation may also be transpiled
93 // into another compilation.
94 bool hasSharedICScript() const {
95 const InlineScriptTree
* script
= this;
96 while (!script
->isOutermostCaller()) {
97 if (script
->isMonomorphicallyInlined_
) {
100 script
= script
->caller();
106 class BytecodeSite
: public TempObject
{
107 // InlineScriptTree identifying innermost active function at site.
108 InlineScriptTree
* tree_
;
110 // Bytecode address within innermost active function.
114 // Wasm compilation leaves both fields null.
115 BytecodeSite() : tree_(nullptr), pc_(nullptr) {}
117 // Warp compilation sets both fields to non-null values.
118 BytecodeSite(InlineScriptTree
* tree
, jsbytecode
* pc
) : tree_(tree
), pc_(pc
) {
119 MOZ_ASSERT(tree_
!= nullptr);
120 MOZ_ASSERT(pc_
!= nullptr);
123 InlineScriptTree
* tree() const { return tree_
; }
125 jsbytecode
* pc() const { return pc_
; }
127 JSScript
* script() const { return tree_
? tree_
->script() : nullptr; }
133 #endif /* jit_InlineScriptTree_h */