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_MachineState_h
8 #define jit_MachineState_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Attributes.h"
12 #include "mozilla/Variant.h"
16 #include "jit/Registers.h"
17 #include "jit/RegisterSets.h"
21 // Information needed to recover machine register state. This supports two
24 // * Bailouts: all registers are pushed on the stack as part of the bailout
25 // process, so MachineState simply points to these FPU/GPR arrays.
26 // See RegisterDump and BailoutStack.
28 // * Safepoints: live registers are pushed on the stack before a VM call, so
29 // MachineState stores the register sets and a pointer to the stack memory
30 // where these registers were pushed. This is also used by exception bailouts.
31 class MOZ_STACK_CLASS MachineState
{
35 RegisterDump::FPUArray
& floatRegs
;
36 RegisterDump::GPRArray
& regs
;
38 BailoutState(RegisterDump::FPUArray
& floatRegs
,
39 RegisterDump::GPRArray
& regs
)
40 : floatRegs(floatRegs
), regs(regs
) {}
43 struct SafepointState
{
44 FloatRegisterSet floatRegs
;
45 GeneralRegisterSet regs
;
46 // Pointers to the start of the pushed |floatRegs| and |regs| on the stack.
47 // This is the value of the stack pointer right before the first register
52 SafepointState(const FloatRegisterSet
& floatRegs
,
53 const GeneralRegisterSet
& regs
, char* floatSpillBase
,
55 : floatRegs(floatRegs
),
57 floatSpillBase(floatSpillBase
),
58 spillBase(spillBase
) {}
59 uintptr_t* addressOfRegister(Register reg
) const;
60 char* addressOfRegister(FloatRegister reg
) const;
62 using State
= mozilla::Variant
<NullState
, BailoutState
, SafepointState
>;
63 State state_
{NullState()};
66 MachineState() = default;
67 MachineState(const MachineState
& other
) = default;
68 MachineState
& operator=(const MachineState
& other
) = default;
70 static MachineState
FromBailout(RegisterDump::GPRArray
& regs
,
71 RegisterDump::FPUArray
& fpregs
) {
73 res
.state_
.emplace
<BailoutState
>(fpregs
, regs
);
77 static MachineState
FromSafepoint(const FloatRegisterSet
& floatRegs
,
78 const GeneralRegisterSet
& regs
,
80 uintptr_t* spillBase
) {
82 res
.state_
.emplace
<SafepointState
>(floatRegs
, regs
, floatSpillBase
,
87 bool has(Register reg
) const {
88 if (state_
.is
<BailoutState
>()) {
91 return state_
.as
<SafepointState
>().regs
.hasRegisterIndex(reg
);
93 bool has(FloatRegister reg
) const {
94 if (state_
.is
<BailoutState
>()) {
97 return state_
.as
<SafepointState
>().floatRegs
.hasRegisterIndex(reg
);
100 uintptr_t read(Register reg
) const;
101 template <typename T
>
102 T
read(FloatRegister reg
) const;
104 // Used by moving GCs to update pointers.
105 void write(Register reg
, uintptr_t value
) const;
108 } // namespace js::jit
110 #endif /* jit_MachineState_h */