michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef jit_RematerializedFrame_h michael@0: #define jit_RematerializedFrame_h michael@0: michael@0: #ifdef JS_ION michael@0: michael@0: #include "jsfun.h" michael@0: michael@0: #include "jit/JitFrameIterator.h" michael@0: michael@0: #include "vm/Stack.h" michael@0: michael@0: namespace js { michael@0: namespace jit { michael@0: michael@0: // michael@0: // An optimized frame that has been rematerialized with values read out of michael@0: // Snapshots. michael@0: // michael@0: class RematerializedFrame michael@0: { michael@0: // See DebugScopes::updateLiveScopes. michael@0: bool prevUpToDate_; michael@0: michael@0: // The fp of the top frame associated with this possibly inlined frame. michael@0: uint8_t *top_; michael@0: michael@0: size_t frameNo_; michael@0: unsigned numActualArgs_; michael@0: michael@0: JSScript *script_; michael@0: JSObject *scopeChain_; michael@0: ArgumentsObject *argsObj_; michael@0: michael@0: Value returnValue_; michael@0: Value thisValue_; michael@0: Value slots_[1]; michael@0: michael@0: RematerializedFrame(JSContext *cx, uint8_t *top, InlineFrameIterator &iter); michael@0: michael@0: public: michael@0: static RematerializedFrame *New(JSContext *cx, uint8_t *top, InlineFrameIterator &iter); michael@0: michael@0: bool prevUpToDate() const { michael@0: return prevUpToDate_; michael@0: } michael@0: void setPrevUpToDate() { michael@0: prevUpToDate_ = true; michael@0: } michael@0: michael@0: uint8_t *top() const { michael@0: return top_; michael@0: } michael@0: size_t frameNo() const { michael@0: return frameNo_; michael@0: } michael@0: bool inlined() const { michael@0: return frameNo_ > 0; michael@0: } michael@0: michael@0: JSObject *scopeChain() const { michael@0: return scopeChain_; michael@0: } michael@0: bool hasCallObj() const { michael@0: return maybeFun() && fun()->isHeavyweight(); michael@0: } michael@0: CallObject &callObj() const; michael@0: michael@0: bool hasArgsObj() const { michael@0: return !!argsObj_; michael@0: } michael@0: ArgumentsObject &argsObj() const { michael@0: MOZ_ASSERT(hasArgsObj()); michael@0: MOZ_ASSERT(script()->needsArgsObj()); michael@0: return *argsObj_; michael@0: } michael@0: michael@0: bool isFunctionFrame() const { michael@0: return !!script_->functionNonDelazifying(); michael@0: } michael@0: bool isGlobalFrame() const { michael@0: return !isFunctionFrame(); michael@0: } michael@0: bool isNonEvalFunctionFrame() const { michael@0: // Ion doesn't support eval frames. michael@0: return isFunctionFrame(); michael@0: } michael@0: michael@0: JSScript *script() const { michael@0: return script_; michael@0: } michael@0: JSFunction *fun() const { michael@0: MOZ_ASSERT(isFunctionFrame()); michael@0: return script_->functionNonDelazifying(); michael@0: } michael@0: JSFunction *maybeFun() const { michael@0: return isFunctionFrame() ? fun() : nullptr; michael@0: } michael@0: JSFunction *callee() const { michael@0: return fun(); michael@0: } michael@0: Value calleev() const { michael@0: return ObjectValue(*fun()); michael@0: } michael@0: Value &thisValue() { michael@0: return thisValue_; michael@0: } michael@0: michael@0: unsigned numFormalArgs() const { michael@0: return maybeFun() ? fun()->nargs() : 0; michael@0: } michael@0: unsigned numActualArgs() const { michael@0: return numActualArgs_; michael@0: } michael@0: michael@0: Value *argv() { michael@0: return slots_; michael@0: } michael@0: Value *locals() { michael@0: return slots_ + numActualArgs_; michael@0: } michael@0: michael@0: Value &unaliasedVar(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) { michael@0: JS_ASSERT_IF(checkAliasing, !script()->varIsAliased(i)); michael@0: JS_ASSERT(i < script()->nfixed()); michael@0: return locals()[i]; michael@0: } michael@0: Value &unaliasedLocal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) { michael@0: JS_ASSERT(i < script()->nfixed()); michael@0: #ifdef DEBUG michael@0: CheckLocalUnaliased(checkAliasing, script(), i); michael@0: #endif michael@0: return locals()[i]; michael@0: } michael@0: Value &unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) { michael@0: JS_ASSERT(i < numFormalArgs()); michael@0: JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals() && michael@0: !script()->formalIsAliased(i)); michael@0: return argv()[i]; michael@0: } michael@0: Value &unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) { michael@0: JS_ASSERT(i < numActualArgs()); michael@0: JS_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals()); michael@0: JS_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i)); michael@0: return argv()[i]; michael@0: } michael@0: michael@0: Value returnValue() const { michael@0: return returnValue_; michael@0: } michael@0: michael@0: void mark(JSTracer *trc); michael@0: void dump(); michael@0: }; michael@0: michael@0: } // namespace jit michael@0: } // namespace js michael@0: michael@0: #endif // JS_ION michael@0: #endif // jit_RematerializedFrame_h