Bug 738841 - Fix handling of 'this' in methodjit without TI (r=bhackett)
authorBill McCloskey <wmccloskey@mozilla.com>
Tue, 27 Mar 2012 10:54:04 -0700
changeset 90434 f6b7b4b9f235b18ec544d7477f3fc563fd180dcf
parent 90433 fbe032073e04874ef540a5012e7fb853e8bee309
child 90435 2f79b816b0daea744fb01775d3021d9defdf2813
push id22358
push userkhuey@mozilla.com
push dateWed, 28 Mar 2012 14:41:10 +0000
treeherdermozilla-central@c3fd0768d46a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs738841
milestone14.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 738841 - Fix handling of 'this' in methodjit without TI (r=bhackett)
js/src/jit-test/tests/basic/bug738841.js
js/src/jit-test/tests/basic/bug738846.js
js/src/methodjit/Compiler.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug738841.js
@@ -0,0 +1,49 @@
+try {
+    for (let z = 0; z < 1; ++evalcx("[]", newGlobal("new-compartment"))) {}
+} catch (e) {}
+try {
+    for (y in [schedulegc(58)]) {
+        b
+    }
+} catch (e) {}
+try {
+    e
+} catch (e) {}
+try {
+    (function() {
+        h
+    }())
+} catch (e) {}
+try {
+    (function() {
+        this.m.f = function() {}
+    }())
+} catch (e) {}
+try {
+    t()
+} catch (e) {}
+try {
+    p
+} catch (e) {}
+try {
+    gc()
+    p
+} catch (e) {}
+try {
+    (function() {
+        for (var v of m) {}
+    }())
+} catch (e) {}
+try {
+    m
+} catch (e) {}
+try {
+    var f = function() {
+        {
+            print(new function(q)("", s))
+            let u
+        }
+    };
+    dis(f);
+    f();
+} catch (e) {}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug738846.js
@@ -0,0 +1,49 @@
+try {
+    (function() {
+        var m
+        ArrayBuffer()
+        var _ = t
+        var _2 = []
+    }())
+} catch (e) {}
+try {
+    for (y in [schedulegc(58)]) {
+        m
+    }
+} catch (e) {}
+try {
+    (function() {
+        n.(O)
+    }())
+} catch (e) {}
+try {
+    (function() {
+        s
+    }())
+} catch (e) {}
+try {
+    e
+} catch (e) {}
+try {
+    "" ()
+} catch (e) {}
+try {
+    gc()
+    s
+} catch (e) {}
+try {
+    (function() {
+        for (v of m) {}
+    }())
+} catch (e) {}
+try {
+    t
+} catch (e) {}
+try {
+    (function() {
+        "use strict";
+        print(new function() {
+            r
+        }(this))
+    }())
+} catch (e) {}
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -4117,25 +4117,25 @@ mjit::Compiler::inlineCallHelper(uint32_
      * 'this' does not need to be synced for constructing. :FIXME: is it
      * possible that one of the arguments is directly copying the 'this'
      * entry (something like 'new x.f(x)')?
      */
     if (callingNew) {
         frame.discardFe(origThis);
 
         /*
-         * If inference is enabled, the 'this' value of the pushed frame always
-         * needs to be coherent. If a GC gets triggered before the callee can
-         * fill in the slot (i.e. the GC happens on constructing the 'new'
-         * object or the call object for a heavyweight callee), it needs to be
-         * able to read the 'this' value to tell whether newScript constraints
-         * will need to be regenerated afterwards.
+         * We store NULL here to ensure that the slot doesn't contain
+         * garbage. Additionally, we need to store a non-object value here for
+         * TI. If a GC gets triggered before the callee can fill in the slot
+         * (i.e. the GC happens on constructing the 'new' object or the call
+         * object for a heavyweight callee), it needs to be able to read the
+         * 'this' value to tell whether newScript constraints will need to be
+         * regenerated afterwards.
          */
-        if (cx->typeInferenceEnabled())
-            masm.storeValue(NullValue(), frame.addressOf(origThis));
+        masm.storeValue(NullValue(), frame.addressOf(origThis));
     }
 
     if (!cx->typeInferenceEnabled()) {
         CompileStatus status = callArrayBuiltin(callImmArgc, callingNew);
         if (status != Compile_InlineAbort)
             return (status == Compile_Okay);
     }