Bug 917996 - XDR Lazy Scripts. r=till

This commit is contained in:
Nicolas B. Pierron 2014-02-19 07:46:33 -08:00
parent 022c86a654
commit 3557e5f96f
4 changed files with 378 additions and 79 deletions

View File

@ -2069,9 +2069,9 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox *funbo
size_t numInnerFunctions = pc->innerFunctions.length();
RootedFunction fun(context, funbox->function());
LazyScript *lazy = LazyScript::Create(context, fun, numFreeVariables, numInnerFunctions, versionNumber(),
funbox->bufStart, funbox->bufEnd,
funbox->startLine, funbox->startColumn);
LazyScript *lazy = LazyScript::CreateRaw(context, fun, numFreeVariables, numInnerFunctions,
versionNumber(), funbox->bufStart, funbox->bufEnd,
funbox->startLine, funbox->startColumn);
if (!lazy)
return false;

View File

@ -357,8 +357,9 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
MutableHandleObject objp)
{
enum FirstWordFlag {
HasAtom = 0x1,
IsStarGenerator = 0x2
HasAtom = 0x1,
IsStarGenerator = 0x2,
IsLazy = 0x4
};
/* NB: Keep this in sync with CloneFunctionAndScript. */
@ -369,6 +370,8 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
JSContext *cx = xdr->cx();
RootedFunction fun(cx);
RootedScript script(cx);
Rooted<LazyScript *> lazy(cx);
if (mode == XDR_ENCODE) {
fun = &objp->as<JSFunction>();
if (!fun->isInterpreted()) {
@ -379,13 +382,27 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
}
return false;
}
if (fun->atom() || fun->hasGuessedAtom())
firstword |= HasAtom;
if (fun->isStarGenerator())
firstword |= IsStarGenerator;
script = fun->getOrCreateScript(cx);
if (!script)
return false;
if (fun->isInterpretedLazy()) {
// This can only happen for re-lazified cloned functions, so this
// does not apply to any JSFunction produced by the parser, only to
// JSFunction created by the runtime.
JS_ASSERT(!fun->lazyScript()->maybeScript());
// Encode a lazy script.
firstword |= IsLazy;
lazy = fun->lazyScript();
} else {
// Encode the script.
script = fun->nonLazyScript();
}
atom = fun->displayAtom();
flagsword = (fun->nargs() << 16) | fun->flags();
}
@ -414,18 +431,29 @@ js::XDRInterpretedFunction(XDRState<mode> *xdr, HandleObject enclosingScope, Han
if (!xdr->codeUint32(&flagsword))
return false;
if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
return false;
if (firstword & IsLazy) {
if (!XDRLazyScript(xdr, enclosingScope, enclosingScript, fun, &lazy))
return false;
} else {
if (!XDRScript(xdr, enclosingScope, enclosingScript, fun, &script))
return false;
}
if (mode == XDR_DECODE) {
fun->setArgCount(flagsword >> 16);
fun->setFlags(uint16_t(flagsword));
fun->initAtom(atom);
fun->initScript(script);
script->setFunction(fun);
if (firstword & IsLazy) {
fun->initLazyScript(lazy);
} else {
fun->initScript(script);
script->setFunction(fun);
JS_ASSERT(fun->nargs() == script->bindings.numArgs());
}
if (!JSFunction::setTypeForScriptedFunction(cx, fun))
return false;
JS_ASSERT(fun->nargs() == fun->nonLazyScript()->bindings.numArgs());
objp.set(fun);
}

View File

@ -414,6 +414,75 @@ js::XDRScriptConst(XDRState<XDR_ENCODE> *, MutableHandleValue);
template bool
js::XDRScriptConst(XDRState<XDR_DECODE> *, MutableHandleValue);
// Code LazyScript's free variables.
template<XDRMode mode>
static bool
XDRLazyFreeVariables(XDRState<mode> *xdr, MutableHandle<LazyScript *> lazy)
{
JSContext *cx = xdr->cx();
RootedAtom atom(cx);
HeapPtrAtom *freeVariables = lazy->freeVariables();
size_t numFreeVariables = lazy->numFreeVariables();
for (size_t i = 0; i < numFreeVariables; i++) {
if (mode == XDR_ENCODE)
atom = freeVariables[i];
if (!XDRAtom(xdr, &atom))
return false;
if (mode == XDR_DECODE)
freeVariables[i] = atom;
}
return true;
}
// Code the missing part needed to re-create a LazyScript from a JSScript.
template<XDRMode mode>
static bool
XDRRelazificationInfo(XDRState<mode> *xdr, HandleFunction fun, HandleScript script,
MutableHandle<LazyScript *> lazy)
{
MOZ_ASSERT_IF(mode == XDR_ENCODE, script->isRelazifiable() && script->maybeLazyScript());
MOZ_ASSERT_IF(mode == XDR_ENCODE, !lazy->numInnerFunctions());
JSContext *cx = xdr->cx();
uint64_t packedFields;
{
uint32_t begin = script->sourceStart();
uint32_t end = script->sourceEnd();
uint32_t lineno = script->lineno();
uint32_t column = script->column();
if (mode == XDR_ENCODE) {
packedFields = lazy->packedFields();
MOZ_ASSERT(begin == lazy->begin());
MOZ_ASSERT(end == lazy->end());
MOZ_ASSERT(lineno == lazy->lineno());
MOZ_ASSERT(column == lazy->column());
}
if (!xdr->codeUint64(&packedFields))
return false;
if (mode == XDR_DECODE) {
lazy.set(LazyScript::Create(cx, fun, packedFields, begin, end, lineno, column));
// As opposed to XDRLazyScript, we need to restore the runtime bits
// of the script, as we are trying to match the fact this function
// has already been parsed and that it would need to be re-lazified.
lazy->initRuntimeFields(packedFields);
}
}
// Code free variables.
if (!XDRLazyFreeVariables(xdr, lazy))
return false;
return true;
}
static inline uint32_t
FindScopeObjectIndex(JSScript *script, NestedScopeObject &scope)
{
@ -463,7 +532,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
SelfHosted,
IsCompileAndGo,
HasSingleton,
TreatAsRunOnce
TreatAsRunOnce,
HasLazyScript
};
uint32_t length, lineno, column, nslots;
@ -561,6 +631,8 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
scriptBits |= (1 << HasSingleton);
if (script->treatAsRunOnce())
scriptBits |= (1 << TreatAsRunOnce);
if (script->isRelazifiable())
scriptBits |= (1 << HasLazyScript);
}
if (!xdr->codeUint32(&prologLength))
@ -821,12 +893,16 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
case CK_JSFunction: {
/* Code the nested function's enclosing scope. */
uint32_t funEnclosingScopeIndex = 0;
RootedObject funEnclosingScope(cx);
if (mode == XDR_ENCODE) {
JSScript *innerScript = (*objp)->as<JSFunction>().getOrCreateScript(cx);
if (!innerScript)
return false;
RootedObject staticScope(cx, innerScript->enclosingStaticScope());
StaticScopeIter<NoGC> ssi(staticScope);
RootedFunction function(cx, &(*objp)->as<JSFunction>());
if (function->isInterpretedLazy())
funEnclosingScope = function->lazyScript()->enclosingScope();
else
funEnclosingScope = function->nonLazyScript()->enclosingStaticScope();
StaticScopeIter<NoGC> ssi(funEnclosingScope);
if (ssi.done() || ssi.type() == StaticScopeIter<NoGC>::FUNCTION) {
JS_ASSERT(ssi.done() == !fun);
funEnclosingScopeIndex = UINT32_MAX;
@ -835,9 +911,10 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
JS_ASSERT(funEnclosingScopeIndex < i);
}
}
if (!xdr->codeUint32(&funEnclosingScopeIndex))
return false;
Rooted<JSObject*> funEnclosingScope(cx);
if (mode == XDR_DECODE) {
if (funEnclosingScopeIndex == UINT32_MAX) {
funEnclosingScope = fun;
@ -847,6 +924,7 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
}
}
// Code nested function and script.
RootedObject tmp(cx, *objp);
if (!XDRInterpretedFunction(xdr, funEnclosingScope, script, &tmp))
return false;
@ -901,6 +979,18 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
}
}
if (scriptBits & (1 << HasLazyScript)) {
Rooted<LazyScript *> lazy(cx);
if (mode == XDR_ENCODE)
lazy = script->maybeLazyScript();
if (!XDRRelazificationInfo(xdr, fun, script, &lazy))
return false;
if (mode == XDR_DECODE)
script->setLazyScript(lazy);
}
if (mode == XDR_DECODE) {
scriptp.set(script);
@ -923,6 +1013,83 @@ template bool
js::XDRScript(XDRState<XDR_DECODE> *, HandleObject, HandleScript, HandleFunction,
MutableHandleScript);
template<XDRMode mode>
bool
js::XDRLazyScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
HandleFunction fun, MutableHandle<LazyScript *> lazy)
{
JSContext *cx = xdr->cx();
{
uint32_t begin;
uint32_t end;
uint32_t lineno;
uint32_t column;
uint64_t packedFields;
if (mode == XDR_ENCODE) {
MOZ_ASSERT(!lazy->maybeScript());
MOZ_ASSERT(fun == lazy->functionNonDelazifying());
begin = lazy->begin();
end = lazy->end();
lineno = lazy->lineno();
column = lazy->column();
packedFields = lazy->packedFields();
}
if (!xdr->codeUint32(&begin) || !xdr->codeUint32(&end) ||
!xdr->codeUint32(&lineno) || !xdr->codeUint32(&column) ||
!xdr->codeUint64(&packedFields))
{
return false;
}
if (mode == XDR_DECODE)
lazy.set(LazyScript::Create(cx, fun, packedFields, begin, end, lineno, column));
}
// Code free variables.
if (!XDRLazyFreeVariables(xdr, lazy))
return false;
// Code inner functions.
{
RootedObject func(cx);
HeapPtrFunction *innerFunctions = lazy->innerFunctions();
size_t numInnerFunctions = lazy->numInnerFunctions();
for (size_t i = 0; i < numInnerFunctions; i++) {
if (mode == XDR_ENCODE)
func = innerFunctions[i];
if (!XDRInterpretedFunction(xdr, fun, enclosingScript, &func))
return false;
if (mode == XDR_DECODE)
innerFunctions[i] = &func->as<JSFunction>();
}
}
if (mode == XDR_DECODE) {
JS_ASSERT(!lazy->sourceObject());
ScriptSourceObject *sourceObject = &enclosingScript->scriptSourceUnwrap();
// Set the enclosing scope of the lazy function, this would later be
// used to define the environment when the function would be used.
lazy->setParent(enclosingScope, sourceObject);
}
return true;
}
template bool
js::XDRLazyScript(XDRState<XDR_ENCODE> *, HandleObject, HandleScript,
HandleFunction, MutableHandle<LazyScript *>);
template bool
js::XDRLazyScript(XDRState<XDR_DECODE> *, HandleObject, HandleScript,
HandleFunction, MutableHandle<LazyScript *>);
void
JSScript::setSourceObject(JSObject *object)
{
@ -930,9 +1097,14 @@ JSScript::setSourceObject(JSObject *object)
sourceObject_ = object;
}
js::ScriptSourceObject &
JSScript::scriptSourceUnwrap() const {
return UncheckedUnwrap(sourceObject())->as<ScriptSourceObject>();
}
js::ScriptSource *
JSScript::scriptSource() const {
return UncheckedUnwrap(sourceObject())->as<ScriptSourceObject>().source();
return scriptSourceUnwrap().source();
}
bool
@ -3242,30 +3414,18 @@ JSScript::formalLivesInArgumentsObject(unsigned argSlot)
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
}
LazyScript::LazyScript(JSFunction *fun, void *table, uint32_t numFreeVariables, uint32_t numInnerFunctions,
JSVersion version, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
LazyScript::LazyScript(JSFunction *fun, void *table, uint64_t packedFields, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
: script_(nullptr),
function_(fun),
enclosingScope_(nullptr),
sourceObject_(nullptr),
table_(table),
version_(version),
numFreeVariables_(numFreeVariables),
numInnerFunctions_(numInnerFunctions),
generatorKindBits_(GeneratorKindAsBits(NotGenerator)),
strict_(false),
bindingsAccessedDynamically_(false),
hasDebuggerStatement_(false),
directlyInsideEval_(false),
usesArgumentsAndApply_(false),
hasBeenCloned_(false),
treatAsRunOnce_(false),
packedFields_(packedFields),
begin_(begin),
end_(end),
lineno_(lineno),
column_(column)
{
JS_ASSERT(this->version() == version);
JS_ASSERT(begin <= end);
}
@ -3301,14 +3461,23 @@ LazyScript::sourceObject() const
}
/* static */ LazyScript *
LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
LazyScript::CreateRaw(ExclusiveContext *cx, HandleFunction fun,
uint64_t packedFields, uint32_t begin, uint32_t end,
uint32_t lineno, uint32_t column)
{
JS_ASSERT(begin <= end);
union {
PackedView p;
uint64_t packed;
};
size_t bytes = (numFreeVariables * sizeof(HeapPtrAtom))
+ (numInnerFunctions * sizeof(HeapPtrFunction));
packed = packedFields;
// Reset runtime flags to obtain a fresh LazyScript.
p.hasBeenCloned = false;
p.treatAsRunOnce = false;
size_t bytes = (p.numFreeVariables * sizeof(HeapPtrAtom))
+ (p.numInnerFunctions * sizeof(HeapPtrFunction));
void *table = nullptr;
if (bytes) {
@ -3323,8 +3492,75 @@ LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
cx->compartment()->scheduleDelazificationForDebugMode();
return new (res) LazyScript(fun, table, numFreeVariables, numInnerFunctions, version,
begin, end, lineno, column);
return new (res) LazyScript(fun, table, packed, begin, end, lineno, column);
}
/* static */ LazyScript *
LazyScript::CreateRaw(ExclusiveContext *cx, HandleFunction fun,
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
{
union {
PackedView p;
uint64_t packedFields;
};
p.version = version;
p.numFreeVariables = numFreeVariables;
p.numInnerFunctions = numInnerFunctions;
p.generatorKindBits = GeneratorKindAsBits(NotGenerator);
p.strict = false;
p.bindingsAccessedDynamically = false;
p.hasDebuggerStatement = false;
p.directlyInsideEval = false;
p.usesArgumentsAndApply = false;
LazyScript *res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column);
JS_ASSERT(res->version() == version);
return res;
}
/* static */ LazyScript *
LazyScript::Create(ExclusiveContext *cx, HandleFunction fun,
uint64_t packedFields, uint32_t begin, uint32_t end,
uint32_t lineno, uint32_t column)
{
// Dummy atom which is not a valid property name.
RootedAtom dummyAtom(cx, cx->names().comma);
// Dummy function which is not a valid function as this is the one which is
// holding this lazy script.
HandleFunction dummyFun = fun;
LazyScript *res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column);
if (!res)
return nullptr;
// Fill with dummies, to be GC-safe after the initialization of the free
// variables and inner functions.
size_t i, num;
HeapPtrAtom *variables = res->freeVariables();
for (i = 0, num = res->numFreeVariables(); i < num; i++)
variables[i].init(dummyAtom);
HeapPtrFunction *functions = res->innerFunctions();
for (i = 0, num = res->numInnerFunctions(); i < num; i++)
functions[i].init(dummyFun);
return res;
}
void
LazyScript::initRuntimeFields(uint64_t packedFields)
{
union {
PackedView p;
uint64_t packed;
};
packed = packedFields;
p_.hasBeenCloned = p.hasBeenCloned;
p_.treatAsRunOnce = p.treatAsRunOnce;
}
uint32_t

View File

@ -595,6 +595,11 @@ JSScript *
CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript script,
NewObjectKind newKind = GenericObject);
template<XDRMode mode>
bool
XDRLazyScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enclosingScript,
HandleFunction fun, MutableHandle<LazyScript *> lazy);
/*
* Code any constant value.
*/
@ -1240,6 +1245,7 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
JSObject *sourceObject() const {
return sourceObject_;
}
js::ScriptSourceObject &scriptSourceUnwrap() const;
js::ScriptSource *scriptSource() const;
JSPrincipals *originPrincipals() const { return scriptSource()->originPrincipals(); }
const char *filename() const { return scriptSource()->filename(); }
@ -1607,22 +1613,29 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
uint32_t padding;
#endif
// Assorted bits that should really be in ScriptSourceObject.
uint32_t version_ : 8;
struct PackedView {
// Assorted bits that should really be in ScriptSourceObject.
uint32_t version : 8;
uint32_t numFreeVariables_ : 24;
uint32_t numInnerFunctions_ : 23;
uint32_t numFreeVariables : 24;
uint32_t numInnerFunctions : 23;
uint32_t generatorKindBits_:2;
uint32_t generatorKindBits : 2;
// N.B. These are booleans but need to be uint32_t to pack correctly on MSVC.
uint32_t strict_ : 1;
uint32_t bindingsAccessedDynamically_ : 1;
uint32_t hasDebuggerStatement_ : 1;
uint32_t directlyInsideEval_:1;
uint32_t usesArgumentsAndApply_:1;
uint32_t hasBeenCloned_:1;
uint32_t treatAsRunOnce_:1;
// N.B. These are booleans but need to be uint32_t to pack correctly on MSVC.
uint32_t strict : 1;
uint32_t bindingsAccessedDynamically : 1;
uint32_t hasDebuggerStatement : 1;
uint32_t directlyInsideEval : 1;
uint32_t usesArgumentsAndApply : 1;
uint32_t hasBeenCloned : 1;
uint32_t treatAsRunOnce : 1;
};
union {
PackedView p_;
uint64_t packedFields_;
};
// Source location for the script.
uint32_t begin_;
@ -1630,16 +1643,34 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
uint32_t lineno_;
uint32_t column_;
LazyScript(JSFunction *fun, void *table,
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
LazyScript(JSFunction *fun, void *table, uint64_t packedFields,
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);
// Create a LazyScript without initializing the freeVariables and the
// innerFunctions. To be GC-safe, the caller must initialize both vectors
// with valid atoms and functions.
static LazyScript *CreateRaw(ExclusiveContext *cx, HandleFunction fun,
uint64_t packedData, uint32_t begin, uint32_t end,
uint32_t lineno, uint32_t column);
public:
// Create a LazyScript without initializing the freeVariables and the
// innerFunctions. To be GC-safe, the caller must initialize both vectors
// with valid atoms and functions.
static LazyScript *CreateRaw(ExclusiveContext *cx, HandleFunction fun,
uint32_t numFreeVariables, uint32_t numInnerFunctions,
JSVersion version, uint32_t begin, uint32_t end,
uint32_t lineno, uint32_t column);
// Create a LazyScript and initialize the freeVariables and the
// innerFunctions with dummy values to be replaced in a later initialization
// phase.
static LazyScript *Create(ExclusiveContext *cx, HandleFunction fun,
uint32_t numFreeVariables, uint32_t numInnerFunctions,
JSVersion version, uint32_t begin, uint32_t end,
uint64_t packedData, uint32_t begin, uint32_t end,
uint32_t lineno, uint32_t column);
void initRuntimeFields(uint64_t packedFields);
inline JSFunction *functionDelazifying(JSContext *cx) const;
JSFunction *functionNonDelazifying() const {
return function_;
@ -1663,26 +1694,26 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
}
JSVersion version() const {
JS_STATIC_ASSERT(JSVERSION_UNKNOWN == -1);
return (version_ == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(version_);
return (p_.version == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(p_.version);
}
void setParent(JSObject *enclosingScope, ScriptSourceObject *sourceObject);
uint32_t numFreeVariables() const {
return numFreeVariables_;
return p_.numFreeVariables;
}
HeapPtrAtom *freeVariables() {
return (HeapPtrAtom *)table_;
}
uint32_t numInnerFunctions() const {
return numInnerFunctions_;
return p_.numInnerFunctions;
}
HeapPtrFunction *innerFunctions() {
return (HeapPtrFunction *)&freeVariables()[numFreeVariables()];
}
GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
GeneratorKind generatorKind() const { return GeneratorKindFromBits(p_.generatorKindBits); }
bool isGenerator() const { return generatorKind() != NotGenerator; }
@ -1696,56 +1727,56 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
JS_ASSERT(!isGenerator());
// Legacy generators cannot currently be lazy.
JS_ASSERT(kind != LegacyGenerator);
generatorKindBits_ = GeneratorKindAsBits(kind);
p_.generatorKindBits = GeneratorKindAsBits(kind);
}
bool strict() const {
return strict_;
return p_.strict;
}
void setStrict() {
strict_ = true;
p_.strict = true;
}
bool bindingsAccessedDynamically() const {
return bindingsAccessedDynamically_;
return p_.bindingsAccessedDynamically;
}
void setBindingsAccessedDynamically() {
bindingsAccessedDynamically_ = true;
p_.bindingsAccessedDynamically = true;
}
bool hasDebuggerStatement() const {
return hasDebuggerStatement_;
return p_.hasDebuggerStatement;
}
void setHasDebuggerStatement() {
hasDebuggerStatement_ = true;
p_.hasDebuggerStatement = true;
}
bool directlyInsideEval() const {
return directlyInsideEval_;
return p_.directlyInsideEval;
}
void setDirectlyInsideEval() {
directlyInsideEval_ = true;
p_.directlyInsideEval = true;
}
bool usesArgumentsAndApply() const {
return usesArgumentsAndApply_;
return p_.usesArgumentsAndApply;
}
void setUsesArgumentsAndApply() {
usesArgumentsAndApply_ = true;
p_.usesArgumentsAndApply = true;
}
bool hasBeenCloned() const {
return hasBeenCloned_;
return p_.hasBeenCloned;
}
void setHasBeenCloned() {
hasBeenCloned_ = true;
p_.hasBeenCloned = true;
}
bool treatAsRunOnce() const {
return treatAsRunOnce_;
return p_.treatAsRunOnce;
}
void setTreatAsRunOnce() {
treatAsRunOnce_ = true;
p_.treatAsRunOnce = true;
}
ScriptSource *source() const {
@ -1775,6 +1806,10 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
{
return mallocSizeOf(table_);
}
uint64_t packedFields() const {
return packedFields_;
}
};
/* If this fails, add/remove padding within LazyScript. */