InlineScriptTree.h (4393B)
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/. */ 6 7 #ifndef jit_InlineScriptTree_h 8 #define jit_InlineScriptTree_h 9 10 #include "mozilla/Assertions.h" 11 12 #include "jit/JitAllocPolicy.h" 13 #include "js/TypeDecls.h" 14 15 namespace js { 16 namespace jit { 17 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). 21 // 22 // To support this, use a tree that records the inlinings done during 23 // compilation. 24 class InlineScriptTree { 25 public: 26 // Maximum inlining depth. This is the depth used by Ion/Warp compilation. 27 // Trial inlining uses a smaller depth (see MaxICScriptDepth in 28 // TrialInlining.cpp). 29 static constexpr uint32_t MaxDepth = 8; 30 31 private: 32 // InlineScriptTree for the caller 33 InlineScriptTree* caller_; 34 35 // PC in the caller corresponding to this script. 36 jsbytecode* callerPc_; 37 38 // Script for this entry. 39 JSScript* script_; 40 41 // Child entries (linked together by nextCallee pointer) 42 InlineScriptTree* children_; 43 InlineScriptTree* nextCallee_; 44 45 // Whether this script is monomorphically inlined into its caller. 46 bool isMonomorphicallyInlined_; 47 48 public: 49 InlineScriptTree(InlineScriptTree* caller, jsbytecode* callerPc, 50 JSScript* script, bool isMonomorphicallyInlined) 51 : caller_(caller), 52 callerPc_(callerPc), 53 script_(script), 54 children_(nullptr), 55 nextCallee_(nullptr), 56 isMonomorphicallyInlined_(isMonomorphicallyInlined) {} 57 58 static inline InlineScriptTree* New(TempAllocator* allocator, 59 InlineScriptTree* caller, 60 jsbytecode* callerPc, JSScript* script, 61 bool isMonomorphicallyInlined = false); 62 63 inline InlineScriptTree* addCallee(TempAllocator* allocator, 64 jsbytecode* callerPc, 65 JSScript* calleeScript, 66 bool isMonomorphicallyInlined); 67 inline void removeCallee(InlineScriptTree* callee); 68 69 InlineScriptTree* caller() const { return caller_; } 70 71 bool isOutermostCaller() const { return caller_ == nullptr; } 72 bool hasCaller() const { return caller_ != nullptr; } 73 74 jsbytecode* callerPc() const { return callerPc_; } 75 76 JSScript* script() const { return script_; } 77 78 bool hasChildren() const { return children_ != nullptr; } 79 InlineScriptTree* firstChild() const { 80 MOZ_ASSERT(hasChildren()); 81 return children_; 82 } 83 84 bool hasNextCallee() const { return nextCallee_ != nullptr; } 85 InlineScriptTree* nextCallee() const { 86 MOZ_ASSERT(hasNextCallee()); 87 return nextCallee_; 88 } 89 90 unsigned depth() const { 91 if (isOutermostCaller()) { 92 return 1; 93 } 94 return 1 + caller_->depth(); 95 } 96 97 // Returns true if this script, or any of its callers in the 98 // inlining tree, was monomorphically inlined. If this is true, 99 // ICs transpiled into this compilation may also be transpiled 100 // into another compilation. 101 bool hasSharedICScript() const { 102 const InlineScriptTree* script = this; 103 while (!script->isOutermostCaller()) { 104 if (script->isMonomorphicallyInlined_) { 105 return true; 106 } 107 script = script->caller(); 108 } 109 return false; 110 } 111 }; 112 113 class BytecodeSite : public TempObject { 114 // InlineScriptTree identifying innermost active function at site. 115 InlineScriptTree* tree_; 116 117 // Bytecode address within innermost active function. 118 jsbytecode* pc_; 119 120 public: 121 // Wasm compilation leaves both fields null. 122 BytecodeSite() : tree_(nullptr), pc_(nullptr) {} 123 124 // Warp compilation sets both fields to non-null values. 125 BytecodeSite(InlineScriptTree* tree, jsbytecode* pc) : tree_(tree), pc_(pc) { 126 MOZ_ASSERT(tree_ != nullptr); 127 MOZ_ASSERT(pc_ != nullptr); 128 } 129 130 InlineScriptTree* tree() const { return tree_; } 131 132 jsbytecode* pc() const { return pc_; } 133 134 JSScript* script() const { return tree_ ? tree_->script() : nullptr; } 135 }; 136 137 } // namespace jit 138 } // namespace js 139 140 #endif /* jit_InlineScriptTree_h */