Bug 1126318 - Fix TryAttachNativeGetPropStub to ensure the function is native before using its jitinfo. r=bz, a=lmandel
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 30 Jan 2015 22:11:53 +0100
changeset 240477 2e9b093db1fb3f0abd8dc5f93839bd495374551a
parent 240476 4811407460e6a3d438a324ab299456dafc4c0844
child 240478 3e7182df6ae92cbc53fe67ddebed9b926b83101d
push id7563
push userryanvm@gmail.com
push dateTue, 03 Feb 2015 22:03:56 +0000
treeherdermozilla-aurora@d54d5134aab7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, lmandel
bugs1126318
milestone37.0a2
Bug 1126318 - Fix TryAttachNativeGetPropStub to ensure the function is native before using its jitinfo. r=bz, a=lmandel
js/src/jit/BaselineIC.cpp
js/src/tests/ecma_5/misc/bug1126318.js
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -6688,89 +6688,87 @@ TryAttachNativeGetPropStub(JSContext *cx
                                         &domProxyShadowsResult, &domProxyHasGeneration))
         {
             return false;
         }
         cacheableCall = IsCacheableGetPropCall(cx, obj, holder, shape, &isScripted,
                                                isTemporarilyUnoptimizable, isDOMProxy);
     }
 
+    // Try handling JSNative getters.
+    if (!cacheableCall || isScripted)
+        return true;
+
     if (!shape || !shape->hasGetterValue() || !shape->getterValue().isObject() ||
         !shape->getterObject()->is<JSFunction>())
     {
         return true;
     }
 
     RootedFunction callee(cx, &shape->getterObject()->as<JSFunction>());
+    MOZ_ASSERT(callee->isNative());
 
     if (outerClass && (!callee->jitInfo() || callee->jitInfo()->needsOuterizedThisObject()))
         return true;
 
-    // Try handling JSNative getters.
-    if (cacheableCall && !isScripted) {
 #if JS_HAS_NO_SUCH_METHOD
-        // It's unlikely that a getter function will be used to generate functions for calling
-        // in CALLPROP locations.  Just don't attach stubs in that case to avoid issues with
-        // __noSuchMethod__ handling.
-        if (isCallProp)
-            return true;
+    // It's unlikely that a getter function will be used to generate functions for calling
+    // in CALLPROP locations.  Just don't attach stubs in that case to avoid issues with
+    // __noSuchMethod__ handling.
+    if (isCallProp)
+        return true;
 #endif
 
-        MOZ_ASSERT(callee->isNative());
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(%s%s/NativeGetter %p) stub",
-                isDOMProxy ? "DOMProxyObj" : "NativeObj",
-                isDOMProxy && domProxyHasGeneration ? "WithGeneration" : "",
-                callee->native());
-
-        ICStub *newStub = nullptr;
-        if (isDOMProxy) {
-            MOZ_ASSERT(obj != holder);
-            ICStub::Kind kind;
-            if (domProxyHasGeneration) {
-                if (UpdateExistingGenerationalDOMProxyStub(stub, obj)) {
-                    *attached = true;
-                    return true;
-                }
-                kind = ICStub::GetProp_CallDOMProxyWithGenerationNative;
-            } else {
-                kind = ICStub::GetProp_CallDOMProxyNative;
-            }
-            Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
-            ICGetPropCallDOMProxyNativeCompiler
-                compiler(cx, kind, monitorStub, proxy, holder, callee, script->pcToOffset(pc));
-            newStub = compiler.getStub(compiler.getStubSpace(script));
-        } else if (obj == holder) {
-            if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNative,
-                                               obj, JS::NullPtr(), callee)) {
+    JitSpew(JitSpew_BaselineIC, "  Generating GetProp(%s%s/NativeGetter %p) stub",
+            isDOMProxy ? "DOMProxyObj" : "NativeObj",
+            isDOMProxy && domProxyHasGeneration ? "WithGeneration" : "",
+            callee->native());
+
+    ICStub *newStub = nullptr;
+    if (isDOMProxy) {
+        MOZ_ASSERT(obj != holder);
+        ICStub::Kind kind;
+        if (domProxyHasGeneration) {
+            if (UpdateExistingGenerationalDOMProxyStub(stub, obj)) {
                 *attached = true;
                 return true;
             }
-
-            ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, callee,
-                                                    script->pcToOffset(pc), outerClass);
-            newStub = compiler.getStub(compiler.getStubSpace(script));
+            kind = ICStub::GetProp_CallDOMProxyWithGenerationNative;
         } else {
-            if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNativePrototype,
-                                               holder, obj, callee)) {
-                *attached = true;
-                return true;
-            }
-
-            ICGetProp_CallNativePrototype::Compiler compiler(cx, monitorStub, obj, holder, callee,
-                                                             script->pcToOffset(pc), outerClass);
-            newStub = compiler.getStub(compiler.getStubSpace(script));
-        }
-        if (!newStub)
-            return false;
-        stub->addNewStub(newStub);
-        *attached = true;
-        return true;
-    }
-
+            kind = ICStub::GetProp_CallDOMProxyNative;
+        }
+        Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
+        ICGetPropCallDOMProxyNativeCompiler compiler(cx, kind, monitorStub, proxy, holder, callee,
+                                                     script->pcToOffset(pc));
+        newStub = compiler.getStub(compiler.getStubSpace(script));
+    } else if (obj == holder) {
+        if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNative,
+                                           obj, JS::NullPtr(), callee)) {
+            *attached = true;
+            return true;
+        }
+
+        ICGetProp_CallNative::Compiler compiler(cx, monitorStub, obj, callee,
+                                                script->pcToOffset(pc), outerClass);
+        newStub = compiler.getStub(compiler.getStubSpace(script));
+    } else {
+        if (UpdateExistingGetPropCallStubs(stub, ICStub::GetProp_CallNativePrototype,
+                                           holder, obj, callee)) {
+            *attached = true;
+            return true;
+        }
+
+        ICGetProp_CallNativePrototype::Compiler compiler(cx, monitorStub, obj, holder, callee,
+                                                         script->pcToOffset(pc), outerClass);
+        newStub = compiler.getStub(compiler.getStubSpace(script));
+    }
+    if (!newStub)
+        return false;
+    stub->addNewStub(newStub);
+    *attached = true;
     return true;
 }
 
 static bool
 TryAttachTypedObjectGetPropStub(JSContext *cx, HandleScript script,
                                 ICGetProp_Fallback *stub, HandlePropertyName name, HandleValue val,
                                 bool *attached)
 {
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_5/misc/bug1126318.js
@@ -0,0 +1,13 @@
+if (typeof window === "undefined")
+    window = this;
+
+Object.defineProperty(window, "foo", {
+    get: function() { return 5; },
+    configurable: true
+});
+
+for (var i = 0; i < 100; ++i)
+    assertEq(window.foo, 5);
+
+if (typeof reportCompare === "function")
+    reportCompare(0, 0);