2010-05-09 Maciej Stachowiak <mjs@apple.com>
authormjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 May 2010 11:18:25 +0000 (11:18 +0000)
committermjs@apple.com <mjs@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 May 2010 11:18:25 +0000 (11:18 +0000)
        Fixed version of: "Optimized o[s] where o is a cell and s is a string"
        https://bugs.webkit.org/show_bug.cgi?id=38815

        Fixed the previous patch for this from Geoff Garen.

        The two problems were a missing exception check and a PropertySlot
        initialized improperly, leading to crashes and failures in the case
        of getters accessed with bracket syntax.

    Previous patch:

        Optimized o[s] where o is a cell and s is a string, removing some old
        code that wasn't really tuned for the JIT.

        SunSpider says 0.8% faster.

        * jit/JITStubs.cpp:
        (JSC::DEFINE_STUB_FUNCTION):
        * runtime/JSCell.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@59055 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/jit/JITStubs.cpp
JavaScriptCore/runtime/JSCell.h

index f467e25555a3e24a35d2de0817693140b153c4db..a759c48db15e4c21833d4d345488c3d495fe2720 100644 (file)
@@ -1,3 +1,25 @@
+2010-05-09  Maciej Stachowiak  <mjs@apple.com>
+
+        Fixed version of: "Optimized o[s] where o is a cell and s is a string"
+        https://bugs.webkit.org/show_bug.cgi?id=38815
+        
+        Fixed the previous patch for this from Geoff Garen.
+        
+        The two problems were a missing exception check and a PropertySlot
+        initialized improperly, leading to crashes and failures in the case
+        of getters accessed with bracket syntax.
+
+    Previous patch:
+
+        Optimized o[s] where o is a cell and s is a string, removing some old
+        code that wasn't really tuned for the JIT.
+        
+        SunSpider says 0.8% faster.
+
+        * jit/JITStubs.cpp:
+        (JSC::DEFINE_STUB_FUNCTION):
+        * runtime/JSCell.h:
+
 2010-05-08  Laszlo Gombos  <laszlo.1.gombos@nokia.com>
 
         Unreviewed, build fix.
index ebd26bb97344c08947380ef7eb551021a0d9dec1..e237bd5ca0ebf20d703c8784fbe58af0d16a5f95 100644 (file)
@@ -2087,31 +2087,36 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
 
-    JSValue result;
+    if (LIKELY(baseValue.isCell() && subscript.isString())) {
+        Identifier propertyName(callFrame, asString(subscript)->value(callFrame));
+        PropertySlot slot(asCell(baseValue));
+        if (asCell(baseValue)->fastGetOwnPropertySlot(callFrame, propertyName, slot)) {
+            JSValue result = slot.getValue(callFrame, propertyName);
+            CHECK_FOR_EXCEPTION();
+            return JSValue::encode(result);
+        }
+    }
 
-    if (LIKELY(subscript.isUInt32())) {
+    if (subscript.isUInt32()) {
         uint32_t i = subscript.asUInt32();
-        if (isJSArray(globalData, baseValue)) {
-            JSArray* jsArray = asArray(baseValue);
-            if (jsArray->canGetIndex(i))
-                result = jsArray->getIndex(i);
-            else
-                result = jsArray->JSArray::get(callFrame, i);
-        } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
-            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+        if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
-            result = asString(baseValue)->getIndex(callFrame, i);
-        } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            JSValue result = asString(baseValue)->getIndex(callFrame, i);
+            CHECK_FOR_EXCEPTION();
+            return JSValue::encode(result);
+        }
+        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
             // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
             return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
-        } else
-            result = baseValue.get(callFrame, i);
-    } else {
-        Identifier property(callFrame, subscript.toString(callFrame));
-        result = baseValue.get(callFrame, property);
+        }
+        JSValue result = baseValue.get(callFrame, i);
+        CHECK_FOR_EXCEPTION();
+        return JSValue::encode(result);
     }
-
+    
+    Identifier property(callFrame, subscript.toString(callFrame));
+    JSValue result = baseValue.get(callFrame, property);
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
index 772708f59f9381c3adb7b4605df040d40f46a3b7..ae5aca3bf422eccde0516fce73fdc44cf66683f6 100644 (file)
@@ -111,12 +111,17 @@ namespace JSC {
         void* vptr() { return *reinterpret_cast<void**>(this); }
         void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; }
 
+        // FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and
+        // fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always
+        // call this function, not its slower virtual counterpart. (For integer
+        // property names, we want a similar interface with appropriate optimizations.)
+        bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+
     protected:
         static const unsigned AnonymousSlotCount = 0;
 
     private:
         // Base implementation; for non-object classes implements getPropertySlot.
-        bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);