Commit 2cebeda0 authored by fpizlo@apple.com's avatar fpizlo@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):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@130315 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 020939da
2012-10-03 Filip Pizlo <fpizlo@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 <mhahnenberg@apple.com>
Delayed structure sweep can leak structures without bound
......
......@@ -202,9 +202,9 @@ static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, un
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;
}
......
......@@ -505,7 +505,7 @@ void JSArray::push(ExecState* exec, JSValue value)
}
}
bool JSArray::shiftCount(ExecState* exec, unsigned count)
bool JSArray::shiftCount(ExecState* exec, unsigned startIndex, unsigned count)
{
ASSERT(count > 0);
......@@ -522,20 +522,44 @@ bool JSArray::shiftCount(ExecState* exec, unsigned count)
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) {
count = min(vectorLength, (unsigned)count);
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) {
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;
......
......@@ -71,8 +71,8 @@ namespace JSC {
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment