зеркало из https://github.com/mozilla/gecko-dev.git
Bug 762473 - Don't apply non-reentrant-closure optimization when the scope is extensible (r=dvander)
--HG-- extra : rebase_source : e20cc5157607b72d8ecdd1fc4560373e0ad7060a
This commit is contained in:
Родитель
20cc12b099
Коммит
2271b34bbd
|
@ -34,6 +34,13 @@ MarkInnerAndOuterFunctions(JSContext *cx, JSScript* script_)
|
||||||
JSScript *outer = worklist.back();
|
JSScript *outer = worklist.back();
|
||||||
worklist.popBack();
|
worklist.popBack();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If outer has an extensible scope, its slots may be resized which
|
||||||
|
* will invalidate nesting->varArray/argArray.
|
||||||
|
*/
|
||||||
|
if (outer->funHasExtensibleScope)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (outer->hasObjects()) {
|
if (outer->hasObjects()) {
|
||||||
ObjectArray *arr = outer->objects();
|
ObjectArray *arr = outer->objects();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
function f(i) {
|
||||||
|
var a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a16,a17;
|
||||||
|
var b = true;
|
||||||
|
if (b)
|
||||||
|
function f1() {}
|
||||||
|
if (b)
|
||||||
|
function f2() {}
|
||||||
|
if (b)
|
||||||
|
function f3() {}
|
||||||
|
if (b)
|
||||||
|
function f4() {}
|
||||||
|
if (b)
|
||||||
|
function f5() {}
|
||||||
|
if (b)
|
||||||
|
function f6() {}
|
||||||
|
if (b)
|
||||||
|
function f7() {}
|
||||||
|
if (b)
|
||||||
|
function f8() {}
|
||||||
|
if (b)
|
||||||
|
function f9() {}
|
||||||
|
if (b)
|
||||||
|
function f10() {}
|
||||||
|
if (b)
|
||||||
|
function f11() {}
|
||||||
|
if (b)
|
||||||
|
function f12() {}
|
||||||
|
if (b)
|
||||||
|
function f13() {}
|
||||||
|
if (b)
|
||||||
|
function f14() {}
|
||||||
|
if (b)
|
||||||
|
function f15() {}
|
||||||
|
if (b)
|
||||||
|
function f16() {}
|
||||||
|
if (b)
|
||||||
|
function f17() {}
|
||||||
|
|
||||||
|
a1 = i;
|
||||||
|
|
||||||
|
function f() {
|
||||||
|
return a1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 100; ++i)
|
||||||
|
assertEq(f(i), i);
|
|
@ -5259,6 +5259,8 @@ NestingPrologue(JSContext *cx, StackFrame *fp)
|
||||||
MarkTypeObjectFlags(cx, fp->fun(), OBJECT_FLAG_REENTRANT_FUNCTION);
|
MarkTypeObjectFlags(cx, fp->fun(), OBJECT_FLAG_REENTRANT_FUNCTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extensibility guards in the frontend guarantee the slots won't move. */
|
||||||
|
JS_ASSERT(!script->funHasExtensibleScope);
|
||||||
nesting->activeCall = &fp->callObj();
|
nesting->activeCall = &fp->callObj();
|
||||||
nesting->argArray = Valueify(nesting->activeCall->argArray());
|
nesting->argArray = Valueify(nesting->activeCall->argArray());
|
||||||
nesting->varArray = Valueify(nesting->activeCall->varArray());
|
nesting->varArray = Valueify(nesting->activeCall->varArray());
|
||||||
|
|
|
@ -374,6 +374,7 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
||||||
SavedCallerFun,
|
SavedCallerFun,
|
||||||
StrictModeCode,
|
StrictModeCode,
|
||||||
ContainsDynamicNameAccess,
|
ContainsDynamicNameAccess,
|
||||||
|
FunHasExtensibleScope,
|
||||||
ArgumentsHasLocalBinding,
|
ArgumentsHasLocalBinding,
|
||||||
NeedsArgsObj,
|
NeedsArgsObj,
|
||||||
OwnFilename,
|
OwnFilename,
|
||||||
|
@ -529,6 +530,8 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
||||||
scriptBits |= (1 << StrictModeCode);
|
scriptBits |= (1 << StrictModeCode);
|
||||||
if (script->bindingsAccessedDynamically)
|
if (script->bindingsAccessedDynamically)
|
||||||
scriptBits |= (1 << ContainsDynamicNameAccess);
|
scriptBits |= (1 << ContainsDynamicNameAccess);
|
||||||
|
if (script->funHasExtensibleScope)
|
||||||
|
scriptBits |= (1 << FunHasExtensibleScope);
|
||||||
if (script->argumentsHasLocalBinding())
|
if (script->argumentsHasLocalBinding())
|
||||||
scriptBits |= (1 << ArgumentsHasLocalBinding);
|
scriptBits |= (1 << ArgumentsHasLocalBinding);
|
||||||
if (script->analyzedArgsUsage() && script->needsArgsObj())
|
if (script->analyzedArgsUsage() && script->needsArgsObj())
|
||||||
|
@ -602,6 +605,8 @@ js::XDRScript(XDRState<mode> *xdr, JSScript **scriptp, JSScript *parentScript)
|
||||||
script->strictModeCode = true;
|
script->strictModeCode = true;
|
||||||
if (scriptBits & (1 << ContainsDynamicNameAccess))
|
if (scriptBits & (1 << ContainsDynamicNameAccess))
|
||||||
script->bindingsAccessedDynamically = true;
|
script->bindingsAccessedDynamically = true;
|
||||||
|
if (scriptBits & (1 << FunHasExtensibleScope))
|
||||||
|
script->funHasExtensibleScope = true;
|
||||||
if (scriptBits & (1 << ArgumentsHasLocalBinding)) {
|
if (scriptBits & (1 << ArgumentsHasLocalBinding)) {
|
||||||
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
|
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
|
||||||
unsigned local;
|
unsigned local;
|
||||||
|
@ -1313,6 +1318,7 @@ JSScript::NewScriptFromEmitter(JSContext *cx, BytecodeEmitter *bce)
|
||||||
script->savedCallerFun = true;
|
script->savedCallerFun = true;
|
||||||
}
|
}
|
||||||
script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
|
script->bindingsAccessedDynamically = bce->sc->bindingsAccessedDynamically();
|
||||||
|
script->funHasExtensibleScope = bce->sc->funHasExtensibleScope();
|
||||||
script->hasSingletons = bce->hasSingletons;
|
script->hasSingletons = bce->hasSingletons;
|
||||||
#ifdef JS_METHODJIT
|
#ifdef JS_METHODJIT
|
||||||
if (cx->compartment->debugMode())
|
if (cx->compartment->debugMode())
|
||||||
|
@ -1820,6 +1826,7 @@ js::CloneScript(JSContext *cx, HandleScript src)
|
||||||
dst->strictModeCode = src->strictModeCode;
|
dst->strictModeCode = src->strictModeCode;
|
||||||
dst->compileAndGo = src->compileAndGo;
|
dst->compileAndGo = src->compileAndGo;
|
||||||
dst->bindingsAccessedDynamically = src->bindingsAccessedDynamically;
|
dst->bindingsAccessedDynamically = src->bindingsAccessedDynamically;
|
||||||
|
dst->funHasExtensibleScope = src->funHasExtensibleScope;
|
||||||
dst->hasSingletons = src->hasSingletons;
|
dst->hasSingletons = src->hasSingletons;
|
||||||
dst->isGenerator = src->isGenerator;
|
dst->isGenerator = src->isGenerator;
|
||||||
|
|
||||||
|
|
|
@ -526,6 +526,7 @@ struct JSScript : public js::gc::Cell
|
||||||
bool strictModeCode:1; /* code is in strict mode */
|
bool strictModeCode:1; /* code is in strict mode */
|
||||||
bool compileAndGo:1; /* see Parser::compileAndGo */
|
bool compileAndGo:1; /* see Parser::compileAndGo */
|
||||||
bool bindingsAccessedDynamically:1; /* see ContextFlags' field of the same name */
|
bool bindingsAccessedDynamically:1; /* see ContextFlags' field of the same name */
|
||||||
|
bool funHasExtensibleScope:1; /* see ContextFlags' field of the same name */
|
||||||
bool warnedAboutTwoArgumentEval:1; /* have warned about use of
|
bool warnedAboutTwoArgumentEval:1; /* have warned about use of
|
||||||
obsolete eval(s, o) in
|
obsolete eval(s, o) in
|
||||||
this script */
|
this script */
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace js {
|
||||||
* and saved versions. If deserialization fails, the data should be
|
* and saved versions. If deserialization fails, the data should be
|
||||||
* invalidated if possible.
|
* invalidated if possible.
|
||||||
*/
|
*/
|
||||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 117);
|
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 118);
|
||||||
|
|
||||||
class XDRBuffer {
|
class XDRBuffer {
|
||||||
public:
|
public:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче