Line data Source code
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 : #ifndef jit_BaselineDebugModeOSR_h
8 : #define jit_BaselineDebugModeOSR_h
9 :
10 : #include "jit/BaselineFrame.h"
11 : #include "jit/BaselineIC.h"
12 : #include "jit/BaselineJIT.h"
13 : #include "jit/JitFrameIterator.h"
14 :
15 : #include "vm/Debugger.h"
16 :
17 : namespace js {
18 : namespace jit {
19 :
20 : // Note that this file and the corresponding .cpp implement debug mode
21 : // on-stack recompilation. This is to be distinguished from ordinary
22 : // Baseline->Ion OSR, which is used to jump into compiled loops.
23 :
24 : //
25 : // A volatile location due to recompilation of an on-stack baseline script
26 : // (e.g., for debug mode toggling).
27 : //
28 : // It is usually used in fallback stubs which may trigger on-stack
29 : // recompilation by calling out into the VM. Example use:
30 : //
31 : // DebugModeOSRVolatileStub<FallbackStubT*> stub(frame, stub_)
32 : //
33 : // // Call out to the VM
34 : // // Other effectful operations like TypeScript::Monitor
35 : //
36 : // if (stub.invalid())
37 : // return true;
38 : //
39 : // // First use of stub after VM call.
40 : //
41 : template <typename T>
42 : class DebugModeOSRVolatileStub
43 : {
44 : ICStubCompiler::Engine engine_;
45 : T stub_;
46 : BaselineFrame* frame_;
47 : uint32_t pcOffset_;
48 :
49 : public:
50 1273 : DebugModeOSRVolatileStub(ICStubCompiler::Engine engine, BaselineFrame* frame,
51 : ICFallbackStub* stub)
52 : : engine_(engine),
53 : stub_(static_cast<T>(stub)),
54 : frame_(frame),
55 1273 : pcOffset_(stub->icEntry()->pcOffset())
56 1273 : { }
57 :
58 16246 : DebugModeOSRVolatileStub(BaselineFrame* frame, ICFallbackStub* stub)
59 : : engine_(ICStubCompiler::Engine::Baseline),
60 : stub_(static_cast<T>(stub)),
61 : frame_(frame),
62 16246 : pcOffset_(stub->icEntry()->pcOffset())
63 16246 : { }
64 :
65 117390 : bool invalid() const {
66 117390 : if (engine_ == ICStubCompiler::Engine::IonSharedIC)
67 0 : return stub_->invalid();
68 117390 : MOZ_ASSERT(!frame_->isHandlingException());
69 117390 : ICEntry& entry = frame_->script()->baselineScript()->icEntryFromPCOffset(pcOffset_);
70 117390 : return stub_ != entry.fallbackStub();
71 : }
72 :
73 31074 : operator const T&() const { MOZ_ASSERT(!invalid()); return stub_; }
74 69417 : T operator->() const { MOZ_ASSERT(!invalid()); return stub_; }
75 : T* address() { MOZ_ASSERT(!invalid()); return &stub_; }
76 : const T* address() const { MOZ_ASSERT(!invalid()); return &stub_; }
77 : T& get() { MOZ_ASSERT(!invalid()); return stub_; }
78 : const T& get() const { MOZ_ASSERT(!invalid()); return stub_; }
79 :
80 : bool operator!=(const T& other) const { MOZ_ASSERT(!invalid()); return stub_ != other; }
81 : bool operator==(const T& other) const { MOZ_ASSERT(!invalid()); return stub_ == other; }
82 : };
83 :
84 : //
85 : // A JitFrameIterator that updates itself in case of recompilation of an
86 : // on-stack baseline script.
87 : //
88 : class DebugModeOSRVolatileJitFrameIterator : public JitFrameIterator
89 : {
90 : DebugModeOSRVolatileJitFrameIterator** stack;
91 : DebugModeOSRVolatileJitFrameIterator* prev;
92 :
93 : public:
94 1993 : explicit DebugModeOSRVolatileJitFrameIterator(JSContext* cx)
95 1993 : : JitFrameIterator(cx)
96 : {
97 1993 : stack = &cx->liveVolatileJitFrameIterators_.ref();
98 1993 : prev = *stack;
99 1993 : *stack = this;
100 1993 : }
101 :
102 3986 : ~DebugModeOSRVolatileJitFrameIterator() {
103 1993 : MOZ_ASSERT(*stack == this);
104 1993 : *stack = prev;
105 1993 : }
106 :
107 : static void forwardLiveIterators(const CooperatingContext& target,
108 : uint8_t* oldAddr, uint8_t* newAddr);
109 : };
110 :
111 : //
112 : // Auxiliary info to help the DebugModeOSRHandler fix up state.
113 : //
114 : struct BaselineDebugModeOSRInfo
115 : {
116 : uint8_t* resumeAddr;
117 : jsbytecode* pc;
118 : PCMappingSlotInfo slotInfo;
119 : ICEntry::Kind frameKind;
120 :
121 : // Filled in by SyncBaselineDebugModeOSRInfo.
122 : uintptr_t stackAdjust;
123 : Value valueR0;
124 : Value valueR1;
125 :
126 0 : BaselineDebugModeOSRInfo(jsbytecode* pc, ICEntry::Kind kind)
127 0 : : resumeAddr(nullptr),
128 : pc(pc),
129 : slotInfo(0),
130 : frameKind(kind),
131 : stackAdjust(0),
132 : valueR0(UndefinedValue()),
133 0 : valueR1(UndefinedValue())
134 0 : { }
135 :
136 : void popValueInto(PCMappingSlotInfo::SlotLocation loc, Value* vp);
137 : };
138 :
139 : MOZ_MUST_USE bool
140 : RecompileOnStackBaselineScriptsForDebugMode(JSContext* cx,
141 : const Debugger::ExecutionObservableSet& obs,
142 : Debugger::IsObserving observing);
143 :
144 : } // namespace jit
145 : } // namespace js
146 :
147 : #endif // jit_BaselineDebugModeOSR_h
|