Title: [184217] trunk/Source/_javascript_Core
Revision
184217
Author
[email protected]
Date
2015-05-12 14:04:10 -0700 (Tue, 12 May 2015)

Log Message

Array.slice should have a fast path like Array.splice
https://bugs.webkit.org/show_bug.cgi?id=144901

Reviewed by Geoffrey Garen.

Add a fast memcpy path to Array.prototype.slice as done for Array.prototype.splice.
In Kraken, this appears to be 30% win on stanford-crypto-ccm and 10% win on stanford-crypto-pbkdf2.

* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncSlice):
* runtime/JSArray.cpp:
(JSC::JSArray::fastSlice): Added.
* runtime/JSArray.h:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (184216 => 184217)


--- trunk/Source/_javascript_Core/ChangeLog	2015-05-12 21:02:41 UTC (rev 184216)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-05-12 21:04:10 UTC (rev 184217)
@@ -1,3 +1,19 @@
+2015-05-12  Ryosuke Niwa  <[email protected]>
+
+        Array.slice should have a fast path like Array.splice
+        https://bugs.webkit.org/show_bug.cgi?id=144901
+
+        Reviewed by Geoffrey Garen.
+
+        Add a fast memcpy path to Array.prototype.slice as done for Array.prototype.splice.
+        In Kraken, this appears to be 30% win on stanford-crypto-ccm and 10% win on stanford-crypto-pbkdf2.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSlice):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::fastSlice): Added.
+        * runtime/JSArray.h:
+
 2015-05-11  Filip Pizlo  <[email protected]>
 
         OSR availability analysis would be more scalable (and correct) if it did more liveness pruning

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (184216 => 184217)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2015-05-12 21:02:41 UTC (rev 184216)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2015-05-12 21:04:10 UTC (rev 184217)
@@ -601,6 +601,12 @@
     unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
     unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
 
+    if (isJSArray(thisObj)) {
+        EncodedJSValue result;
+        if (asArray(thisObj)->fastSlice(*exec, begin, end - begin, result))
+            return result;
+    }
+
     JSArray* result = constructEmptyArray(exec, nullptr, end - begin);
 
     unsigned n = 0;

Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (184216 => 184217)


--- trunk/Source/_javascript_Core/runtime/JSArray.cpp	2015-05-12 21:02:41 UTC (rev 184216)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp	2015-05-12 21:04:10 UTC (rev 184217)
@@ -666,6 +666,40 @@
     }
 }
 
+bool JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count, EncodedJSValue& result)
+{
+    auto arrayType = indexingType();
+    switch (arrayType) {
+    case ArrayWithDouble:
+    case ArrayWithInt32:
+    case ArrayWithContiguous: {
+        VM& vm = exec.vm();
+        if (count >= MIN_SPARSE_ARRAY_INDEX || structure(vm)->holesMustForwardToPrototype(vm))
+            return false;
+
+        Structure* resultStructure = exec.lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(arrayType);
+        JSArray* resultArray = JSArray::tryCreateUninitialized(vm, resultStructure, count);
+        if (!resultArray) {
+            result = JSValue::encode(throwOutOfMemoryError(&exec));
+            return true;
+        }
+
+        auto& resultButterfly = *resultArray->butterfly();
+        if (arrayType == ArrayWithDouble)
+            memcpy(resultButterfly.contiguousDouble().data(), m_butterfly->contiguousDouble().data() + startIndex, sizeof(JSValue) * count);
+        else
+            memcpy(resultButterfly.contiguous().data(), m_butterfly->contiguous().data() + startIndex, sizeof(JSValue) * count);
+        resultButterfly.setPublicLength(count);
+
+        result = JSValue::encode(resultArray);
+        return true;
+    }
+    default:
+        break;
+    }
+    return false;
+}
+
 bool JSArray::shiftCountWithArrayStorage(VM& vm, unsigned startIndex, unsigned count, ArrayStorage* storage)
 {
     unsigned oldLength = storage->length();

Modified: trunk/Source/_javascript_Core/runtime/JSArray.h (184216 => 184217)


--- trunk/Source/_javascript_Core/runtime/JSArray.h	2015-05-12 21:02:41 UTC (rev 184216)
+++ trunk/Source/_javascript_Core/runtime/JSArray.h	2015-05-12 21:04:10 UTC (rev 184217)
@@ -73,6 +73,8 @@
     JS_EXPORT_PRIVATE void push(ExecState*, JSValue);
     JS_EXPORT_PRIVATE JSValue pop(ExecState*);
 
+    bool fastSlice(ExecState&, unsigned startIndex, unsigned count, EncodedJSValue&);
+
     enum ShiftCountMode {
         // This form of shift hints that we're doing queueing. With this assumption in hand,
         // we convert to ArrayStorage, which has queue optimizations.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to