Title: [167249] trunk/Source/_javascript_Core
Revision
167249
Author
[email protected]
Date
2014-04-14 09:19:58 -0700 (Mon, 14 Apr 2014)

Log Message

Array.prototype.concat should allocate output storage only once.
<https://webkit.org/b/131609>

Do a first pass across 'this' and any arguments to compute the
final size of the resulting array from Array.prototype.concat.
This avoids having to grow the output incrementally as we go.

This also includes two other micro-optimizations:

- Mark getProperty() with ALWAYS_INLINE.

- Use JSArray::length() instead of taking the generic property
  lookup path when we know an argument is an Array.

My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.

Reviewed by Darin Adler.

* runtime/ArrayPrototype.cpp:
(JSC::getProperty):
(JSC::arrayProtoFuncConcat):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (167248 => 167249)


--- trunk/Source/_javascript_Core/ChangeLog	2014-04-14 16:02:03 UTC (rev 167248)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-04-14 16:19:58 UTC (rev 167249)
@@ -1,3 +1,27 @@
+2014-04-14  Andreas Kling  <[email protected]>
+
+        Array.prototype.concat should allocate output storage only once.
+        <https://webkit.org/b/131609>
+
+        Do a first pass across 'this' and any arguments to compute the
+        final size of the resulting array from Array.prototype.concat.
+        This avoids having to grow the output incrementally as we go.
+
+        This also includes two other micro-optimizations:
+
+        - Mark getProperty() with ALWAYS_INLINE.
+
+        - Use JSArray::length() instead of taking the generic property
+          lookup path when we know an argument is an Array.
+
+        My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
+
+        Reviewed by Darin Adler.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::getProperty):
+        (JSC::arrayProtoFuncConcat):
+
 2014-04-14  Benjamin Poulain  <[email protected]>
 
         [JSC] Improve the call site of string comparison in some hot path

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (167248 => 167249)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2014-04-14 16:02:03 UTC (rev 167248)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2014-04-14 16:19:58 UTC (rev 167249)
@@ -146,7 +146,7 @@
 // ------------------------------ Array Functions ----------------------------
 
 // Helper function
-static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
+static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
 {
     PropertySlot slot(obj);
     if (!obj->getPropertySlot(exec, index, slot))
@@ -416,19 +416,33 @@
 EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
 {
     JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
-    JSArray* arr = constructEmptyArray(exec, nullptr);
-    unsigned n = 0;
+    size_t argCount = exec->argumentCount();
     JSValue curArg = thisValue.toObject(exec);
+    Checked<unsigned, RecordOverflow> finalArraySize = 0;
+
+    for (size_t i = 0; i <= argCount; ++i) {
+        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg))
+            finalArraySize += currentArray->length();
+        else
+            finalArraySize++;
+        curArg = exec->uncheckedArgument(i);
+    }
+
+    if (finalArraySize.hasOverflowed())
+        return JSValue::encode(throwOutOfMemoryError(exec));
+
+    JSArray* arr = constructEmptyArray(exec, nullptr, finalArraySize.unsafeGet());
     if (exec->hadException())
         return JSValue::encode(jsUndefined());
+
+    curArg = thisValue.toObject(exec);
+    unsigned n = 0;
     size_t i = 0;
-    size_t argCount = exec->argumentCount();
     while (1) {
-        if (curArg.inherits(JSArray::info())) {
-            unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
-            JSObject* curObject = curArg.toObject(exec);
+        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
+            unsigned length = currentArray->length();
             for (unsigned k = 0; k < length; ++k) {
-                JSValue v = getProperty(exec, curObject, k);
+                JSValue v = getProperty(exec, currentArray, k);
                 if (exec->hadException())
                     return JSValue::encode(jsUndefined());
                 if (v)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to