Bug 1600439 - Replace LazyScriptData with PrivateScriptData. r=jandem

It it straight-foward for users of LazyScriptData to support a single array
for closedOverBindings and innerFunctions. As a result, we can use
PrivateScriptData as the implementation and eliminate the LazyScriptData type
altogether.

Depends on D55035

Differential Revision: https://phabricator.services.mozilla.com/D55360

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ted Campbell 2019-12-02 14:31:42 +00:00
Родитель 6ea700f0c1
Коммит 8ec1a14c33
6 изменённых файлов: 205 добавлений и 310 удалений

Просмотреть файл

@ -532,6 +532,28 @@ static bool PushFunctionScript(JSContext* cx, Debugger* dbg, HandleFunction fun,
return wrapped && NewbornArrayPush(cx, array, ObjectValue(*wrapped));
}
static bool PushInnerFunctions(JSContext* cx, Debugger* dbg, HandleObject array,
mozilla::Span<const JS::GCCellPtr> gcThings) {
RootedFunction fun(cx);
for (JS::GCCellPtr gcThing : gcThings) {
if (!gcThing.is<JSObject>()) {
continue;
}
JSObject* obj = &gcThing.as<JSObject>();
if (obj->is<JSFunction>()) {
fun = &obj->as<JSFunction>();
if (!PushFunctionScript(cx, dbg, fun, array)) {
return false;
}
}
}
return true;
}
bool DebuggerScript::CallData::getChildScripts() {
if (!ensureScriptMaybeLazy()) {
return false;
@ -543,31 +565,15 @@ bool DebuggerScript::CallData::getChildScripts() {
return false;
}
RootedFunction fun(cx);
if (obj->getReferent().is<JSScript*>()) {
RootedScript script(cx, obj->getReferent().as<JSScript*>());
for (JS::GCCellPtr gcThing : script->gcthings()) {
if (!gcThing.is<JSObject>()) {
continue;
}
JSObject* obj = &gcThing.as<JSObject>();
if (obj->is<JSFunction>()) {
fun = &obj->as<JSFunction>();
if (!PushFunctionScript(cx, dbg, fun, result)) {
return false;
}
}
if (!PushInnerFunctions(cx, dbg, result, script->gcthings())) {
return false;
}
} else {
Rooted<LazyScript*> lazy(cx, obj->getReferent().as<LazyScript*>());
for (const GCPtrFunction& innerFun : lazy->innerFunctions()) {
fun = innerFun;
if (!PushFunctionScript(cx, dbg, fun, result)) {
return false;
}
if (!PushInnerFunctions(cx, dbg, result, lazy->gcthings())) {
return false;
}
}

Просмотреть файл

@ -102,7 +102,22 @@ class FullParseHandler {
lazyOuterFunction_(cx, lazyOuterFunction),
lazyInnerFunctionIndex(0),
lazyClosedOverBindingIndex(0),
sourceKind_(kind) {}
sourceKind_(kind) {
// The LazyScript::gcthings() array contains the inner function list
// followed by the closed-over bindings data. Advance the index for
// closed-over bindings to the end of the inner functions. The
// nextLazyInnerFunction / nextLazyClosedOverBinding accessors confirm we
// have the expected types. See also: LazyScript::Create.
if (lazyOuterFunction) {
for (JS::GCCellPtr gcThing : lazyOuterFunction->gcthings()) {
if (gcThing.is<JSObject>()) {
lazyClosedOverBindingIndex++;
} else {
break;
}
}
}
}
static NullNode null() { return NullNode(); }
@ -1036,15 +1051,17 @@ class FullParseHandler {
bool canSkipLazyInnerFunctions() { return !!lazyOuterFunction_; }
bool canSkipLazyClosedOverBindings() { return !!lazyOuterFunction_; }
JSFunction* nextLazyInnerFunction() {
MOZ_ASSERT(lazyInnerFunctionIndex <
lazyOuterFunction_->numInnerFunctions());
return lazyOuterFunction_->innerFunctions()[lazyInnerFunctionIndex++];
return &lazyOuterFunction_->gcthings()[lazyInnerFunctionIndex++]
.as<JSObject>()
.as<JSFunction>();
}
JSAtom* nextLazyClosedOverBinding() {
MOZ_ASSERT(lazyClosedOverBindingIndex <
lazyOuterFunction_->numClosedOverBindings());
return lazyOuterFunction_
->closedOverBindings()[lazyClosedOverBindingIndex++];
// These entries are either JSAtom* or nullptr, so use the 'asCell()'
// accessor which is faster.
gc::Cell* cell =
lazyOuterFunction_->gcthings()[lazyClosedOverBindingIndex++].asCell();
MOZ_ASSERT_IF(cell, cell->is<JSAtom>());
return static_cast<JSAtom*>(cell);
}
};

Просмотреть файл

@ -977,17 +977,8 @@ void LazyScript::traceChildren(JSTracer* trc) {
TraceNullableEdge(trc, &script_, "script");
}
// We rely on the fact that atoms are always tenured.
for (GCPtrAtom& closedOverBinding : closedOverBindings()) {
if (closedOverBinding) {
TraceEdge(trc, &closedOverBinding, "closedOverBinding");
}
}
for (GCPtrFunction& innerFunction : innerFunctions()) {
if (innerFunction) {
TraceEdge(trc, &innerFunction, "lazyScriptInnerFunction");
}
if (data_) {
data_->trace(trc);
}
if (trc->isMarkingTracer()) {
@ -1005,16 +996,16 @@ inline void js::GCMarker::eagerlyMarkChildren(LazyScript* thing) {
// script_ is weak so is not traced here.
// We rely on the fact that atoms are always tenured.
for (GCPtrAtom& closedOverBinding : thing->closedOverBindings()) {
if (closedOverBinding) {
traverseEdge(thing, static_cast<JSString*>(closedOverBinding));
}
}
for (GCPtrFunction& innerFunction : thing->innerFunctions()) {
if (innerFunction) {
traverseEdge(thing, static_cast<JSObject*>(innerFunction));
if (thing->data_) {
// Traverse the PrivateScriptData::gcthings() array.
for (JS::GCCellPtr& elem : thing->data_->gcthings()) {
if (elem.is<JSObject>()) {
traverseEdge(thing, &elem.as<JSObject>());
} else if (elem.is<JSString>()) {
traverseEdge(thing, &elem.as<JSString>());
} else {
MOZ_ASSERT(!elem);
}
}
}

Просмотреть файл

@ -86,11 +86,12 @@ static void TraverseInnerLazyScriptsForLazyScript(
JSContext* cx, void* data, LazyScript* enclosingLazyScript,
IterateLazyScriptCallback lazyScriptCallback,
const JS::AutoRequireNoGC& nogc) {
for (JSFunction* fun : enclosingLazyScript->innerFunctions()) {
// LazyScript::CreateForXDR temporarily initializes innerFunctions with
// its own function, but it should be overwritten with correct
// inner functions before getting inserted into parent's innerFunctions.
MOZ_ASSERT(fun != enclosingLazyScript->function());
for (JS::GCCellPtr gcThing : enclosingLazyScript->gcthings()) {
if (!gcThing.is<JSObject>()) {
continue;
}
JSFunction* fun = &gcThing.as<JSObject>().as<JSFunction>();
if (!fun->isInterpretedLazy()) {
return;

Просмотреть файл

@ -241,27 +241,59 @@ template XDRResult js::XDRScriptConst(XDRState<XDR_DECODE>*,
// Code LazyScript's closed over bindings.
template <XDRMode mode>
static XDRResult XDRLazyClosedOverBindings(XDRState<mode>* xdr,
MutableHandle<LazyScript*> lazy) {
/* static */
XDRResult LazyScript::XDRScriptData(XDRState<mode>* xdr,
HandleScriptSourceObject sourceObject,
Handle<LazyScript*> lazy) {
JSContext* cx = xdr->cx();
RootedAtom atom(cx);
for (GCPtrAtom& elem : lazy->closedOverBindings()) {
uint8_t endOfScopeSentinel;
if (mode == XDR_ENCODE) {
atom = elem.get();
endOfScopeSentinel = !atom;
}
RootedFunction func(cx);
MOZ_TRY(xdr->codeUint8(&endOfScopeSentinel));
for (JS::GCCellPtr& elem : lazy->data_->gcthings()) {
JS::TraceKind kind = elem.kind();
if (endOfScopeSentinel) {
atom = nullptr;
} else {
MOZ_TRY(XDRAtom(xdr, &atom));
}
MOZ_TRY(xdr->codeEnum32(&kind));
if (mode == XDR_DECODE) {
elem.init(atom);
switch (kind) {
case JS::TraceKind::Object: {
if (mode == XDR_ENCODE) {
func = &elem.as<JSObject>().as<JSFunction>();
}
MOZ_TRY(XDRInterpretedFunction(xdr, nullptr, sourceObject, &func));
if (mode == XDR_DECODE) {
MOZ_ASSERT(func->isInterpretedLazy());
func->setEnclosingLazyScript(lazy);
elem = JS::GCCellPtr(func);
}
break;
}
case JS::TraceKind::String: {
if (mode == XDR_ENCODE) {
gc::Cell* cell = elem.asCell();
MOZ_ASSERT_IF(cell, cell->is<JSAtom>());
atom = static_cast<JSAtom*>(cell);
}
MOZ_TRY(XDRAtom(xdr, &atom));
if (mode == XDR_DECODE) {
elem = JS::GCCellPtr(static_cast<JSString*>(atom));
}
break;
}
case JS::TraceKind::Null: {
// This is default so nothing to do.
MOZ_ASSERT(!elem);
break;
}
default: {
// Fail in debug, but only soft-fail in release
MOZ_ASSERT(false, "Bad XDR class kind");
return xdr->fail(JS::TranscodeResult_Failure_BadDecode);
}
}
}
@ -279,8 +311,10 @@ static XDRResult XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun,
JSContext* cx = xdr->cx();
RootedScriptSourceObject sourceObject(cx, script->sourceObject());
uint32_t immutableFlags;
uint32_t numClosedOverBindings;
uint32_t ngcthings;
{
uint32_t sourceStart = script->sourceStart();
uint32_t sourceEnd = script->sourceEnd();
@ -292,17 +326,13 @@ static XDRResult XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun,
if (mode == XDR_ENCODE) {
immutableFlags = lazy->immutableFlags();
numClosedOverBindings = lazy->numClosedOverBindings();
ngcthings = lazy->gcthings().size();
MOZ_ASSERT(sourceStart == lazy->sourceStart());
MOZ_ASSERT(sourceEnd == lazy->sourceEnd());
MOZ_ASSERT(toStringStart == lazy->toStringStart());
MOZ_ASSERT(toStringEnd == lazy->toStringEnd());
MOZ_ASSERT(lineno == lazy->lineno());
MOZ_ASSERT(column == lazy->column());
// We can assert we have no inner functions because we don't
// relazify scripts with inner functions. See
// JSFunction::delazifyLazilyInterpretedFunction.
MOZ_ASSERT(!lazy->hasInnerFunctions());
if (fun->kind() == FunctionFlags::FunctionKind::ClassConstructor) {
numFieldInitializers =
(uint32_t)lazy->getFieldInitializers().numFieldInitializers;
@ -313,14 +343,13 @@ static XDRResult XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun,
MOZ_TRY(xdr->codeUint32(&immutableFlags));
MOZ_TRY(xdr->codeUint32(&numFieldInitializers));
MOZ_TRY(xdr->codeUint32(&numClosedOverBindings));
MOZ_TRY(xdr->codeUint32(&ngcthings));
if (mode == XDR_DECODE) {
RootedScriptSourceObject sourceObject(cx, script->sourceObject());
lazy.set(LazyScript::CreateForXDR(
cx, numClosedOverBindings, /* numInnerFunctions = */ 0, fun, script,
enclosingScope, sourceObject, immutableFlags, sourceStart, sourceEnd,
toStringStart, toStringEnd, lineno, column));
cx, ngcthings, fun, script, enclosingScope, sourceObject,
immutableFlags, sourceStart, sourceEnd, toStringStart, toStringEnd,
lineno, column));
if (!lazy) {
return xdr->fail(JS::TranscodeResult_Throw);
}
@ -332,11 +361,11 @@ static XDRResult XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun,
}
}
// Code binding names.
MOZ_TRY(XDRLazyClosedOverBindings(xdr, lazy));
// We can assert we have no inner functions because we don't relazify scripts
// with inner functions. See JSFunction::delazifyLazilyInterpretedFunction.
MOZ_ASSERT(!lazy->hasInnerFunctions());
// No need to do anything with inner functions, since we asserted we don't
// have any.
MOZ_TRY(LazyScript::XDRScriptData(xdr, sourceObject, lazy));
return Ok();
}
@ -1249,8 +1278,7 @@ XDRResult js::XDRLazyScript(XDRState<mode>* xdr, HandleScope enclosingScope,
uint32_t column;
uint32_t immutableFlags;
uint32_t numFieldInitializers;
uint32_t numClosedOverBindings;
uint32_t numInnerFunctions;
uint32_t ngcthings;
if (mode == XDR_ENCODE) {
// Note: it's possible the LazyScript has a non-null script_ pointer
@ -1272,8 +1300,7 @@ XDRResult js::XDRLazyScript(XDRState<mode>* xdr, HandleScope enclosingScope,
} else {
numFieldInitializers = UINT32_MAX;
}
numClosedOverBindings = lazy->numClosedOverBindings();
numInnerFunctions = lazy->numInnerFunctions();
ngcthings = lazy->gcthings().size();
}
MOZ_TRY(xdr->codeUint32(&sourceStart));
@ -1284,14 +1311,13 @@ XDRResult js::XDRLazyScript(XDRState<mode>* xdr, HandleScope enclosingScope,
MOZ_TRY(xdr->codeUint32(&column));
MOZ_TRY(xdr->codeUint32(&immutableFlags));
MOZ_TRY(xdr->codeUint32(&numFieldInitializers));
MOZ_TRY(xdr->codeUint32(&numClosedOverBindings));
MOZ_TRY(xdr->codeUint32(&numInnerFunctions));
MOZ_TRY(xdr->codeUint32(&ngcthings));
if (mode == XDR_DECODE) {
lazy.set(LazyScript::CreateForXDR(
cx, numClosedOverBindings, numInnerFunctions, fun, nullptr,
enclosingScope, sourceObject, immutableFlags, sourceStart, sourceEnd,
toStringStart, toStringEnd, lineno, column));
cx, ngcthings, fun, nullptr, enclosingScope, sourceObject,
immutableFlags, sourceStart, sourceEnd, toStringStart, toStringEnd,
lineno, column));
if (!lazy) {
return xdr->fail(JS::TranscodeResult_Throw);
}
@ -1305,27 +1331,7 @@ XDRResult js::XDRLazyScript(XDRState<mode>* xdr, HandleScope enclosingScope,
}
}
// Code closed-over bindings.
MOZ_TRY(XDRLazyClosedOverBindings(xdr, lazy));
// Code inner functions.
{
RootedFunction func(cx);
for (GCPtrFunction& elem : lazy->innerFunctions()) {
if (mode == XDR_ENCODE) {
func = elem.get();
}
MOZ_TRY(XDRInterpretedFunction(xdr, nullptr, sourceObject, &func));
if (mode == XDR_DECODE) {
elem.init(func);
if (elem->isInterpretedLazy()) {
elem->setEnclosingLazyScript(lazy);
}
}
}
}
MOZ_TRY(LazyScript::XDRScriptData(xdr, sourceObject, lazy));
return Ok();
}
@ -5332,9 +5338,8 @@ void JSScript::traceChildren(JSTracer* trc) {
}
void LazyScript::finalize(JSFreeOp* fop) {
if (lazyData_) {
fop->free_(this, lazyData_, lazyData_->allocationSize(),
MemoryUse::LazyScriptData);
if (data_) {
fop->free_(this, data_, data_->allocationSize(), MemoryUse::LazyScriptData);
}
}
@ -5556,103 +5561,16 @@ bool JSScript::formalLivesInArgumentsObject(unsigned argSlot) {
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
}
/* static */ size_t LazyScriptData::AllocationSize(
uint32_t numClosedOverBindings, uint32_t numInnerFunctions) {
size_t size = sizeof(LazyScriptData);
size += numClosedOverBindings * sizeof(GCPtrAtom);
size += numInnerFunctions * sizeof(GCPtrFunction);
return size;
}
inline size_t LazyScriptData::allocationSize() const {
return AllocationSize(numClosedOverBindings_, numInnerFunctions_);
}
// Placement-new elements of an array. This should optimize away for types with
// trivial default initiation.
template <typename T>
void LazyScriptData::initElements(size_t offset, size_t length) {
void* raw = offsetToPointer<void>(offset);
DefaultInitializeElements<T>(raw, length);
}
LazyScriptData::LazyScriptData(uint32_t numClosedOverBindings,
uint32_t numInnerFunctions)
: numClosedOverBindings_(numClosedOverBindings),
numInnerFunctions_(numInnerFunctions) {
// Variable-length data begins immediately after LazyScriptData itself.
size_t cursor = sizeof(*this);
// Default-initialize trailing arrays.
static_assert(alignof(LazyScriptData) >= alignof(GCPtrAtom),
"Incompatible alignment");
initElements<GCPtrAtom>(cursor, numClosedOverBindings);
cursor += numClosedOverBindings * sizeof(GCPtrAtom);
static_assert(alignof(GCPtrAtom) >= alignof(GCPtrFunction),
"Incompatible alignment");
initElements<GCPtrFunction>(cursor, numInnerFunctions);
cursor += numInnerFunctions * sizeof(GCPtrFunction);
// Sanity check
MOZ_ASSERT(AllocationSize(numClosedOverBindings, numInnerFunctions) ==
cursor);
}
/* static */ LazyScriptData* LazyScriptData::new_(
JSContext* cx, uint32_t numClosedOverBindings, uint32_t numInnerFunctions) {
// Compute size including trailing arrays
size_t size = AllocationSize(numClosedOverBindings, numInnerFunctions);
// Allocate contiguous raw buffer
void* raw = cx->pod_malloc<uint8_t>(size);
MOZ_ASSERT(uintptr_t(raw) % alignof(LazyScriptData) == 0);
if (!raw) {
return nullptr;
}
// Constuct the LazyScriptData. Trailing arrays are uninitialized but
// GCPtrs are put into a safe state.
return new (raw) LazyScriptData(numClosedOverBindings, numInnerFunctions);
}
mozilla::Span<GCPtrAtom> LazyScriptData::closedOverBindings() {
size_t offset = sizeof(LazyScriptData);
return mozilla::MakeSpan(offsetToPointer<GCPtrAtom>(offset),
numClosedOverBindings_);
}
mozilla::Span<GCPtrFunction> LazyScriptData::innerFunctions() {
size_t offset =
sizeof(LazyScriptData) + sizeof(GCPtrAtom) * numClosedOverBindings_;
return mozilla::MakeSpan(offsetToPointer<GCPtrFunction>(offset),
numInnerFunctions_);
}
void LazyScriptData::trace(JSTracer* trc) {
if (numClosedOverBindings_) {
auto array = closedOverBindings();
TraceRange(trc, array.size(), array.data(), "closedOverBindings");
}
if (numInnerFunctions_) {
auto array = innerFunctions();
TraceRange(trc, array.size(), array.data(), "innerFunctions");
}
}
LazyScript::LazyScript(JSFunction* fun, uint8_t* stubEntry,
ScriptSourceObject& sourceObject, LazyScriptData* data,
uint32_t immutableFlags, uint32_t sourceStart,
uint32_t sourceEnd, uint32_t toStringStart,
uint32_t toStringEnd, uint32_t lineno, uint32_t column)
ScriptSourceObject& sourceObject,
PrivateScriptData* data, uint32_t immutableFlags,
uint32_t sourceStart, uint32_t sourceEnd,
uint32_t toStringStart, uint32_t toStringEnd,
uint32_t lineno, uint32_t column)
: BaseScript(stubEntry, fun, &sourceObject, sourceStart, sourceEnd,
toStringStart, toStringEnd),
script_(nullptr),
lazyData_(data) {
data_(data) {
lineno_ = lineno;
column_ = column;
@ -5694,8 +5612,7 @@ void LazyScript::setEnclosingScope(Scope* enclosingScope) {
}
/* static */
LazyScript* LazyScript::CreateRaw(JSContext* cx, uint32_t numClosedOverBindings,
uint32_t numInnerFunctions,
LazyScript* LazyScript::CreateRaw(JSContext* cx, uint32_t ngcthings,
HandleFunction fun,
HandleScriptSourceObject sourceObject,
uint32_t immutableFlags, uint32_t sourceStart,
@ -5706,12 +5623,11 @@ LazyScript* LazyScript::CreateRaw(JSContext* cx, uint32_t numClosedOverBindings,
MOZ_ASSERT(sourceObject);
// Allocate a LazyScriptData if it will not be empty. Lazy class constructors
// also need LazyScriptData for field lists.
Rooted<UniquePtr<LazyScriptData>> data(cx);
if (numClosedOverBindings || numInnerFunctions || fun->isClassConstructor()) {
data.reset(
LazyScriptData::new_(cx, numClosedOverBindings, numInnerFunctions));
// Allocate a PrivateScriptData if it will not be empty. Lazy class
// constructors also need PrivateScriptData for field lists.
Rooted<UniquePtr<PrivateScriptData>> data(cx);
if (ngcthings || fun->isClassConstructor()) {
data.reset(PrivateScriptData::new_(cx, ngcthings));
if (!data) {
return nullptr;
}
@ -5750,41 +5666,52 @@ LazyScript* LazyScript::Create(
immutableFlags |= uint32_t(ImmutableFlags::HasInnerFunctions);
}
uint32_t ngcthings =
innerFunctionBoxes.length() + closedOverBindings.length();
LazyScript* res = LazyScript::CreateRaw(
cx, closedOverBindings.length(), innerFunctionBoxes.length(), fun,
sourceObject, immutableFlags, sourceStart, sourceEnd, toStringStart,
toStringEnd, lineno, column);
cx, ngcthings, fun, sourceObject, immutableFlags, sourceStart, sourceEnd,
toStringStart, toStringEnd, lineno, column);
if (!res) {
return nullptr;
}
mozilla::Span<GCPtrAtom> resClosedOverBindings = res->closedOverBindings();
for (size_t i = 0; i < res->numClosedOverBindings(); i++) {
resClosedOverBindings[i].init(closedOverBindings[i]);
// Fill in gcthing data with inner functions followed by binding data.
mozilla::Span<JS::GCCellPtr> gcThings =
res->data_ ? res->data_->gcthings() : mozilla::Span<JS::GCCellPtr>();
auto iter = gcThings.begin();
for (const frontend::FunctionBox* funbox : innerFunctionBoxes) {
JSFunction* fun = funbox->function();
*iter++ = JS::GCCellPtr(fun);
MOZ_ASSERT(fun->isInterpretedLazy());
fun->setEnclosingLazyScript(res);
}
mozilla::Span<GCPtrFunction> resInnerFunctions = res->innerFunctions();
for (size_t i = 0; i < res->numInnerFunctions(); i++) {
resInnerFunctions[i].init(innerFunctionBoxes[i]->function());
if (resInnerFunctions[i]->isInterpretedLazy()) {
resInnerFunctions[i]->setEnclosingLazyScript(res);
for (JSAtom* binding : closedOverBindings) {
if (binding) {
*iter++ = JS::GCCellPtr(binding);
} else {
iter++;
}
}
MOZ_ASSERT(iter == gcThings.end());
return res;
}
/* static */
LazyScript* LazyScript::CreateForXDR(
JSContext* cx, uint32_t numClosedOverBindings, uint32_t numInnerFunctions,
HandleFunction fun, HandleScript script, HandleScope enclosingScope,
HandleScriptSourceObject sourceObject, uint32_t immutableFlags,
uint32_t sourceStart, uint32_t sourceEnd, uint32_t toStringStart,
uint32_t toStringEnd, uint32_t lineno, uint32_t column) {
JSContext* cx, uint32_t ngcthings, HandleFunction fun, HandleScript script,
HandleScope enclosingScope, HandleScriptSourceObject sourceObject,
uint32_t immutableFlags, uint32_t sourceStart, uint32_t sourceEnd,
uint32_t toStringStart, uint32_t toStringEnd, uint32_t lineno,
uint32_t column) {
LazyScript* res = LazyScript::CreateRaw(
cx, numClosedOverBindings, numInnerFunctions, fun, sourceObject,
immutableFlags, sourceStart, sourceEnd, toStringStart, toStringEnd,
lineno, column);
cx, ngcthings, fun, sourceObject, immutableFlags, sourceStart, sourceEnd,
toStringStart, toStringEnd, lineno, column);
if (!res) {
return nullptr;
}

Просмотреть файл

@ -3223,48 +3223,6 @@ static_assert(
namespace js {
// Variable-length data for LazyScripts. Contains vector of inner functions and
// vector of captured property ids.
class alignas(uintptr_t) LazyScriptData final {
private:
uint32_t numClosedOverBindings_ = 0;
uint32_t numInnerFunctions_ = 0;
FieldInitializers fieldInitializers_ = FieldInitializers::Invalid();
// Size to allocate
static size_t AllocationSize(uint32_t numClosedOverBindings,
uint32_t numInnerFunctions);
size_t allocationSize() const;
// Translate an offset into a concrete pointer.
template <typename T>
T* offsetToPointer(size_t offset) {
uintptr_t base = reinterpret_cast<uintptr_t>(this);
return reinterpret_cast<T*>(base + offset);
}
template <typename T>
void initElements(size_t offset, size_t length);
LazyScriptData(uint32_t numClosedOverBindings, uint32_t numInnerFunctions);
public:
static LazyScriptData* new_(JSContext* cx, uint32_t numClosedOverBindings,
uint32_t numInnerFunctions);
friend class LazyScript;
mozilla::Span<GCPtrAtom> closedOverBindings();
mozilla::Span<GCPtrFunction> innerFunctions();
void trace(JSTracer* trc);
// LazyScriptData has trailing data so isn't copyable or movable.
LazyScriptData(const LazyScriptData&) = delete;
LazyScriptData& operator=(const LazyScriptData&) = delete;
};
// Information about a script which may be (or has been) lazily compiled to
// bytecode from its source.
class LazyScript : public BaseScript {
@ -3353,14 +3311,14 @@ class LazyScript : public BaseScript {
// +-----------------+
// Heap allocated table with any free variables, inner functions, or class
// fields. This will be nullptr if none exist.
LazyScriptData* lazyData_;
// fields. This will be nullptr if none exists.
PrivateScriptData* data_ = nullptr;
static const uint32_t NumClosedOverBindingsBits = 20;
static const uint32_t NumInnerFunctionsBits = 20;
LazyScript(JSFunction* fun, uint8_t* stubEntry,
ScriptSourceObject& sourceObject, LazyScriptData* data,
ScriptSourceObject& sourceObject, PrivateScriptData* data,
uint32_t immutableFlags, uint32_t sourceStart, uint32_t sourceEnd,
uint32_t toStringStart, uint32_t toStringEnd, uint32_t lineno,
uint32_t column);
@ -3368,8 +3326,8 @@ class LazyScript : public BaseScript {
// Create a LazyScript without initializing the closedOverBindings and the
// innerFunctions. To be GC-safe, the caller must initialize both vectors
// with valid atoms and functions.
static LazyScript* CreateRaw(JSContext* cx, uint32_t numClosedOverBindings,
uint32_t numInnerFunctions, HandleFunction fun,
static LazyScript* CreateRaw(JSContext* cx, uint32_t ngcthings,
HandleFunction fun,
HandleScriptSourceObject sourceObject,
uint32_t immutableFlags, uint32_t sourceStart,
uint32_t sourceEnd, uint32_t toStringStart,
@ -3400,12 +3358,19 @@ class LazyScript : public BaseScript {
//
// The sourceObject and enclosingScope arguments may be null if the
// enclosing function is also lazy.
static LazyScript* CreateForXDR(
JSContext* cx, uint32_t numClosedOverBindings, uint32_t numInnerFunctions,
HandleFunction fun, HandleScript script, HandleScope enclosingScope,
HandleScriptSourceObject sourceObject, uint32_t immutableFlags,
uint32_t sourceStart, uint32_t sourceEnd, uint32_t toStringStart,
uint32_t toStringEnd, uint32_t lineno, uint32_t column);
static LazyScript* CreateForXDR(JSContext* cx, uint32_t ngcthings,
HandleFunction fun, HandleScript script,
HandleScope enclosingScope,
HandleScriptSourceObject sourceObject,
uint32_t immutableFlags, uint32_t sourceStart,
uint32_t sourceEnd, uint32_t toStringStart,
uint32_t toStringEnd, uint32_t lineno,
uint32_t column);
template <XDRMode mode>
static XDRResult XDRScriptData(XDRState<mode>* xdr,
HandleScriptSourceObject sourceObject,
Handle<LazyScript*> lazy);
bool canRelazify() const {
// Only functions without inner functions or direct eval are re-lazified.
@ -3441,20 +3406,8 @@ class LazyScript : public BaseScript {
return enclosingScope()->hasOnChain(ScopeKind::NonSyntactic);
}
mozilla::Span<GCPtrAtom> closedOverBindings() {
return lazyData_ ? lazyData_->closedOverBindings()
: mozilla::Span<GCPtrAtom>();
}
uint32_t numClosedOverBindings() const {
return lazyData_ ? lazyData_->closedOverBindings().size() : 0;
};
mozilla::Span<GCPtrFunction> innerFunctions() {
return lazyData_ ? lazyData_->innerFunctions()
: mozilla::Span<GCPtrFunction>();
}
uint32_t numInnerFunctions() const {
return lazyData_ ? lazyData_->innerFunctions().size() : 0;
mozilla::Span<JS::GCCellPtr> gcthings() {
return data_ ? data_->gcthings() : mozilla::Span<JS::GCCellPtr>();
}
frontend::ParseGoal parseGoal() const {
@ -3472,13 +3425,13 @@ class LazyScript : public BaseScript {
void setWrappedByDebugger() { setFlag(MutableFlags::WrappedByDebugger); }
void setFieldInitializers(FieldInitializers fieldInitializers) {
MOZ_ASSERT(lazyData_);
lazyData_->fieldInitializers_ = fieldInitializers;
MOZ_ASSERT(data_);
data_->setFieldInitializers(fieldInitializers);
}
const FieldInitializers& getFieldInitializers() const {
MOZ_ASSERT(lazyData_);
return lazyData_->fieldInitializers_;
MOZ_ASSERT(data_);
return data_->getFieldInitializers();
}
// Returns true if the enclosing script has ever been compiled.
@ -3498,7 +3451,7 @@ class LazyScript : public BaseScript {
static const JS::TraceKind TraceKind = JS::TraceKind::LazyScript;
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
return mallocSizeOf(lazyData_);
return mallocSizeOf(data_);
}
};