tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */