Activation-inl.h (4065B)
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 vm_Activation_inl_h 8 #define vm_Activation_inl_h 9 10 #include "vm/Activation.h" 11 12 #include "mozilla/Assertions.h" // MOZ_ASSERT{,_IF}, MOZ_CRASH 13 #include "mozilla/Likely.h" // MOZ_UNLIKELY 14 #include "mozilla/Maybe.h" // mozilla::Maybe 15 16 #include "jit/CalleeToken.h" // js::jit::CalleeToken 17 #include "vm/FrameIter.h" // js::FrameIter 18 #include "vm/JitActivation.h" // js::jit::JitActivation 19 #include "vm/JSContext.h" // JSContext 20 #include "vm/Stack.h" // js::AbstractFramePtr 21 22 namespace js { 23 24 inline Activation::Activation(JSContext* cx, Kind kind) 25 : cx_(cx), 26 compartment_(cx->compartment()), 27 prev_(cx->activation_), 28 prevProfiling_(prev_ ? prev_->mostRecentProfiling() : nullptr), 29 hideScriptedCallerCount_(0), 30 frameCache_(cx), 31 asyncStack_(cx, cx->asyncStackForNewActivations()), 32 asyncCause_(cx->asyncCauseForNewActivations), 33 asyncCallIsExplicit_(cx->asyncCallIsExplicit), 34 kind_(kind) { 35 cx->asyncStackForNewActivations() = nullptr; 36 cx->asyncCauseForNewActivations = nullptr; 37 cx->asyncCallIsExplicit = false; 38 cx->activation_ = this; 39 } 40 41 inline Activation::~Activation() { 42 MOZ_ASSERT_IF(isProfiling(), this != cx_->profilingActivation_); 43 MOZ_ASSERT(cx_->activation_ == this); 44 MOZ_ASSERT(hideScriptedCallerCount_ == 0); 45 cx_->activation_ = prev_; 46 cx_->asyncCauseForNewActivations = asyncCause_; 47 cx_->asyncStackForNewActivations() = asyncStack_; 48 cx_->asyncCallIsExplicit = asyncCallIsExplicit_; 49 } 50 51 inline bool Activation::isProfiling() const { 52 if (isInterpreter()) { 53 return asInterpreter()->isProfiling(); 54 } 55 56 MOZ_ASSERT(isJit()); 57 return asJit()->isProfiling(); 58 } 59 60 inline Activation* Activation::mostRecentProfiling() { 61 if (isProfiling()) { 62 return this; 63 } 64 return prevProfiling_; 65 } 66 67 inline LiveSavedFrameCache* Activation::getLiveSavedFrameCache(JSContext* cx) { 68 if (!frameCache_.get().initialized() && !frameCache_.get().init(cx)) { 69 return nullptr; 70 } 71 return frameCache_.address(); 72 } 73 74 /* static */ inline mozilla::Maybe<LiveSavedFrameCache::FramePtr> 75 LiveSavedFrameCache::FramePtr::create(const FrameIter& iter) { 76 if (iter.done()) { 77 return mozilla::Nothing(); 78 } 79 80 if (iter.isPhysicalJitFrame()) { 81 return mozilla::Some(FramePtr(iter.physicalJitFrame())); 82 } 83 84 if (!iter.hasUsableAbstractFramePtr()) { 85 return mozilla::Nothing(); 86 } 87 88 auto afp = iter.abstractFramePtr(); 89 90 if (afp.isInterpreterFrame()) { 91 return mozilla::Some(FramePtr(afp.asInterpreterFrame())); 92 } 93 if (afp.isWasmDebugFrame()) { 94 return mozilla::Some(FramePtr(afp.asWasmDebugFrame())); 95 } 96 if (afp.isRematerializedFrame()) { 97 return mozilla::Some(FramePtr(afp.asRematerializedFrame())); 98 } 99 100 MOZ_CRASH("unexpected frame type"); 101 } 102 103 struct LiveSavedFrameCache::FramePtr::HasCachedMatcher { 104 template <typename Frame> 105 bool operator()(Frame* f) const { 106 return f->hasCachedSavedFrame(); 107 } 108 }; 109 110 inline bool LiveSavedFrameCache::FramePtr::hasCachedSavedFrame() const { 111 return ptr.match(HasCachedMatcher()); 112 } 113 114 struct LiveSavedFrameCache::FramePtr::SetHasCachedMatcher { 115 template <typename Frame> 116 void operator()(Frame* f) { 117 f->setHasCachedSavedFrame(); 118 } 119 }; 120 121 inline void LiveSavedFrameCache::FramePtr::setHasCachedSavedFrame() { 122 ptr.match(SetHasCachedMatcher()); 123 } 124 125 struct LiveSavedFrameCache::FramePtr::ClearHasCachedMatcher { 126 template <typename Frame> 127 void operator()(Frame* f) { 128 f->clearHasCachedSavedFrame(); 129 } 130 }; 131 132 inline void LiveSavedFrameCache::FramePtr::clearHasCachedSavedFrame() { 133 ptr.match(ClearHasCachedMatcher()); 134 } 135 136 inline bool Activation::hasWasmExitFP() const { 137 return isJit() && asJit()->hasWasmExitFP(); 138 } 139 140 } // namespace js 141 142 #endif // vm_Activation_inl_h