Changeset 167249 in webkit


Ignore:
Timestamp:
Apr 14, 2014 9:19:58 AM (10 years ago)
Author:
akling@apple.com
Message:

Array.prototype.concat should allocate output storage only once.
<https://webkit.org/b/131609>

Do a first pass across 'this' and any arguments to compute the
final size of the resulting array from Array.prototype.concat.
This avoids having to grow the output incrementally as we go.

This also includes two other micro-optimizations:

  • Mark getProperty() with ALWAYS_INLINE.
  • Use JSArray::length() instead of taking the generic property lookup path when we know an argument is an Array.

My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.

Reviewed by Darin Adler.

  • runtime/ArrayPrototype.cpp:

(JSC::getProperty):
(JSC::arrayProtoFuncConcat):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r167220 r167249  
     12014-04-14  Andreas Kling  <akling@apple.com>
     2
     3        Array.prototype.concat should allocate output storage only once.
     4        <https://webkit.org/b/131609>
     5
     6        Do a first pass across 'this' and any arguments to compute the
     7        final size of the resulting array from Array.prototype.concat.
     8        This avoids having to grow the output incrementally as we go.
     9
     10        This also includes two other micro-optimizations:
     11
     12        - Mark getProperty() with ALWAYS_INLINE.
     13
     14        - Use JSArray::length() instead of taking the generic property
     15          lookup path when we know an argument is an Array.
     16
     17        My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
     18
     19        Reviewed by Darin Adler.
     20
     21        * runtime/ArrayPrototype.cpp:
     22        (JSC::getProperty):
     23        (JSC::arrayProtoFuncConcat):
     24
    1252014-04-14  Benjamin Poulain  <benjamin@webkit.org>
    226
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r166792 r167249  
    147147
    148148// Helper function
    149 static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
     149static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
    150150{
    151151    PropertySlot slot(obj);
     
    417417{
    418418    JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
    419     JSArray* arr = constructEmptyArray(exec, nullptr);
     419    size_t argCount = exec->argumentCount();
     420    JSValue curArg = thisValue.toObject(exec);
     421    Checked<unsigned, RecordOverflow> finalArraySize = 0;
     422
     423    for (size_t i = 0; i <= argCount; ++i) {
     424        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg))
     425            finalArraySize += currentArray->length();
     426        else
     427            finalArraySize++;
     428        curArg = exec->uncheckedArgument(i);
     429    }
     430
     431    if (finalArraySize.hasOverflowed())
     432        return JSValue::encode(throwOutOfMemoryError(exec));
     433
     434    JSArray* arr = constructEmptyArray(exec, nullptr, finalArraySize.unsafeGet());
     435    if (exec->hadException())
     436        return JSValue::encode(jsUndefined());
     437
     438    curArg = thisValue.toObject(exec);
    420439    unsigned n = 0;
    421     JSValue curArg = thisValue.toObject(exec);
    422     if (exec->hadException())
    423         return JSValue::encode(jsUndefined());
    424440    size_t i = 0;
    425     size_t argCount = exec->argumentCount();
    426441    while (1) {
    427         if (curArg.inherits(JSArray::info())) {
    428             unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
    429             JSObject* curObject = curArg.toObject(exec);
     442        if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
     443            unsigned length = currentArray->length();
    430444            for (unsigned k = 0; k < length; ++k) {
    431                 JSValue v = getProperty(exec, curObject, k);
     445                JSValue v = getProperty(exec, currentArray, k);
    432446                if (exec->hadException())
    433447                    return JSValue::encode(jsUndefined());
Note: See TracChangeset for help on using the changeset viewer.