author | Jan de Mooij <jdemooij@mozilla.com> |
Fri, 11 Mar 2016 15:21:16 +0100 | |
changeset 288282 | f97f2238854e0463b9fae36f782d7baf5db512cc |
parent 288281 | 9c01878c2e8ad29031357f7be67e5f95f417dac6 |
child 288283 | 827864e6dceb86226326104a66720b61c7485601 |
push id | 30079 |
push user | ryanvm@gmail.com |
push date | Sat, 12 Mar 2016 20:24:19 +0000 |
treeherder | mozilla-central@d1d47ba19ce9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bhackett |
bugs | 1227035 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -827,18 +827,18 @@ frontend::CompileLazyFunction(JSContext* Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options, sourceObject, lazy->begin(), lazy->end())); if (!script) return false; script->bindings = pn->pn_funbox->bindings; - if (lazy->usesArgumentsApplyAndThis()) - script->setUsesArgumentsApplyAndThis(); + if (lazy->isLikelyConstructorWrapper()) + script->setLikelyConstructorWrapper(); if (lazy->hasBeenCloned()) script->setHasBeenCloned(); /* * We just pass false for insideNonGlobalEval and insideEval, because we * don't actually know whether we are or not. The only consumer of those * booleans is TryConvertFreeName, and it has special machinery to avoid * doing bad things when a lazy function is inside eval.
--- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -6427,18 +6427,18 @@ BytecodeEmitter::emitFunction(ParseNode* insideNonGlobalEval, lineNum, emitterMode); if (!bce2.init()) return false; /* We measured the max scope depth when we parsed the function. */ if (!bce2.emitFunctionScript(pn->pn_body)) return false; - if (funbox->usesArguments && funbox->usesApply && funbox->usesThis) - script->setUsesArgumentsApplyAndThis(); + if (funbox->isLikelyConstructorWrapper()) + script->setLikelyConstructorWrapper(); } if (outersc->isFunctionBox()) outersc->asFunctionBox()->function()->nonLazyScript()->setHasInnerFunctions(true); } else { MOZ_ASSERT(IsAsmJSModule(fun)); } /* Make the function object a literal in the outer script's pool. */
--- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -783,16 +783,17 @@ FunctionBox::FunctionBox(ExclusiveContex inGenexpLambda(false), hasDestructuringArgs(false), useAsm(false), insideUseAsm(outerpc && outerpc->useAsmOrInsideUseAsm()), wasEmitted(false), usesArguments(false), usesApply(false), usesThis(false), + usesReturn(false), funCxFlags() { // Functions created at parse time may be set singleton after parsing and // baked into JIT code, so they must be allocated tenured. They are held by // the JSScript so cannot be collected during a minor GC anyway. MOZ_ASSERT(fun->isTenured()); } @@ -2879,18 +2880,18 @@ Parser<SyntaxParseHandler>::finishFuncti HeapPtrFunction* innerFunctions = lazy->innerFunctions(); for (size_t i = 0; i < numInnerFunctions; i++) innerFunctions[i].init(pc->innerFunctions[i]); if (pc->sc->strict()) lazy->setStrict(); lazy->setGeneratorKind(funbox->generatorKind()); - if (funbox->usesArguments && funbox->usesApply && funbox->usesThis) - lazy->setUsesArgumentsApplyAndThis(); + if (funbox->isLikelyConstructorWrapper()) + lazy->setLikelyConstructorWrapper(); if (funbox->isDerivedClassConstructor()) lazy->setIsDerivedClassConstructor(); if (funbox->needsHomeObject()) lazy->setNeedsHomeObject(); PropagateTransitiveParseFlags(funbox, lazy); fun->initLazyScript(lazy); return true; @@ -6504,16 +6505,17 @@ Parser<ParseHandler>::breakStatement(Yie template <typename ParseHandler> typename ParseHandler::Node Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling) { MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_RETURN)); uint32_t begin = pos().begin; MOZ_ASSERT(pc->sc->isFunctionBox()); + pc->sc->asFunctionBox()->usesReturn = true; // Parse an optional operand. // // This is ugly, but we don't want to require a semicolon. Node exprNode; TokenKind tt = TOK_EOF; if (!tokenStream.peekTokenSameLine(&tt, TokenStream::Operand)) return null();
--- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -325,29 +325,34 @@ class FunctionBox : public ObjectBox, pu bool useAsm:1; /* see useAsmOrInsideUseAsm */ bool insideUseAsm:1; /* see useAsmOrInsideUseAsm */ bool wasEmitted:1; /* Bytecode has been emitted for this function. */ // Fields for use in heuristics. bool usesArguments:1; /* contains a free use of 'arguments' */ bool usesApply:1; /* contains an f.apply() call */ bool usesThis:1; /* contains 'this' */ + bool usesReturn:1; /* contains a 'return' statement */ FunctionContextFlags funCxFlags; template <typename ParseHandler> FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun, JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc, Directives directives, bool extraWarnings, GeneratorKind generatorKind); ObjectBox* toObjectBox() override { return this; } JSFunction* function() const { return &object->as<JSFunction>(); } JSObject* staticScope() const override { return function(); } JSObject* enclosingStaticScope() const { return enclosingStaticScope_; } + bool isLikelyConstructorWrapper() const { + return usesArguments && usesApply && usesThis && !usesReturn; + } + GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); } bool isGenerator() const { return generatorKind() != NotGenerator; } bool isLegacyGenerator() const { return generatorKind() == LegacyGenerator; } bool isStarGenerator() const { return generatorKind() == StarGenerator; } bool isArrow() const { return function()->isArrow(); } void setGeneratorKind(GeneratorKind kind) { // A generator kind can be set at initialization, or when "yield" is
--- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -4350,17 +4350,17 @@ LazyScript::CreateRaw(ExclusiveContext* p.version = version; p.numFreeVariables = numFreeVariables; p.numInnerFunctions = numInnerFunctions; p.generatorKindBits = GeneratorKindAsBits(NotGenerator); p.strict = false; p.bindingsAccessedDynamically = false; p.hasDebuggerStatement = false; p.hasDirectEval = false; - p.usesArgumentsApplyAndThis = false; + p.isLikelyConstructorWrapper = false; p.isDerivedClassConstructor = false; p.needsHomeObject = false; LazyScript* res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column); MOZ_ASSERT_IF(res, res->version() == version); return res; }
--- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1144,17 +1144,17 @@ class JSScript : public js::gc::TenuredC // Script came from eval(), and is still active. bool isActiveEval_:1; // Script came from eval(), and is in eval cache. bool isCachedEval_:1; // 'this', 'arguments' and f.apply() are used. This is likely to be a wrapper. - bool usesArgumentsApplyAndThis_:1; + bool isLikelyConstructorWrapper_:1; // IonMonkey compilation hints. bool failedBoundsCheck_:1; /* script has had hoisted bounds checks fail */ bool failedShapeGuard_:1; /* script has had hoisted shape guard fail */ bool hadFrequentBailouts_:1; bool hadOverflowBailout_:1; bool uninlineable_:1; /* explicitly marked as uninlineable */ @@ -1407,20 +1407,20 @@ class JSScript : public js::gc::TenuredC void uncacheForEval() { MOZ_ASSERT(isCachedEval() && !isActiveEval()); isCachedEval_ = false; isActiveEval_ = true; } void setActiveEval() { isActiveEval_ = true; } - bool usesArgumentsApplyAndThis() const { - return usesArgumentsApplyAndThis_; + bool isLikelyConstructorWrapper() const { + return isLikelyConstructorWrapper_; } - void setUsesArgumentsApplyAndThis() { usesArgumentsApplyAndThis_ = true; } + void setLikelyConstructorWrapper() { isLikelyConstructorWrapper_ = true; } bool isGeneratorExp() const { return isGeneratorExp_; } bool failedBoundsCheck() const { return failedBoundsCheck_; } bool failedShapeGuard() const { return failedShapeGuard_; @@ -2174,17 +2174,17 @@ class LazyScript : public gc::TenuredCel // N.B. These are booleans but need to be uint32_t to pack correctly on MSVC. // If you add another boolean here, make sure to initialze it in // LazyScript::CreateRaw(). uint32_t strict : 1; uint32_t bindingsAccessedDynamically : 1; uint32_t hasDebuggerStatement : 1; uint32_t hasDirectEval : 1; - uint32_t usesArgumentsApplyAndThis : 1; + uint32_t isLikelyConstructorWrapper : 1; uint32_t hasBeenCloned : 1; uint32_t treatAsRunOnce : 1; uint32_t isDerivedClassConstructor : 1; uint32_t needsHomeObject : 1; }; union { PackedView p_; @@ -2328,21 +2328,21 @@ class LazyScript : public gc::TenuredCel bool hasDirectEval() const { return p_.hasDirectEval; } void setHasDirectEval() { p_.hasDirectEval = true; } - bool usesArgumentsApplyAndThis() const { - return p_.usesArgumentsApplyAndThis; + bool isLikelyConstructorWrapper() const { + return p_.isLikelyConstructorWrapper; } - void setUsesArgumentsApplyAndThis() { - p_.usesArgumentsApplyAndThis = true; + void setLikelyConstructorWrapper() { + p_.isLikelyConstructorWrapper = true; } bool hasBeenCloned() const { return p_.hasBeenCloned; } void setHasBeenCloned() { p_.hasBeenCloned = true; }
--- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -145,22 +145,22 @@ ObjectGroup::useSingletonForClone(JSFunc * initialize method. We capture this, along with similar cases, by looking * for short scripts which use both .apply and arguments. For such scripts, * whenever creating a new instance of the function we both give that * instance a singleton type and clone the underlying script. */ uint32_t begin, end; if (fun->hasScript()) { - if (!fun->nonLazyScript()->usesArgumentsApplyAndThis()) + if (!fun->nonLazyScript()->isLikelyConstructorWrapper()) return false; begin = fun->nonLazyScript()->sourceStart(); end = fun->nonLazyScript()->sourceEnd(); } else { - if (!fun->lazyScript()->usesArgumentsApplyAndThis()) + if (!fun->lazyScript()->isLikelyConstructorWrapper()) return false; begin = fun->lazyScript()->begin(); end = fun->lazyScript()->end(); } return end - begin <= 100; }