1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
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 #include "jscntxt.h"
8 #include "jscompartment.h"
9 
10 #include "jit/Bailouts.h"
11 #include "jit/JitCompartment.h"
12 
13 using namespace js;
14 using namespace js::jit;
15 
16 #if defined(_WIN32)
17 # pragma pack(push, 1)
18 #endif
19 
20 namespace js {
21 namespace jit {
22 
23 class BailoutStack
24 {
25     uintptr_t frameClassId_;
26     RegisterDump::FPUArray fpregs_;
27     RegisterDump::GPRArray regs_;
28     union {
29         uintptr_t frameSize_;
30         uintptr_t tableOffset_;
31     };
32     uintptr_t snapshotOffset_;
33 
34   public:
frameClass() const35     FrameSizeClass frameClass() const {
36         return FrameSizeClass::FromClass(frameClassId_);
37     }
tableOffset() const38     uintptr_t tableOffset() const {
39         MOZ_ASSERT(frameClass() != FrameSizeClass::None());
40         return tableOffset_;
41     }
frameSize() const42     uint32_t frameSize() const {
43         if (frameClass() == FrameSizeClass::None())
44             return frameSize_;
45         return frameClass().frameSize();
46     }
machine()47     MachineState machine() {
48         return MachineState::FromBailout(regs_, fpregs_);
49     }
snapshotOffset() const50     SnapshotOffset snapshotOffset() const {
51         MOZ_ASSERT(frameClass() == FrameSizeClass::None());
52         return snapshotOffset_;
53     }
parentStackPointer() const54     uint8_t* parentStackPointer() const {
55         if (frameClass() == FrameSizeClass::None())
56             return (uint8_t*)this + sizeof(BailoutStack);
57         return (uint8_t*)this + offsetof(BailoutStack, snapshotOffset_);
58     }
59 };
60 
61 } // namespace jit
62 } // namespace js
63 
64 #if defined(_WIN32)
65 # pragma pack(pop)
66 #endif
67 
BailoutFrameInfo(const JitActivationIterator & activations,BailoutStack * bailout)68 BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations,
69                                    BailoutStack* bailout)
70   : machine_(bailout->machine())
71 {
72     uint8_t* sp = bailout->parentStackPointer();
73     framePointer_ = sp + bailout->frameSize();
74     topFrameSize_ = framePointer_ - sp;
75 
76     JSScript* script = ScriptFromCalleeToken(((JitFrameLayout*) framePointer_)->calleeToken());
77     JitActivation* activation = activations.activation()->asJit();
78     topIonScript_ = script->ionScript();
79 
80     attachOnJitActivation(activations);
81 
82     if (bailout->frameClass() == FrameSizeClass::None()) {
83         snapshotOffset_ = bailout->snapshotOffset();
84         return;
85     }
86 
87     // Compute the snapshot offset from the bailout ID.
88     JSRuntime* rt = activation->compartment()->runtimeFromMainThread();
89     JitCode* code = rt->jitRuntime()->getBailoutTable(bailout->frameClass());
90     uintptr_t tableOffset = bailout->tableOffset();
91     uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw());
92 
93     MOZ_ASSERT(tableOffset >= tableStart &&
94                tableOffset < tableStart + code->instructionsSize());
95     MOZ_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0);
96 
97     uint32_t bailoutId = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1;
98     MOZ_ASSERT(bailoutId < BAILOUT_TABLE_SIZE);
99 
100     snapshotOffset_ = topIonScript_->bailoutToSnapshot(bailoutId);
101 }
102 
BailoutFrameInfo(const JitActivationIterator & activations,InvalidationBailoutStack * bailout)103 BailoutFrameInfo::BailoutFrameInfo(const JitActivationIterator& activations,
104                                    InvalidationBailoutStack* bailout)
105   : machine_(bailout->machine())
106 {
107     framePointer_ = (uint8_t*) bailout->fp();
108     topFrameSize_ = framePointer_ - bailout->sp();
109     topIonScript_ = bailout->ionScript();
110     attachOnJitActivation(activations);
111 
112     uint8_t* returnAddressToFp_ = bailout->osiPointReturnAddress();
113     const OsiIndex* osiIndex = topIonScript_->getOsiIndex(returnAddressToFp_);
114     snapshotOffset_ = osiIndex->snapshotOffset();
115 }
116