Changeset 48948 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Sep 30, 2009, 2:32:51 PM (16 years ago)
Author:
[email protected]
Message:

Devirtualise array toString conversion

Reviewed by Geoff Garen.

Tweak the implementation of Array.prototype.toString to have a fast path
when acting on a true JSArray.

Location:
trunk/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r48938 r48948  
     12009-09-30  Oliver Hunt  <[email protected]>
     2
     3        Reviewed by Geoff Garen.
     4
     5        Devirtualise array toString conversion
     6
     7        Tweak the implementation of Array.prototype.toString to have a fast path
     8        when acting on a true JSArray.
     9
     10        * runtime/ArrayPrototype.cpp:
     11        (JSC::arrayProtoFuncToString):
     12
    1132009-09-30  Csaba Osztrogonac  <[email protected]>
    214
  • trunk/JavaScriptCore/runtime/ArrayPrototype.cpp

    r48836 r48948  
    150150JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
    151151{
    152     if (!thisValue.inherits(&JSArray::info))
     152    bool isRealArray = isJSArray(&exec->globalData(), thisValue);
     153    if (!isRealArray && !thisValue.inherits(&JSArray::info))
    153154        return throwError(exec, TypeError);
    154     JSObject* thisObj = asArray(thisValue);
    155 
     155    JSArray* thisObj = asArray(thisValue);
     156   
    156157    HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
    157158    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
     
    164165        return jsEmptyString(exec); // return an empty string, avoiding infinite recursion.
    165166
    166     Vector<UChar, 256> strBuffer;
    167     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     167    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     168    unsigned totalSize = length ? length - 1 : 0;
     169    Vector<RefPtr<UString::Rep>, 256> strBuffer(length);
    168170    for (unsigned k = 0; k < length; k++) {
    169         if (k >= 1)
    170             strBuffer.append(',');
     171        JSValue element;
     172        if (isRealArray && thisObj->canGetIndex(k))
     173            element = thisObj->getIndex(k);
     174        else
     175            element = thisObj->get(exec, k);
     176       
     177        if (element.isUndefinedOrNull())
     178            continue;
     179       
     180        UString str = element.toString(exec);
     181        strBuffer[k] = str.rep();
     182        totalSize += str.size();
     183       
    171184        if (!strBuffer.data()) {
    172185            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
    173186            exec->setException(error);
    174             break;
    175         }
    176 
    177         JSValue element = thisObj->get(exec, k);
    178         if (element.isUndefinedOrNull())
    179             continue;
    180 
    181         UString str = element.toString(exec);
    182         strBuffer.append(str.data(), str.size());
    183 
    184         if (!strBuffer.data()) {
    185             JSObject* error = Error::create(exec, GeneralError, "Out of memory");
    186             exec->setException(error);
    187         }
    188 
     187        }
     188       
    189189        if (exec->hadException())
    190190            break;
    191191    }
    192192    arrayVisitedElements.remove(thisObj);
    193     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
     193    if (!totalSize)
     194        return jsEmptyString(exec);
     195    Vector<UChar> buffer;
     196    buffer.reserveCapacity(totalSize);
     197    if (!buffer.data())
     198        return throwError(exec, GeneralError, "Out of memory");
     199       
     200    for (unsigned i = 0; i < length; i++) {
     201        if (i)
     202            buffer.append(',');
     203        if (RefPtr<UString::Rep> rep = strBuffer[i])
     204            buffer.append(rep->data(), rep->size());
     205    }
     206    ASSERT(buffer.size() == totalSize);
     207    unsigned finalSize = buffer.size();
     208    return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false));
    194209}
    195210
Note: See TracChangeset for help on using the changeset viewer.