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