Title: [88975] trunk/Source/_javascript_Core
Revision
88975
Author
[email protected]
Date
2011-06-15 14:57:17 -0700 (Wed, 15 Jun 2011)

Log Message

Make access-nseive ~9x faster on the non-speculative path by
adding special casing for doubles that can lossless-ly be converted
to a uint32_t in getByVal and putByVal. This avoids calls to stringification
and the hash lookup.  Long term, we should try and get property of a getByVal
and putByVal to be an integer immediate even in the non-speculative path.

Reviewed by Geoffrey Garen and Gavin Barraclough.

* dfg/DFGOperations.cpp:
(JSC::DFG::putByVal):
(JSC::DFG::operationPutByValInternal):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (88974 => 88975)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-15 21:46:13 UTC (rev 88974)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-15 21:57:17 UTC (rev 88975)
@@ -1,3 +1,17 @@
+2011-06-15  Sam Weinig  <[email protected]>
+
+        Reviewed by Geoffrey Garen and Gavin Barraclough.
+
+        Make access-nseive ~9x faster on the non-speculative path by
+        adding special casing for doubles that can lossless-ly be converted
+        to a uint32_t in getByVal and putByVal. This avoids calls to stringification
+        and the hash lookup.  Long term, we should try and get property of a getByVal
+        and putByVal to be an integer immediate even in the non-speculative path.
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::putByVal):
+        (JSC::DFG::operationPutByValInternal):
+
 2011-06-15  Oliver Hunt  <[email protected]>
 
         Reviewed by Darin Adler.

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (88974 => 88975)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-06-15 21:46:13 UTC (rev 88974)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2011-06-15 21:57:17 UTC (rev 88975)
@@ -46,48 +46,62 @@
 
 namespace JSC { namespace DFG {
 
-template<bool strict>
-ALWAYS_INLINE static void operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
+static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
 {
     JSGlobalData* globalData = &exec->globalData();
 
-    JSValue baseValue = JSValue::decode(encodedBase);
-    JSValue property = JSValue::decode(encodedProperty);
-    JSValue value = JSValue::decode(encodedValue);
+    if (isJSArray(globalData, baseValue)) {
+        JSArray* array = asArray(baseValue);
+        if (array->canSetIndex(index)) {
+            array->setIndex(*globalData, index, value);
+            return;
+        }
 
-    if (LIKELY(property.isUInt32())) {
-        uint32_t index = property.asUInt32();
+        array->JSArray::put(exec, index, value);
+        return;
+    }
 
-        if (isJSArray(globalData, baseValue)) {
-            JSArray* array = asArray(baseValue);
-            if (array->canSetIndex(index)) {
-                array->setIndex(*globalData, index, value);
-                return;
-            }
+    if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(index)) {
+        JSByteArray* byteArray = asByteArray(baseValue);
+        // FIXME: the JITstub used to relink this to an optimized form!
+        if (value.isInt32()) {
+            byteArray->setIndex(index, value.asInt32());
+            return;
+        }
 
-            array->JSArray::put(exec, index, value);
+        double dValue = 0;
+        if (value.getNumber(dValue)) {
+            byteArray->setIndex(index, dValue);
             return;
         }
+    }
 
-        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(index)) {
-            JSByteArray* byteArray = asByteArray(baseValue);
-            // FIXME: the JITstub used to relink this to an optimized form!
-            if (value.isInt32()) {
-                byteArray->setIndex(index, value.asInt32());
-                return;
-            }
+    baseValue.put(exec, index, value);
+}
 
-            double dValue = 0;
-            if (value.getNumber(dValue)) {
-                byteArray->setIndex(index, dValue);
-                return;
-            }
-        }
+template<bool strict>
+ALWAYS_INLINE static void operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
+{
+    JSValue baseValue = JSValue::decode(encodedBase);
+    JSValue property = JSValue::decode(encodedProperty);
+    JSValue value = JSValue::decode(encodedValue);
 
-        baseValue.put(exec, index, value);
+    if (LIKELY(property.isUInt32())) {
+        putByVal(exec, baseValue, property.asUInt32(), value);
         return;
     }
 
+    if (property.isDouble()) {
+        double propertyAsDouble = property.asDouble();
+        uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
+        if (propertyAsDouble == propertyAsUInt32) {
+            putByVal(exec, baseValue, propertyAsUInt32, value);
+            return;
+        }
+    }
+
+    JSGlobalData* globalData = &exec->globalData();
+
     // Don't put to an object if toString throws an exception.
     Identifier ident(exec, property.toString(exec));
     if (!globalData->exception) {
@@ -124,6 +138,25 @@
     return JSValue::encode(jsAddSlowCase(exec, op1, op2));
 }
 
+static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
+{
+    JSGlobalData* globalData = &exec->globalData();
+
+    // FIXME: the JIT used to handle these in compiled code!
+    if (isJSArray(globalData, base) && asArray(base)->canGetIndex(index))
+        return JSValue::encode(asArray(base)->getIndex(index));
+
+    // FIXME: the JITstub used to relink this to an optimized form!
+    if (isJSString(globalData, base) && asString(base)->canGetIndex(index))
+        return JSValue::encode(asString(base)->getIndex(exec, index));
+
+    // FIXME: the JITstub used to relink this to an optimized form!
+    if (isJSByteArray(globalData, base) && asByteArray(base)->canAccessIndex(index))
+        return JSValue::encode(asByteArray(base)->getIndex(exec, index));
+
+    return JSValue::encode(JSValue(base).get(exec, index));
+}
+
 EncodedJSValue operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
 {
     JSValue baseValue = JSValue::decode(encodedBase);
@@ -133,25 +166,13 @@
         JSCell* base = baseValue.asCell();
 
         if (property.isUInt32()) {
-            JSGlobalData* globalData = &exec->globalData();
-            uint32_t index = property.asUInt32();
-
-            // FIXME: the JIT used to handle these in compiled code!
-            if (isJSArray(globalData, base) && asArray(base)->canGetIndex(index))
-                return JSValue::encode(asArray(base)->getIndex(index));
-
-            // FIXME: the JITstub used to relink this to an optimized form!
-            if (isJSString(globalData, base) && asString(base)->canGetIndex(index))
-                return JSValue::encode(asString(base)->getIndex(exec, index));
-
-            // FIXME: the JITstub used to relink this to an optimized form!
-            if (isJSByteArray(globalData, base) && asByteArray(base)->canAccessIndex(index))
-                return JSValue::encode(asByteArray(base)->getIndex(exec, index));
-
-            return JSValue::encode(baseValue.get(exec, index));
-        }
-
-        if (property.isString()) {
+            return getByVal(exec, base, property.asUInt32());
+        } else if (property.isDouble()) {
+            double propertyAsDouble = property.asDouble();
+            uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
+            if (propertyAsUInt32 == propertyAsDouble)
+                return getByVal(exec, base, propertyAsUInt32);
+        } else if (property.isString()) {
             Identifier propertyName(exec, asString(property)->value(exec));
             PropertySlot slot(base);
             if (base->fastGetOwnPropertySlot(exec, propertyName, slot))
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to