Bug 1505181 - Use canonical function in TypeNewScript::rollbackPartiallyInitializedObjects. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 07 Nov 2018 21:12:45 +0100
changeset 445988 2599b449d317ad862d059fdc5fe0d97e9caa15b2
parent 445987 ae382e944ea805fb71443ed02fb399044836809a
child 445989 9ee2e7c7fa1622e929ac237a76bf6fe55e4cdc28
child 446033 84b9cfcef11a337689bfb15944cf480e3cec415a
push id109810
push userjandemooij@gmail.com
push dateTue, 13 Nov 2018 11:57:17 +0000
treeherdermozilla-inbound@2599b449d317 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1505181
milestone65.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
Bug 1505181 - Use canonical function in TypeNewScript::rollbackPartiallyInitializedObjects. r=bhackett Differential Revision: https://phabricator.services.mozilla.com/D11224
js/src/vm/JSFunction.h
js/src/vm/ObjectGroup.cpp
js/src/vm/TypeInference.cpp
--- a/js/src/vm/JSFunction.h
+++ b/js/src/vm/JSFunction.h
@@ -570,16 +570,29 @@ class JSFunction : public js::NativeObje
             JSScript* script = existingScriptNonDelazifying();
             flags_ &= ~INTERPRETED_LAZY;
             flags_ |= INTERPRETED;
             initScript(script);
         }
         return nonLazyScript();
     }
 
+    // If this is a scripted function, returns its canonical function (the
+    // original function allocated by the frontend). Note that lazy self-hosted
+    // builtins don't have a lazy script so in that case we also return nullptr.
+    JSFunction* maybeCanonicalFunction() const {
+        if (hasScript()) {
+            return nonLazyScript()->functionNonDelazifying();
+        }
+        if (isInterpretedLazy() && !isSelfHostedBuiltin()) {
+            return lazyScript()->functionNonDelazifying();
+        }
+        return nullptr;
+    }
+
     // The state of a JSFunction whose script errored out during bytecode
     // compilation. Such JSFunctions are only reachable via GC iteration and
     // not from script.
     // If u.scripted.s.script_ is non-null, the pointed JSScript is guaranteed
     // to be complete (see the comment above JSScript::initFromFunctionBox
     // callsite in JSScript::fullyInitFromEmitter).
     bool hasUncompletedScript() const {
         MOZ_ASSERT(hasScript());
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -516,24 +516,17 @@ ObjectGroup::defaultNewGroup(JSContext* 
     // unboxed plain object.
     MOZ_ASSERT_IF(!clasp, !!associated);
 
     if (associated && !associated->is<TypeDescr>()) {
         MOZ_ASSERT(!clasp);
         if (associated->is<JSFunction>()) {
 
             // Canonicalize new functions to use the original one associated with its script.
-            JSFunction* fun = &associated->as<JSFunction>();
-            if (fun->hasScript()) {
-                associated = fun->nonLazyScript()->functionNonDelazifying();
-            } else if (fun->isInterpretedLazy() && !fun->isSelfHostedBuiltin()) {
-                associated = fun->lazyScript()->functionNonDelazifying();
-            } else {
-                associated = nullptr;
-            }
+            associated = associated->as<JSFunction>().maybeCanonicalFunction();
 
             // If we have previously cleared the 'new' script information for this
             // function, don't try to construct another one.
             if (associated && associated->as<JSFunction>().wasNewScriptCleared()) {
                 associated = nullptr;
             }
 
         } else {
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -4020,16 +4020,20 @@ PreliminaryObjectArrayWithTemplate::mayb
 /* static */ bool
 TypeNewScript::make(JSContext* cx, ObjectGroup* group, JSFunction* fun)
 {
     AutoSweepObjectGroup sweep(group);
     MOZ_ASSERT(cx->zone()->types.activeAnalysis);
     MOZ_ASSERT(!group->newScript(sweep));
     MOZ_ASSERT(!group->maybeUnboxedLayout(sweep));
 
+    // rollbackPartiallyInitializedObjects expects function_ to be
+    // canonicalized.
+    MOZ_ASSERT(fun->maybeCanonicalFunction() == fun);
+
     if (group->unknownProperties(sweep)) {
         return true;
     }
 
     auto newScript = cx->make_unique<TypeNewScript>();
     if (!newScript) {
         return false;
     }
@@ -4399,17 +4403,23 @@ TypeNewScript::rollbackPartiallyInitiali
     for (AllScriptFramesIter iter(cx); !iter.done(); ++iter) {
         {
             AutoEnterOOMUnsafeRegion oomUnsafe;
             if (!pcOffsets.append(iter.script()->pcToOffset(iter.pc()))) {
                 oomUnsafe.crash("rollbackPartiallyInitializedObjects");
             }
         }
 
-        if (!iter.isConstructing() || !iter.matchCallee(cx, function)) {
+        if (!iter.isConstructing()) {
+            continue;
+        }
+
+        MOZ_ASSERT(iter.calleeTemplate()->maybeCanonicalFunction());
+
+        if (iter.calleeTemplate()->maybeCanonicalFunction() != function) {
             continue;
         }
 
         // Derived class constructors initialize their this-binding later and
         // we shouldn't run the definite properties analysis on them.
         MOZ_ASSERT(!iter.script()->isDerivedClassConstructor());
 
         Value thisv = iter.thisArgument(cx);