tor-browser

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

Ion.h (4276B)


      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_Ion_h
      8 #define jit_Ion_h
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "mozilla/Likely.h"
     12 #include "mozilla/MemoryReporting.h"
     13 
     14 #include <stddef.h>
     15 #include <stdint.h>
     16 
     17 #include "jsfriendapi.h"
     18 #include "jspubtd.h"
     19 
     20 #include "jit/BaselineJIT.h"
     21 #include "jit/IonTypes.h"
     22 #include "jit/JitContext.h"
     23 #include "jit/JitOptions.h"
     24 #include "js/Principals.h"
     25 #include "js/TypeDecls.h"
     26 #include "vm/BytecodeUtil.h"
     27 #include "vm/JSContext.h"
     28 #include "vm/JSFunction.h"
     29 #include "vm/JSScript.h"
     30 
     31 namespace js {
     32 
     33 class RunState;
     34 
     35 namespace jit {
     36 
     37 class BaselineFrame;
     38 
     39 bool CanIonCompileScript(JSContext* cx, JSScript* script);
     40 
     41 [[nodiscard]] bool IonCompileScriptForBaselineAtEntry(JSContext* cx,
     42                                                      BaselineFrame* frame);
     43 
     44 struct IonOsrTempData {
     45  void* jitcode;
     46  uint8_t* baselineFrame;
     47 
     48  static constexpr size_t offsetOfJitCode() {
     49    return offsetof(IonOsrTempData, jitcode);
     50  }
     51  static constexpr size_t offsetOfBaselineFrame() {
     52    return offsetof(IonOsrTempData, baselineFrame);
     53  }
     54 };
     55 
     56 [[nodiscard]] bool IonCompileScriptForBaselineOSR(JSContext* cx,
     57                                                  BaselineFrame* frame,
     58                                                  uint32_t frameSize,
     59                                                  jsbytecode* pc,
     60                                                  IonOsrTempData** infoPtr);
     61 
     62 MethodStatus CanEnterIon(JSContext* cx, RunState& state);
     63 
     64 class MIRGenerator;
     65 class LIRGraph;
     66 class CodeGenerator;
     67 class LazyLinkExitFrameLayout;
     68 class WarpSnapshot;
     69 
     70 [[nodiscard]] bool OptimizeMIR(MIRGenerator* mir);
     71 LIRGraph* GenerateLIR(MIRGenerator* mir);
     72 CodeGenerator* CompileBackEnd(MIRGenerator* mir, WarpSnapshot* snapshot);
     73 
     74 void LinkIonScript(JSContext* cx, HandleScript calleescript);
     75 uint8_t* LazyLinkTopActivation(JSContext* cx, LazyLinkExitFrameLayout* frame);
     76 
     77 inline bool IsIonInlinableGetterOrSetterOp(JSOp op) {
     78  // JSOp::GetProp, JSOp::CallProp, JSOp::Length, JSOp::GetElem,
     79  // and JSOp::CallElem. (Inlined Getters)
     80  // JSOp::SetProp, JSOp::SetName, JSOp::SetGName (Inlined Setters)
     81  return IsGetPropOp(op) || IsGetElemOp(op) || IsSetPropOp(op);
     82 }
     83 
     84 inline bool IsIonInlinableOp(JSOp op) {
     85  // JSOp::Call, JSOp::FunCall, JSOp::Eval, JSOp::New (Normal Callsites) or an
     86  // inlinable getter or setter.
     87  return (IsInvokeOp(op) && !IsSpreadOp(op)) ||
     88         IsIonInlinableGetterOrSetterOp(op);
     89 }
     90 
     91 inline bool TooManyFormalArguments(unsigned nargs) {
     92  return nargs >= SNAPSHOT_MAX_NARGS || TooManyActualArguments(nargs);
     93 }
     94 
     95 inline size_t NumLocalsAndArgs(JSScript* script) {
     96  size_t num = 1 /* this */ + script->nfixed();
     97  if (JSFunction* fun = script->function()) {
     98    num += fun->nargs();
     99  }
    100  return num;
    101 }
    102 
    103 // Debugging RAII class which marks the current thread as performing an Ion
    104 // backend compilation.
    105 class MOZ_RAII AutoEnterIonBackend {
    106 public:
    107  AutoEnterIonBackend() {
    108 #ifdef DEBUG
    109    JitContext* jcx = GetJitContext();
    110    jcx->enterIonBackend();
    111 #endif
    112  }
    113 
    114 #ifdef DEBUG
    115  ~AutoEnterIonBackend() {
    116    JitContext* jcx = GetJitContext();
    117    jcx->leaveIonBackend();
    118  }
    119 #endif
    120 };
    121 
    122 bool OffThreadCompilationAvailable(JSContext* cx);
    123 
    124 void ForbidCompilation(JSContext* cx, JSScript* script);
    125 
    126 size_t SizeOfIonData(JSScript* script, mozilla::MallocSizeOf mallocSizeOf);
    127 
    128 inline bool IsIonEnabled(JSContext* cx) {
    129  if (MOZ_UNLIKELY(!IsBaselineJitEnabled(cx) || cx->options().disableIon())) {
    130    return false;
    131  }
    132 
    133  if (MOZ_LIKELY(JitOptions.ion)) {
    134    return true;
    135  }
    136  if (JitOptions.jitForTrustedPrincipals) {
    137    JS::Realm* realm = js::GetContextRealm(cx);
    138    return realm && JS::GetRealmPrincipals(realm) &&
    139           JS::GetRealmPrincipals(realm)->isSystemOrAddonPrincipal();
    140  }
    141  return false;
    142 }
    143 
    144 // Implemented per-platform.  Returns true if the flags will not require
    145 // further (lazy) computation.
    146 bool CPUFlagsHaveBeenComputed();
    147 
    148 }  // namespace jit
    149 }  // namespace js
    150 
    151 #endif /* jit_Ion_h */