JSArray::shiftCountWith* could be more efficient
https://bugs.webkit.org/show_bug.cgi?id=133011

Reviewed by Geoffrey Garen.


Source/JavaScriptCore: 
Our current implementations of shiftCountWithAnyIndexingType and shiftCountWithArrayStorage 
are scared of the presence of any holes in the array. We can mitigate this somewhat by enabling 
them to correctly handle holes, thus avoiding the slowest of slow paths in most cases.

* runtime/ArrayStorage.h:
(JSC::ArrayStorage::indexingHeader):
(JSC::ArrayStorage::length):
(JSC::ArrayStorage::hasHoles):
* runtime/IndexingHeader.h:
(JSC::IndexingHeader::publicLength):
(JSC::IndexingHeader::from):
* runtime/JSArray.cpp:
(JSC::JSArray::shiftCountWithArrayStorage):
(JSC::JSArray::shiftCountWithAnyIndexingType):
(JSC::JSArray::unshiftCountWithArrayStorage):
* runtime/JSArray.h:
(JSC::JSArray::shiftCountForShift):
(JSC::JSArray::shiftCountForSplice):
(JSC::JSArray::shiftCount):
* runtime/Structure.cpp:
(JSC::Structure::holesRequireSpecialBehavior):
* runtime/Structure.h:

LayoutTests: 
Added a performance regression test which tests the contiguous shift case. We're ~85% faster 
on this microbenchmark with this patch.

Also added a bunch of tests for each permutation of contiguous/array storage with no holes, holes,
and holes that require special behavior (e.g. indexed properties in the prototype chain).

* js/array-storage-splice-holes-expected.txt: Added.
* js/array-storage-splice-holes-require-special-behavior-expected.txt: Added.
* js/array-storage-splice-holes-require-special-behavior.html: Added.
* js/array-storage-splice-holes.html: Added.
* js/array-storage-splice-no-holes-expected.txt: Added.
* js/array-storage-splice-no-holes.html: Added.
* js/contiguous-splice-holes-expected.txt: Added.
* js/contiguous-splice-holes-require-special-behavior-expected.txt: Added.
* js/contiguous-splice-holes-require-special-behavior.html: Added.
* js/contiguous-splice-holes.html: Added.
* js/contiguous-splice-no-holes-expected.txt: Added.
* js/contiguous-splice-no-holes.html: Added.
* js/regress/array-splice-contiguous-expected.txt: Added.
* js/regress/array-splice-contiguous.html: Added.
* js/regress/script-tests/array-splice-contiguous.js: Added.
(foo):
* js/script-tests/array-storage-splice-holes-require-special-behavior.js: Added.
* js/script-tests/array-storage-splice-holes.js: Added.
* js/script-tests/array-storage-splice-no-holes.js: Added.
* js/script-tests/contiguous-splice-holes-require-special-behavior.js: Added.
* js/script-tests/contiguous-splice-holes.js: Added.
* js/script-tests/contiguous-splice-no-holes.js: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@169121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index 8cca481..d1366cf 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -89,14 +89,14 @@
 
     bool shiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count)
     {
-        return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->vm()));
+        return shiftCountWithArrayStorage(exec->vm(), startIndex, count, ensureArrayStorage(exec->vm()));
     }
-    bool shiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count)
+    bool shiftCountForSplice(ExecState* exec, unsigned& startIndex, unsigned count)
     {
         return shiftCountWithAnyIndexingType(exec, startIndex, count);
     }
     template<ShiftCountMode shiftCountMode>
-    bool shiftCount(ExecState* exec, unsigned startIndex, unsigned count)
+    bool shiftCount(ExecState* exec, unsigned& startIndex, unsigned count)
     {
         switch (shiftCountMode) {
         case ShiftCountForShift:
@@ -156,8 +156,8 @@
         return !map || !map->lengthIsReadOnly();
     }
         
-    bool shiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
-    bool shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage*);
+    bool shiftCountWithAnyIndexingType(ExecState*, unsigned& startIndex, unsigned count);
+    bool shiftCountWithArrayStorage(VM&, unsigned startIndex, unsigned count, ArrayStorage*);
 
     bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count);
     bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*);