Bug 928542 - Add placeholder CallGetProperty ops in definite properties analysis to avoid folding uses of 'this', r=jandem.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 24 Oct 2013 14:07:48 -0600
changeset 166774 b32d240c9a664fd1d8553643ca71f0e9886f4c1c
parent 166773 d0732dc3f30ec3cd30d574ca01acec015961b480
child 166775 541750e89771444d80f70a2f47e10f4db1ef417b
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs928542
milestone27.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 928542 - Add placeholder CallGetProperty ops in definite properties analysis to avoid folding uses of 'this', r=jandem.
js/src/jit-test/tests/ion/bug928542.js
js/src/jit/IonBuilder.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug928542.js
@@ -0,0 +1,10 @@
+
+called = 0;
+function foo() {
+    this.what();
+    this.random = 0;
+    this.what = 1;
+}
+foo.prototype.what = function() { called = 1; }
+new foo();
+assertEq(called, 1);
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -8040,32 +8040,43 @@ IonBuilder::jsop_getprop(PropertyName *n
     // Try to optimize arguments.length.
     if (!getPropTryArgumentsLength(&emitted) || emitted)
         return emitted;
 
     types::TemporaryTypeSet *types = bytecodeTypes(pc);
     bool barrier = PropertyReadNeedsTypeBarrier(cx, context(), constraints(),
                                                 current->peek(-1), name, types);
 
+    // Always use a call if we are doing the definite properties analysis and
+    // not actually emitting code, to simplify later analysis. Also skip deeper
+    // analysis if there are no known types for this operation, as it will
+    // always invalidate when executing.
+    if (info().executionMode() == DefinitePropertiesAnalysis || types->empty()) {
+        MDefinition *obj = current->peek(-1);
+        MCallGetProperty *call = MCallGetProperty::New(obj, name, *pc == JSOP_CALLPROP);
+        current->add(call);
+
+        // During the definite properties analysis we can still try to bake in
+        // constants read off the prototype chain, to allow inlining later on.
+        // In this case we still need the getprop call so that the later
+        // analysis knows when the |this| value has been read from.
+        if (info().executionMode() == DefinitePropertiesAnalysis) {
+            if (!getPropTryConstant(&emitted, name, types) || emitted)
+                return emitted;
+        }
+
+        current->pop();
+        current->push(call);
+        return resumeAfter(call) && pushTypeBarrier(call, types, true);
+    }
+
     // Try to hardcode known constants.
     if (!getPropTryConstant(&emitted, name, types) || emitted)
         return emitted;
 
-    // Except when loading constants above, always use a call if we are doing
-    // the definite properties analysis and not actually emitting code, to
-    // simplify later analysis. Also skip deeper analysis if there are no known
-    // types for this operation, as it will always invalidate when executing.
-    if (info().executionMode() == DefinitePropertiesAnalysis || types->empty()) {
-        MDefinition *obj = current->pop();
-        MCallGetProperty *call = MCallGetProperty::New(obj, name, *pc == JSOP_CALLPROP);
-        current->add(call);
-        current->push(call);
-        return resumeAfter(call) && pushTypeBarrier(call, types, true);
-    }
-
     // Try to emit loads from known binary data blocks
     if (!getPropTryTypedObject(&emitted, name, types) || emitted)
         return emitted;
 
     // Try to emit loads from definite slots.
     if (!getPropTryDefiniteSlot(&emitted, name, barrier, types) || emitted)
         return emitted;