Bug 489623 - JSOP_SETPROP does not run resolve hook when adding properties (resubmitting after fix)
authorKannan Vijayan <kvijayan@mozilla.com>
Fri, 27 Apr 2012 16:08:38 -0400
changeset 112427 1b954a5da88ce0fea80b84993a8136c05baa3f6c
parent 112426 5a6e9f648a26a1c66453d45471a2e559a75599f8
child 112428 fb7572ed4bc6832b84b14670c490b61c9db2d278
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs489623
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 489623 - JSOP_SETPROP does not run resolve hook when adding properties (resubmitting after fix)
js/src/ion/IonCaches.cpp
--- a/js/src/ion/IonCaches.cpp
+++ b/js/src/ion/IonCaches.cpp
@@ -451,27 +451,45 @@ IonCacheSetProperty::attachNativeAdding(
 static bool
 IsEligibleForInlinePropertyAdd(JSContext *cx, JSObject *obj, jsid propId, uint32_t oldSlots,
                                const Shape **propShapeOut)
 {
     const Shape *propShape = obj->nativeLookup(cx, propId);
     if (!propShape || propShape->inDictionary() || !propShape->hasSlot() || !propShape->hasDefaultSetter())
         return false;
 
+    // If object has a non-default resolve hook, don't inline
+    if (obj->getClass()->resolve != JS_ResolveStub)
+        return false;
+
     // walk up the object prototype chain and ensure that all prototypes
     // are native, and that all prototypes have no getter or setter
     // defined on the property
     for (JSObject *proto = obj->getProto(); proto; proto = proto->getProto()) {
         // if prototype is non-native, don't optimize
         if (!proto->isNative()) 
             return false;
 
         // if prototype defines this property in a non-plain way, don't optimize
         const Shape *protoShape = proto->nativeLookup(cx, propId);
-        if (protoShape && !protoShape->hasDefaultSetter())
+        if (protoShape) {
+            // If the prototype has a property with this name, we may be able to
+            // inline-add if the property has a default setter.  If there's no
+            // default setter, then setting would potentially cause special
+            // behaviour, so we choose not to optimize.
+            if (protoShape->hasDefaultSetter()) {
+                *propShapeOut = propShape;
+                return true;
+            }
+            return false;
+        }
+
+        // Otherise, if there's no such property, watch out for a resolve hook that would need
+        // to be invoked and thus prevent inlining of property addition.
+        if (proto->getClass()->resolve != JS_ResolveStub)
             return false;
     }
 
     // Only add a IC entry if the dynamic slots didn't change when the shapes
     // changed.  Need to ensure that a shape change for a subsequent object
     // won't involve reallocating the slot array.
     if (obj->numDynamicSlots() != oldSlots)
         return false;