Commit ef5124b0 authored by darin@apple.com's avatar darin@apple.com

2008-09-22 Darin Adler <darin@apple.com>

        Reviewed by Sam Weinig.

        - https://bugs.webkit.org/show_bug.cgi?id=20993
          Array.push/pop need optimized cases for JSArray

        3% or so speedup on DeltaBlue benchmark.

        * kjs/ArrayPrototype.cpp:
        (JSC::arrayProtoFuncPop): Call JSArray::pop when appropriate.
        (JSC::arrayProtoFuncPush): Call JSArray::push when appropriate.

        * kjs/JSArray.cpp:
        (JSC::JSArray::putSlowCase): Set m_fastAccessCutoff when appropriate, getting
        us into the fast code path.
        (JSC::JSArray::pop): Added.
        (JSC::JSArray::push): Added.
        * kjs/JSArray.h: Added push and pop.

        * kjs/operations.cpp:
        (JSC::throwOutOfMemoryError): Don't inline this. Helps us avoid PIC branches.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36778 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 143e97cb
2008-09-22 Darin Adler <darin@apple.com>
Reviewed by Sam Weinig.
- https://bugs.webkit.org/show_bug.cgi?id=20993
Array.push/pop need optimized cases for JSArray
3% or so speedup on DeltaBlue benchmark.
* kjs/ArrayPrototype.cpp:
(JSC::arrayProtoFuncPop): Call JSArray::pop when appropriate.
(JSC::arrayProtoFuncPush): Call JSArray::push when appropriate.
* kjs/JSArray.cpp:
(JSC::JSArray::putSlowCase): Set m_fastAccessCutoff when appropriate, getting
us into the fast code path.
(JSC::JSArray::pop): Added.
(JSC::JSArray::push): Added.
* kjs/JSArray.h: Added push and pop.
* kjs/operations.cpp:
(JSC::throwOutOfMemoryError): Don't inline this. Helps us avoid PIC branches.
2008-09-22 Maciej Stachowiak <mjs@apple.com>
Reviewed by Cameron Zwarich.
......@@ -101,7 +124,7 @@
2008-09-21 Maciej Stachowiak <mjs@apple.com>
Reviewed by Darin.
Reviewed by Darin Adler.
- introduce a TypeInfo class, for holding per-type (in the C++ class sense) date in StructureID
https://bugs.webkit.org/show_bug.cgi?id=20981
......@@ -411,7 +434,7 @@
2008-09-20 Maciej Stachowiak <mjs@apple.com>
Reviewed by Darin.
Reviewed by Darin Adler.
- assorted optimizations to === and !== operators
(work towards <https://bugs.webkit.org/show_bug.cgi?id=20820>)
......
......@@ -291,6 +291,9 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue* thisValue, co
JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList&)
{
if (exec->machine()->isJSArray(thisValue))
return static_cast<JSArray*>(thisValue)->pop();
JSObject* thisObj = thisValue->toThisObject(exec);
JSValue* result = 0;
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
......@@ -307,6 +310,12 @@ JSValue* arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue* thisValue, const
JSValue* arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
if (exec->machine()->isJSArray(thisValue) && args.size() == 1) {
JSArray* array = static_cast<JSArray*>(thisValue);
array->push(exec, args.begin()->jsValue(exec));
return jsNumber(exec, array->length());
}
JSObject* thisObj = thisValue->toThisObject(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
for (unsigned n = 0; n < args.size(); n++)
......
......@@ -311,8 +311,9 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue* val
if (!map || map->isEmpty()) {
if (increaseVectorLength(i + 1)) {
storage = m_storage;
++storage->m_numValuesInVector;
storage->m_vector[i] = value;
if (++storage->m_numValuesInVector == storage->m_length)
m_fastAccessCutoff = storage->m_length;
checkConsistency();
} else
throwOutOfMemoryError(exec);
......@@ -508,6 +509,87 @@ void JSArray::setLength(unsigned newLength)
checkConsistency();
}
JSValue* JSArray::pop()
{
checkConsistency();
unsigned length = m_storage->m_length;
if (!length)
return jsUndefined();
--length;
JSValue* result;
if (m_fastAccessCutoff > length) {
JSValue*& valueSlot = m_storage->m_vector[length];
result = valueSlot;
ASSERT(result);
valueSlot = 0;
--m_storage->m_numValuesInVector;
m_fastAccessCutoff = length;
} else if (length < m_storage->m_vectorLength) {
JSValue*& valueSlot = m_storage->m_vector[length];
result = valueSlot;
valueSlot = 0;
if (result)
--m_storage->m_numValuesInVector;
else
result = jsUndefined();
} else {
result = jsUndefined();
if (SparseArrayValueMap* map = m_storage->m_sparseValueMap) {
SparseArrayValueMap::iterator it = map->find(length);
if (it != map->end()) {
result = it->second;
map->remove(it);
if (map->isEmpty()) {
delete map;
m_storage->m_sparseValueMap = 0;
}
}
}
}
m_storage->m_length = length;
checkConsistency();
return result;
}
void JSArray::push(ExecState* exec, JSValue* value)
{
checkConsistency();
if (m_storage->m_length < m_storage->m_vectorLength) {
ASSERT(!m_storage->m_vector[m_storage->m_length]);
m_storage->m_vector[m_storage->m_length] = value;
if (++m_storage->m_numValuesInVector == ++m_storage->m_length)
m_fastAccessCutoff = m_storage->m_length;
checkConsistency();
return;
}
if (m_storage->m_length < MIN_SPARSE_ARRAY_INDEX) {
SparseArrayValueMap* map = m_storage->m_sparseValueMap;
if (!map || map->isEmpty()) {
if (increaseVectorLength(m_storage->m_length + 1)) {
m_storage->m_vector[m_storage->m_length] = value;
if (++m_storage->m_numValuesInVector == ++m_storage->m_length)
m_fastAccessCutoff = m_storage->m_length;
checkConsistency();
return;
}
checkConsistency();
throwOutOfMemoryError(exec);
return;
}
}
putSlowCase(exec, m_storage->m_length++, value);
}
void JSArray::mark()
{
JSObject::mark();
......
......@@ -57,6 +57,9 @@ namespace JSC {
void sort(ExecState*);
void sort(ExecState*, JSValue* compareFunction, CallType, const CallData&);
void push(ExecState*, JSValue*);
JSValue* pop();
bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; }
JSValue* getIndex(unsigned i)
{
......
......@@ -115,7 +115,7 @@ bool strictEqualSlowCase(JSValue* v1, JSValue* v2)
return strictEqualSlowCaseInline(v1, v2);
}
JSValue* throwOutOfMemoryError(ExecState* exec)
NEVER_INLINE JSValue* throwOutOfMemoryError(ExecState* exec)
{
JSObject* error = Error::create(exec, GeneralError, "Out of memory");
exec->setException(error);
......
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