Bug 1491336 - Do not support delazification of functions which is optimized out. r=jorendorff
authorTooru Fujisawa <arai_a@mac.com>
Fri, 05 Oct 2018 21:21:38 +0900
changeset 439790 bc381243c490f6e5b54a65734af5504e598e129d
parent 439789 6d525f6dee9f9caeeed3e4bed25f78b641177e46
child 439791 aebbddba77c67a989ad25713e5536477b044c1ce
push id34789
push userdluca@mozilla.com
push dateFri, 05 Oct 2018 15:16:16 +0000
treeherdermozilla-central@97208b5251d7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1491336
milestone64.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 1491336 - Do not support delazification of functions which is optimized out. r=jorendorff
js/src/jit-test/tests/debug/Debugger-findScripts-optimized-out.js
js/src/js.msg
js/src/vm/Debugger.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Debugger-findScripts-optimized-out.js
@@ -0,0 +1,31 @@
+// Accessing Debugger.Script's properties which triggers delazification can
+// fail if the function for the script is optimized out.
+// It shouldn't crash but just throw an error.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal();
+var dbg = new Debugger(g);
+g.eval(`
+function enclosing() {
+    (function g1() {});
+    (function* g2() {});
+    (async function g3() {});
+    (async function* g4() {});
+    () => {};
+    async () => {};
+}
+`);
+
+for (const s of dbg.findScripts()) {
+    if (!s.displayName) {
+        continue;
+    }
+
+    try {
+        s.lineCount;  // don't assert
+    } catch (exc) {
+        // If that didn't throw, it's fine. If it did, check the message.
+        assertEq(exc.message, "function is optimized out");
+    }
+}
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -477,16 +477,17 @@ MSG_DEF(JSMSG_DEBUG_LOOP,              0
 MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGEE,      2, JSEXN_ERR, "{0} is not a debuggee {1}")
 MSG_DEF(JSMSG_DEBUG_NOT_DEBUGGING,     0, JSEXN_ERR, "can't set breakpoint: script global is not a debuggee")
 MSG_DEF(JSMSG_DEBUG_NOT_IDLE,          0, JSEXN_ERR, "can't start debugging: a debuggee script is on the stack")
 MSG_DEF(JSMSG_DEBUG_NOT_LIVE,          1, JSEXN_ERR, "{0} is not live")
 MSG_DEF(JSMSG_DEBUG_NO_ENV_OBJECT,     0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
 MSG_DEF(JSMSG_DEBUG_PROTO,             2, JSEXN_TYPEERR, "{0}.prototype is not a valid {1} instance")
 MSG_DEF(JSMSG_DEBUG_WRONG_OWNER,       1, JSEXN_TYPEERR, "{0} belongs to a different Debugger")
 MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT,     1, JSEXN_ERR, "variable `{0}' has been optimized out")
+MSG_DEF(JSMSG_DEBUG_OPTIMIZED_OUT_FUN, 0, JSEXN_ERR, "function is optimized out")
 MSG_DEF(JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED, 0, JSEXN_TYPEERR, "resumption values are disallowed in this hook")
 MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND,0, JSEXN_TYPEERR, "variable not found in environment")
 MSG_DEF(JSMSG_DEBUG_WRAPPER_IN_WAY,    3, JSEXN_TYPEERR, "{0} is {1}{2}a global object, but a direct reference is required")
 MSG_DEF(JSMSG_DEBUGGEE_WOULD_RUN,      2, JSEXN_DEBUGGEEWOULDRUN, "debuggee `{0}:{1}' would run")
 MSG_DEF(JSMSG_NOT_CALLABLE_OR_UNDEFINED, 0, JSEXN_TYPEERR, "value is not a function or undefined")
 MSG_DEF(JSMSG_NOT_TRACKING_ALLOCATIONS, 1, JSEXN_ERR, "Cannot call {0} without setting trackingAllocationSites to true")
 MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track object allocation, because other tools are already doing so")
 MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'")
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5738,16 +5738,24 @@ DelazifyScript(JSContext* cx, Handle<Laz
     // JSFunction::getOrCreateScript requires the enclosing script not to be
     // lazified.
     MOZ_ASSERT(lazyScript->hasEnclosingLazyScript() || lazyScript->hasEnclosingScope());
     if (lazyScript->hasEnclosingLazyScript()) {
         Rooted<LazyScript*> enclosingLazyScript(cx, lazyScript->enclosingLazyScript());
         if (!DelazifyScript(cx, enclosingLazyScript)) {
             return nullptr;
         }
+
+        if (!lazyScript->enclosingScriptHasEverBeenCompiled()) {
+            // It didn't work! Delazifying the enclosing script still didn't
+            // delazify this script. This happens when the function
+            // corresponding to this script was removed by constant folding.
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_OPTIMIZED_OUT_FUN);
+            return nullptr;
+        }
     }
     MOZ_ASSERT(lazyScript->enclosingScriptHasEverBeenCompiled());
 
     RootedFunction fun0(cx, lazyScript->functionNonDelazifying());
     AutoRealm ar(cx, fun0);
     RootedFunction fun(cx, LazyScript::functionDelazifying(cx, lazyScript));
     if (!fun) {
         return nullptr;