Bug 1330373 - Capture JSScript::lazyScript field when encoding bytecode incrementally. r=shu
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Fri, 16 Jun 2017 12:31:54 +0000
changeset 413120 e28dbb88b4c43f180a13b08e4236cc01c92ac900
parent 413119 4b1ea65170bbf4031fc6ee44a29d47a84afe77d1
child 413121 231bd9d90fb3213eed9ac350116cc352e626b970
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1330373
milestone56.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 1330373 - Capture JSScript::lazyScript field when encoding bytecode incrementally. r=shu
js/src/frontend/BytecodeCompiler.cpp
js/src/jit-test/tests/xdr/relazify.js
js/src/jsfun.cpp
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -707,23 +707,16 @@ frontend::CompileLazyFunction(JSContext*
         return false;
 
     if (!bce.emitFunctionScript(pn->pn_body))
         return false;
 
     if (!NameFunctions(cx, pn))
         return false;
 
-    // XDR the newly delazified function.
-    if (script->scriptSource()->hasEncoder() &&
-        !script->scriptSource()->xdrEncodeFunction(cx, fun, sourceObject))
-    {
-        return false;
-    }
-
     return true;
 }
 
 bool
 frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun,
                                     const ReadOnlyCompileOptions& options,
                                     JS::SourceBufferHolder& srcBuf,
                                     const Maybe<uint32_t>& parameterListEnd,
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/xdr/relazify.js
@@ -0,0 +1,29 @@
+load(libdir + 'bytecode-cache.js');
+var test = "";
+gczeal(0);
+
+// Check that a GC can relazify decoded functions.
+//
+// Generations 0 and 3 are executed from the source, thus f is not executed yet.
+// Generations 1 and 2 are decoded, thus we recorded the delazified f function.
+test = `
+  function f() { return 1; };
+  assertEq(isLazyFunction(f), generation == 0 || generation == 3);
+  f();
+  expect = isRelazifiableFunction(f);
+  assertEq(isLazyFunction(f), false);
+`;
+evalWithCache(test, {
+  checkAfter: function (ctx) {
+    gc(ctx.global.f, "shrinking"); // relazify f, if possible.
+    evaluate("assertEq(isLazyFunction(f), expect);", ctx);
+  }
+});
+
+evalWithCache(test, {
+  incremental: true,
+  checkAfter: function (ctx) {
+    gc(ctx.global.f, "shrinking"); // relazify f, if possible.
+    evaluate("assertEq(isLazyFunction(f), expect);", ctx);
+  }
+});
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1562,16 +1562,24 @@ JSFunction::createScriptForLazilyInterpr
             LazyScriptCache::Lookup lookup(cx, lazy);
             cx->caches().lazyScriptCache.insert(lookup, script);
 
             // Remember the lazy script on the compiled script, so it can be
             // stored on the function again in case of re-lazification.
             // Only functions without inner functions are re-lazified.
             script->setLazyScript(lazy);
         }
+
+        // XDR the newly delazified function.
+        if (script->scriptSource()->hasEncoder()) {
+            RootedScriptSource sourceObject(cx, lazy->sourceObject());
+            if (!script->scriptSource()->xdrEncodeFunction(cx, fun, sourceObject))
+                return false;
+        }
+
         return true;
     }
 
     /* Lazily cloned self-hosted script. */
     MOZ_ASSERT(fun->isSelfHostedBuiltin());
     RootedAtom funAtom(cx, &fun->getExtendedSlot(LAZY_FUNCTION_NAME_SLOT).toString()->asAtom());
     if (!funAtom)
         return false;