Title: [130315] trunk/Source/_javascript_Core
Revision
130315
Author
fpi...@apple.com
Date
2012-10-03 13:03:20 -0700 (Wed, 03 Oct 2012)

Log Message

Array.splice should be fast when it is used to remove elements other than the very first
https://bugs.webkit.org/show_bug.cgi?id=98236

Reviewed by Michael Saboff.

Applied the same technique that was used to optimize the unshift case of splice in
http://trac.webkit.org/changeset/129676.  This is a >20x speed-up on programs that
use splice for element removal.

* runtime/ArrayPrototype.cpp:
(JSC::shift):
* runtime/JSArray.cpp:
(JSC::JSArray::shiftCount):
* runtime/JSArray.h:
(JSArray):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (130314 => 130315)


--- trunk/Source/_javascript_Core/ChangeLog	2012-10-03 20:00:47 UTC (rev 130314)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-10-03 20:03:20 UTC (rev 130315)
@@ -1,3 +1,21 @@
+2012-10-03  Filip Pizlo  <fpi...@apple.com>
+
+        Array.splice should be fast when it is used to remove elements other than the very first
+        https://bugs.webkit.org/show_bug.cgi?id=98236
+
+        Reviewed by Michael Saboff.
+
+        Applied the same technique that was used to optimize the unshift case of splice in
+        http://trac.webkit.org/changeset/129676.  This is a >20x speed-up on programs that
+        use splice for element removal.
+
+        * runtime/ArrayPrototype.cpp:
+        (JSC::shift):
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::shiftCount):
+        * runtime/JSArray.h:
+        (JSArray):
+
 2012-09-16  Mark Hahnenberg  <mhahnenb...@apple.com>
 
         Delayed structure sweep can leak structures without bound

Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (130314 => 130315)


--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2012-10-03 20:00:47 UTC (rev 130314)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2012-10-03 20:03:20 UTC (rev 130315)
@@ -202,9 +202,9 @@
     ASSERT(header <= length);
     ASSERT(currentCount <= (length - header));
 
-    if (!header && isJSArray(thisObj)) {
+    if (isJSArray(thisObj)) {
         JSArray* array = asArray(thisObj);
-        if (array->length() == length && asArray(thisObj)->shiftCount(exec, count))
+        if (array->length() == length && asArray(thisObj)->shiftCount(exec, header, count))
             return;
     }
 

Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (130314 => 130315)


--- trunk/Source/_javascript_Core/runtime/JSArray.cpp	2012-10-03 20:00:47 UTC (rev 130314)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp	2012-10-03 20:03:20 UTC (rev 130315)
@@ -505,7 +505,7 @@
     }
 }
 
-bool JSArray::shiftCount(ExecState* exec, unsigned count)
+bool JSArray::shiftCount(ExecState* exec, unsigned startIndex, unsigned count)
 {
     ASSERT(count > 0);
     
@@ -522,20 +522,44 @@
     if (!oldLength)
         return true;
     
+    unsigned length = oldLength - count;
+    
     storage->m_numValuesInVector -= count;
-    storage->setLength(oldLength - count);
+    storage->setLength(length);
     
     unsigned vectorLength = storage->vectorLength();
+    if (!vectorLength)
+        return true;
+    
+    if (startIndex >= vectorLength)
+        return true;
+    
+    if (startIndex + count > vectorLength)
+        count = vectorLength - startIndex;
+    
+    unsigned usedVectorLength = min(vectorLength, oldLength);
+    
+    vectorLength -= count;
+    storage->setVectorLength(vectorLength);
+    
     if (vectorLength) {
-        count = min(vectorLength, (unsigned)count);
-        
-        vectorLength -= count;
-        storage->setVectorLength(vectorLength);
-        
-        if (vectorLength) {
+        if (startIndex < usedVectorLength - (startIndex + count)) {
+            if (startIndex) {
+                memmove(
+                    storage->m_vector + count,
+                    storage->m_vector,
+                    sizeof(JSValue) * startIndex);
+            }
             m_butterfly = m_butterfly->shift(structure(), count);
             storage = m_butterfly->arrayStorage();
             storage->m_indexBias += count;
+        } else {
+            memmove(
+                storage->m_vector + startIndex,
+                storage->m_vector + startIndex + count,
+                sizeof(JSValue) * (usedVectorLength - (startIndex + count)));
+            for (unsigned i = usedVectorLength - count; i < usedVectorLength; ++i)
+                storage->m_vector[i].clear();
         }
     }
     return true;

Modified: trunk/Source/_javascript_Core/runtime/JSArray.h (130314 => 130315)


--- trunk/Source/_javascript_Core/runtime/JSArray.h	2012-10-03 20:00:47 UTC (rev 130314)
+++ trunk/Source/_javascript_Core/runtime/JSArray.h	2012-10-03 20:03:20 UTC (rev 130315)
@@ -71,8 +71,8 @@
         void push(ExecState*, JSValue);
         JSValue pop(ExecState*);
 
-        bool shiftCount(ExecState*, unsigned count);
-        bool unshiftCount(ExecState*, unsigned, unsigned);
+        bool shiftCount(ExecState*, unsigned startIndex, unsigned count);
+        bool unshiftCount(ExecState*, unsigned startIndex, unsigned count);
 
         void fillArgList(ExecState*, MarkedArgumentBuffer&);
         void copyToArguments(ExecState*, CallFrame*, uint32_t length);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to