Bug 1160182 - Handle extended functions in CreateLazyScriptsForCompartment. r=shu, a=lizzard
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 21 May 2015 17:57:56 +0200
changeset 267533 c0466694b30dde74b51020875b644d934c793acc
parent 267532 5192768092c0be5c40869959e9632e176410cc58
child 267534 7a2b9af5a7c633c5523466568dfe8fd43d644f6d
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu, lizzard
bugs1160182
milestone39.0
Bug 1160182 - Handle extended functions in CreateLazyScriptsForCompartment. r=shu, a=lizzard
js/src/builtin/TestingFunctions.cpp
js/src/jit-test/tests/debug/bug1160182.js
js/src/jscompartment.cpp
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -406,17 +406,17 @@ IsLazyFunction(JSContext* cx, unsigned a
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (args.length() != 1) {
         JS_ReportError(cx, "The function takes exactly one argument.");
         return false;
     }
     if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
         JS_ReportError(cx, "The first argument should be a function.");
-        return true;
+        return false;
     }
     args.rval().setBoolean(args[0].toObject().as<JSFunction>().isInterpretedLazy());
     return true;
 }
 
 static bool
 IsRelazifiableFunction(JSContext* cx, unsigned argc, Value* vp)
 {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug1160182.js
@@ -0,0 +1,11 @@
+var g = newGlobal();
+g.eval("(" + function() {
+    var o = {get x() {}};
+    this.method = Object.getOwnPropertyDescriptor(o, "x").get;
+    assertEq(isLazyFunction(method), true);
+} + ")()");
+var dbg = new Debugger();
+var gw = dbg.addDebuggee(g);
+var scripts = dbg.findScripts();
+var methodv = gw.makeDebuggeeValue(g.method);
+assertEq(scripts.indexOf(methodv.script) != -1, true);
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -735,32 +735,25 @@ AddInnerLazyFunctionsFromScript(JSScript
             if (!lazyFunctions.append(obj))
                 return false;
         }
     }
     return true;
 }
 
 static bool
-CreateLazyScriptsForCompartment(JSContext* cx)
+AddLazyFunctionsForCompartment(JSContext* cx, AutoObjectVector& lazyFunctions, AllocKind kind)
 {
-    AutoObjectVector lazyFunctions(cx);
-
     // Find all live root lazy functions in the compartment: those which
     // have not been compiled, which have a source object, indicating that
     // they have a parent, and which do not have an uncompiled enclosing
     // script. The last condition is so that we don't compile lazy scripts
     // whose enclosing scripts failed to compile, indicating that the lazy
     // script did not escape the script.
-    //
-    // Note that while we ideally iterate over LazyScripts, LazyScripts do not
-    // currently stand in 1-1 relation with JSScripts; JSFunctions with the
-    // same LazyScript may create different JSScripts due to relazification of
-    // clones. See bug 1105306.
-    for (gc::ZoneCellIter i(cx->zone(), JSFunction::FinalizeKind); !i.done(); i.next()) {
+    for (gc::ZoneCellIter i(cx->zone(), kind); !i.done(); i.next()) {
         JSObject* obj = i.get<JSObject>();
 
         // Sweeping is incremental; take care to not delazify functions that
         // are about to be finalized. GC things referenced by objects that are
         // about to be finalized (e.g., in slots) may already be freed.
         if (gc::IsObjectAboutToBeFinalized(&obj) ||
             obj->compartment() != cx->compartment() ||
             !obj->is<JSFunction>())
@@ -775,16 +768,32 @@ CreateLazyScriptsForCompartment(JSContex
                 !lazy->hasUncompiledEnclosingScript())
             {
                 if (!lazyFunctions.append(fun))
                     return false;
             }
         }
     }
 
+    return true;
+}
+
+static bool
+CreateLazyScriptsForCompartment(JSContext* cx)
+{
+    AutoObjectVector lazyFunctions(cx);
+
+    if (!AddLazyFunctionsForCompartment(cx, lazyFunctions, JSFunction::FinalizeKind))
+        return false;
+
+    // Methods, for instance {get method() {}}, are extended functions that can
+    // be relazified, so we need to handle those as well.
+    if (!AddLazyFunctionsForCompartment(cx, lazyFunctions, JSFunction::ExtendedFinalizeKind))
+        return false;
+
     // Create scripts for each lazy function, updating the list of functions to
     // process with any newly exposed inner functions in created scripts.
     // A function cannot be delazified until its outer script exists.
     for (size_t i = 0; i < lazyFunctions.length(); i++) {
         JSFunction* fun = &lazyFunctions[i]->as<JSFunction>();
 
         // lazyFunctions may have been populated with multiple functions for
         // a lazy script.