mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-25 17:55:23 +00:00
240 lines
6.5 KiB
C++
240 lines
6.5 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef jit_RematerializedFrame_h
|
|
#define jit_RematerializedFrame_h
|
|
|
|
#include "jsfun.h"
|
|
|
|
#include "jit/JitFrameIterator.h"
|
|
#include "jit/JitFrames.h"
|
|
|
|
#include "vm/Stack.h"
|
|
|
|
namespace js {
|
|
namespace jit {
|
|
|
|
//
|
|
// An optimized frame that has been rematerialized with values read out of
|
|
// Snapshots.
|
|
//
|
|
class RematerializedFrame
|
|
{
|
|
// See DebugScopes::updateLiveScopes.
|
|
bool prevUpToDate_;
|
|
|
|
// Propagated to the Baseline frame once this is popped.
|
|
bool isDebuggee_;
|
|
|
|
// Has a call object been pushed?
|
|
bool hasCallObj_;
|
|
|
|
// Is this frame constructing?
|
|
bool isConstructing_;
|
|
|
|
// If true, this frame has been on the stack when
|
|
// |js::SavedStacks::saveCurrentStack| was called, and so there is a
|
|
// |js::SavedFrame| object cached for this frame.
|
|
bool hasCachedSavedFrame_;
|
|
|
|
// The fp of the top frame associated with this possibly inlined frame.
|
|
uint8_t* top_;
|
|
|
|
// The bytecode at the time of rematerialization.
|
|
jsbytecode* pc_;
|
|
|
|
size_t frameNo_;
|
|
unsigned numActualArgs_;
|
|
|
|
JSScript* script_;
|
|
JSObject* scopeChain_;
|
|
JSFunction* callee_;
|
|
ArgumentsObject* argsObj_;
|
|
|
|
Value returnValue_;
|
|
Value thisArgument_;
|
|
Value newTarget_;
|
|
Value slots_[1];
|
|
|
|
RematerializedFrame(JSContext* cx, uint8_t* top, unsigned numActualArgs,
|
|
InlineFrameIterator& iter, MaybeReadFallback& fallback);
|
|
|
|
public:
|
|
static RematerializedFrame* New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
|
|
MaybeReadFallback& fallback);
|
|
|
|
// Rematerialize all remaining frames pointed to by |iter| into |frames|
|
|
// in older-to-younger order, e.g., frames[0] is the oldest frame.
|
|
static bool RematerializeInlineFrames(JSContext* cx, uint8_t* top,
|
|
InlineFrameIterator& iter,
|
|
MaybeReadFallback& fallback,
|
|
Vector<RematerializedFrame*>& frames);
|
|
|
|
// Free a vector of RematerializedFrames; takes care to call the
|
|
// destructor. Also clears the vector.
|
|
static void FreeInVector(Vector<RematerializedFrame*>& frames);
|
|
|
|
// Mark a vector of RematerializedFrames.
|
|
static void MarkInVector(JSTracer* trc, Vector<RematerializedFrame*>& frames);
|
|
|
|
bool prevUpToDate() const {
|
|
return prevUpToDate_;
|
|
}
|
|
void setPrevUpToDate() {
|
|
prevUpToDate_ = true;
|
|
}
|
|
void unsetPrevUpToDate() {
|
|
prevUpToDate_ = false;
|
|
}
|
|
|
|
bool isDebuggee() const {
|
|
return isDebuggee_;
|
|
}
|
|
void setIsDebuggee() {
|
|
isDebuggee_ = true;
|
|
}
|
|
void unsetIsDebuggee() {
|
|
MOZ_ASSERT(!script()->isDebuggee());
|
|
isDebuggee_ = false;
|
|
}
|
|
|
|
uint8_t* top() const {
|
|
return top_;
|
|
}
|
|
JSScript* outerScript() const {
|
|
JitFrameLayout* jsFrame = (JitFrameLayout*)top_;
|
|
return ScriptFromCalleeToken(jsFrame->calleeToken());
|
|
}
|
|
jsbytecode* pc() const {
|
|
return pc_;
|
|
}
|
|
size_t frameNo() const {
|
|
return frameNo_;
|
|
}
|
|
bool inlined() const {
|
|
return frameNo_ > 0;
|
|
}
|
|
|
|
JSObject* scopeChain() const {
|
|
return scopeChain_;
|
|
}
|
|
void pushOnScopeChain(ScopeObject& scope);
|
|
bool initFunctionScopeObjects(JSContext* cx);
|
|
|
|
bool hasCallObj() const {
|
|
MOZ_ASSERT(fun()->needsCallObject());
|
|
return hasCallObj_;
|
|
}
|
|
CallObject& callObj() const;
|
|
|
|
bool hasArgsObj() const {
|
|
return !!argsObj_;
|
|
}
|
|
ArgumentsObject& argsObj() const {
|
|
MOZ_ASSERT(hasArgsObj());
|
|
MOZ_ASSERT(script()->needsArgsObj());
|
|
return *argsObj_;
|
|
}
|
|
|
|
bool isFunctionFrame() const {
|
|
return !!script_->functionNonDelazifying();
|
|
}
|
|
bool isModuleFrame() const {
|
|
return !!script_->module();
|
|
}
|
|
bool isGlobalFrame() const {
|
|
return !isFunctionFrame() && !isModuleFrame();
|
|
}
|
|
bool isNonEvalFunctionFrame() const {
|
|
// Ion doesn't support eval frames.
|
|
return isFunctionFrame();
|
|
}
|
|
|
|
JSScript* script() const {
|
|
return script_;
|
|
}
|
|
JSFunction* fun() const {
|
|
MOZ_ASSERT(isFunctionFrame());
|
|
return script_->functionNonDelazifying();
|
|
}
|
|
JSFunction* maybeFun() const {
|
|
return isFunctionFrame() ? fun() : nullptr;
|
|
}
|
|
JSFunction* callee() const {
|
|
MOZ_ASSERT(isFunctionFrame());
|
|
return callee_;
|
|
}
|
|
Value calleev() const {
|
|
return ObjectValue(*callee());
|
|
}
|
|
Value& thisArgument() {
|
|
return thisArgument_;
|
|
}
|
|
|
|
bool isConstructing() const {
|
|
return isConstructing_;
|
|
}
|
|
|
|
bool hasCachedSavedFrame() const {
|
|
return hasCachedSavedFrame_;
|
|
}
|
|
|
|
void setHasCachedSavedFrame() {
|
|
hasCachedSavedFrame_ = true;
|
|
}
|
|
|
|
unsigned numFormalArgs() const {
|
|
return maybeFun() ? fun()->nargs() : 0;
|
|
}
|
|
unsigned numActualArgs() const {
|
|
return numActualArgs_;
|
|
}
|
|
|
|
Value* argv() {
|
|
return slots_;
|
|
}
|
|
Value* locals() {
|
|
return slots_ + numActualArgs_;
|
|
}
|
|
|
|
Value& unaliasedLocal(unsigned i) {
|
|
MOZ_ASSERT(i < script()->nfixed());
|
|
return locals()[i];
|
|
}
|
|
Value& unaliasedFormal(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
|
|
MOZ_ASSERT(i < numFormalArgs());
|
|
MOZ_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals() &&
|
|
!script()->formalIsAliased(i));
|
|
return argv()[i];
|
|
}
|
|
Value& unaliasedActual(unsigned i, MaybeCheckAliasing checkAliasing = CHECK_ALIASING) {
|
|
MOZ_ASSERT(i < numActualArgs());
|
|
MOZ_ASSERT_IF(checkAliasing, !script()->argsObjAliasesFormals());
|
|
MOZ_ASSERT_IF(checkAliasing && i < numFormalArgs(), !script()->formalIsAliased(i));
|
|
return argv()[i];
|
|
}
|
|
|
|
Value newTarget() {
|
|
MOZ_ASSERT(isFunctionFrame());
|
|
if (callee()->isArrow())
|
|
return callee()->getExtendedSlot(FunctionExtended::ARROW_NEWTARGET_SLOT);
|
|
MOZ_ASSERT_IF(!isConstructing(), newTarget_.isUndefined());
|
|
return newTarget_;
|
|
}
|
|
|
|
Value returnValue() const {
|
|
return returnValue_;
|
|
}
|
|
|
|
void mark(JSTracer* trc);
|
|
void dump();
|
|
};
|
|
|
|
} // namespace jit
|
|
} // namespace js
|
|
|
|
#endif // jit_RematerializedFrame_h
|