tor-browser

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

MachineState.h (3604B)


      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_MachineState_h
      8 #define jit_MachineState_h
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "mozilla/Variant.h"
     12 
     13 #include <stdint.h>
     14 
     15 #include "jit/Registers.h"
     16 #include "jit/RegisterSets.h"
     17 
     18 namespace js::jit {
     19 
     20 // Information needed to recover machine register state. This supports two
     21 // different modes:
     22 //
     23 // * Bailouts: all registers are pushed on the stack as part of the bailout
     24 //   process, so MachineState simply points to these FPU/GPR arrays.
     25 //   See RegisterDump and BailoutStack.
     26 //
     27 // * Safepoints: live registers are pushed on the stack before a VM call, so
     28 //   MachineState stores the register sets and a pointer to the stack memory
     29 //   where these registers were pushed. This is also used by exception bailouts.
     30 class MOZ_STACK_CLASS MachineState {
     31  struct NullState {};
     32 
     33  struct BailoutState {
     34    RegisterDump::FPUArray& floatRegs;
     35    RegisterDump::GPRArray& regs;
     36 
     37    BailoutState(RegisterDump::FPUArray& floatRegs,
     38                 RegisterDump::GPRArray& regs)
     39        : floatRegs(floatRegs), regs(regs) {}
     40  };
     41 
     42  struct SafepointState {
     43    FloatRegisterSet floatRegs;
     44    GeneralRegisterSet regs;
     45    // Pointers to the start of the pushed |floatRegs| and |regs| on the stack.
     46    // This is the value of the stack pointer right before the first register
     47    // was pushed.
     48    char* floatSpillBase;
     49    uintptr_t* spillBase;
     50 
     51    SafepointState(const FloatRegisterSet& floatRegs,
     52                   const GeneralRegisterSet& regs, char* floatSpillBase,
     53                   uintptr_t* spillBase)
     54        : floatRegs(floatRegs),
     55          regs(regs),
     56          floatSpillBase(floatSpillBase),
     57          spillBase(spillBase) {}
     58    uintptr_t* addressOfRegister(Register reg) const;
     59    char* addressOfRegister(FloatRegister reg) const;
     60  };
     61  using State = mozilla::Variant<NullState, BailoutState, SafepointState>;
     62  State state_{NullState()};
     63 
     64 public:
     65  MachineState() = default;
     66  MachineState(const MachineState& other) = default;
     67  MachineState& operator=(const MachineState& other) = default;
     68 
     69  static MachineState FromBailout(RegisterDump::GPRArray& regs,
     70                                  RegisterDump::FPUArray& fpregs) {
     71    MachineState res;
     72    res.state_.emplace<BailoutState>(fpregs, regs);
     73    return res;
     74  }
     75 
     76  static MachineState FromSafepoint(const FloatRegisterSet& floatRegs,
     77                                    const GeneralRegisterSet& regs,
     78                                    char* floatSpillBase,
     79                                    uintptr_t* spillBase) {
     80    MachineState res;
     81    res.state_.emplace<SafepointState>(floatRegs, regs, floatSpillBase,
     82                                       spillBase);
     83    return res;
     84  }
     85 
     86  bool has(Register reg) const {
     87    if (state_.is<BailoutState>()) {
     88      return true;
     89    }
     90    return state_.as<SafepointState>().regs.hasRegisterIndex(reg);
     91  }
     92  bool has(FloatRegister reg) const {
     93    if (state_.is<BailoutState>()) {
     94      return true;
     95    }
     96    return state_.as<SafepointState>().floatRegs.hasRegisterIndex(reg);
     97  }
     98 
     99  uintptr_t read(Register reg) const;
    100  template <typename T>
    101  T read(FloatRegister reg) const;
    102 
    103  // Used by moving GCs to update pointers.
    104  void write(Register reg, uintptr_t value) const;
    105 };
    106 
    107 }  // namespace js::jit
    108 
    109 #endif /* jit_MachineState_h */