mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-11-04 05:27:35 +09:00
275 lines
7.5 KiB
C++
275 lines
7.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 <algorithm>
|
|
|
|
#include "jsfun.h"
|
|
|
|
#include "jit/JitFrameIterator.h"
|
|
#include "jit/JitFrames.h"
|
|
|
|
#include "vm/EnvironmentObject.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 an initial environment has been pushed on the environment chain for
|
|
// function frames that need a CallObject or eval frames that need a
|
|
// VarEnvironmentObject?
|
|
bool hasInitialEnv_;
|
|
|
|
// 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* envChain_;
|
|
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 MOZ_MUST_USE bool RematerializeInlineFrames(JSContext* cx, uint8_t* top,
|
|
InlineFrameIterator& iter,
|
|
MaybeReadFallback& fallback,
|
|
GCVector<RematerializedFrame*>& frames);
|
|
|
|
// Free a vector of RematerializedFrames; takes care to call the
|
|
// destructor. Also clears the vector.
|
|
static void FreeInVector(GCVector<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* environmentChain() const {
|
|
return envChain_;
|
|
}
|
|
|
|
template <typename SpecificEnvironment>
|
|
void pushOnEnvironmentChain(SpecificEnvironment& env) {
|
|
MOZ_ASSERT(*environmentChain() == env.enclosingEnvironment());
|
|
envChain_ = &env;
|
|
if (IsFrameInitialEnvironment(this, env))
|
|
hasInitialEnv_ = true;
|
|
}
|
|
|
|
template <typename SpecificEnvironment>
|
|
void popOffEnvironmentChain() {
|
|
MOZ_ASSERT(envChain_->is<SpecificEnvironment>());
|
|
envChain_ = &envChain_->as<SpecificEnvironment>().enclosingEnvironment();
|
|
}
|
|
|
|
MOZ_MUST_USE bool initFunctionEnvironmentObjects(JSContext* cx);
|
|
MOZ_MUST_USE bool pushVarEnvironment(JSContext* cx, HandleScope scope);
|
|
|
|
bool hasInitialEnvironment() const {
|
|
return hasInitialEnv_;
|
|
}
|
|
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 isGlobalFrame() const {
|
|
return script_->isGlobalCode();
|
|
}
|
|
bool isModuleFrame() const {
|
|
return script_->module();
|
|
}
|
|
|
|
JSScript* script() const {
|
|
return script_;
|
|
}
|
|
JSFunction* callee() const {
|
|
MOZ_ASSERT(isFunctionFrame());
|
|
MOZ_ASSERT(callee_);
|
|
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 isFunctionFrame() ? callee()->nargs() : 0;
|
|
}
|
|
unsigned numActualArgs() const {
|
|
return numActualArgs_;
|
|
}
|
|
unsigned numArgSlots() const {
|
|
return (std::max)(numFormalArgs(), numActualArgs());
|
|
}
|
|
|
|
Value* argv() {
|
|
return slots_;
|
|
}
|
|
Value* locals() {
|
|
return slots_ + numArgSlots();
|
|
}
|
|
|
|
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_;
|
|
}
|
|
|
|
void setReturnValue(const Value& value) {
|
|
returnValue_ = value;
|
|
}
|
|
|
|
Value& returnValue() {
|
|
return returnValue_;
|
|
}
|
|
|
|
void trace(JSTracer* trc);
|
|
void dump();
|
|
};
|
|
|
|
} // namespace jit
|
|
} // namespace js
|
|
|
|
namespace JS {
|
|
|
|
template <>
|
|
struct MapTypeToRootKind<js::jit::RematerializedFrame*>
|
|
{
|
|
static const RootKind kind = RootKind::Traceable;
|
|
};
|
|
|
|
template <>
|
|
struct GCPolicy<js::jit::RematerializedFrame*>
|
|
{
|
|
static js::jit::RematerializedFrame* initial() {
|
|
return nullptr;
|
|
}
|
|
|
|
static void trace(JSTracer* trc, js::jit::RematerializedFrame** frame, const char* name) {
|
|
if (*frame)
|
|
(*frame)->trace(trc);
|
|
}
|
|
};
|
|
|
|
} // namespace JS
|
|
|
|
#endif // jit_RematerializedFrame_h
|