Ignore:
Timestamp:
Apr 21, 2011, 10:23:16 AM (14 years ago)
Author:
[email protected]
Message:

2011-04-20 Michael Saboff <[email protected]>

Reviewed by Geoff Garen.

JSString::resolveRope inefficient for common 2 fiber case
https://bugs.webkit.org/show_bug.cgi?id=58994

Split JSString::resolveRope into three routines.
resolveRope allocates the new buffer and handles the 1 or 2
fiber case with single level fibers.
resolveRopeSlowCase handles the general case.
outOfMemory handles the rare out of memory exception case.

  • runtime/JSString.cpp: (JSC::JSString::resolveRope): (JSC::JSString::resolveRopeSlowCase): (JSC::JSString::outOfMemory):
  • runtime/JSString.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSString.cpp

    r82173 r84515  
    3535static const unsigned substringFromRopeCutoff = 4;
    3636
     37void JSString::resolveRope(ExecState* exec) const
     38{
     39    ASSERT(isRope());
     40
     41    UChar* buffer;
     42    if (PassRefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer))
     43        m_value = newImpl;
     44    else {
     45        outOfMemory(exec);
     46        return;
     47    }
     48
     49    RopeImpl::Fiber currentFiber = m_other.m_fibers[0];
     50
     51    if ((m_fiberCount > 2) || (RopeImpl::isRope(currentFiber))
     52        || ((m_fiberCount == 2) && (RopeImpl::isRope(m_other.m_fibers[1])))) {
     53        resolveRopeSlowCase(exec, buffer);
     54        return;
     55    }
     56
     57    UChar* position = buffer;
     58    StringImpl* string = static_cast<StringImpl*>(currentFiber);
     59    unsigned length = string->length();
     60    StringImpl::copyChars(position, string->characters(), length);
     61
     62    if (m_fiberCount > 1) {
     63        position += length;
     64        currentFiber = m_other.m_fibers[1];
     65        string = static_cast<StringImpl*>(currentFiber);
     66        length = string->length();
     67        StringImpl::copyChars(position, string->characters(), length);
     68        position += length;
     69    }
     70
     71    ASSERT((buffer + m_length) == position);
     72    for (unsigned i = 0; i < m_fiberCount; ++i) {
     73        RopeImpl::deref(m_other.m_fibers[i]);
     74        m_other.m_fibers[i] = 0;
     75    }
     76    m_fiberCount = 0;
     77
     78    ASSERT(!isRope());
     79}
     80
    3781// Overview: this methods converts a JSString from holding a string in rope form
    3882// down to a simple UString representation.  It does so by building up the string
     
    4488// Vector before performing any concatenation, but by working backwards we likely
    4589// only fill the queue with the number of substrings at any given level in a
    46 // rope-of-ropes.)
    47 void JSString::resolveRope(ExecState* exec) const
    48 {
    49     ASSERT(isRope());
    50 
    51     // Allocate the buffer to hold the final string, position initially points to the end.
    52     UChar* buffer;
    53     if (PassRefPtr<StringImpl> newImpl = StringImpl::tryCreateUninitialized(m_length, buffer))
    54         m_value = newImpl;
    55     else {
    56         for (unsigned i = 0; i < m_fiberCount; ++i) {
    57             RopeImpl::deref(m_other.m_fibers[i]);
    58             m_other.m_fibers[i] = 0;
    59         }
    60         m_fiberCount = 0;
    61         ASSERT(!isRope());
    62         ASSERT(m_value == UString());
    63         if (exec)
    64             throwOutOfMemoryError(exec);
    65         return;
    66     }
     90// rope-of-ropes.)   
     91void JSString::resolveRopeSlowCase(ExecState* exec, UChar* buffer) const
     92{
     93    UNUSED_PARAM(exec);
     94
    6795    UChar* position = buffer + m_length;
    6896
     
    97125                }
    98126                m_fiberCount = 0;
    99 
     127               
    100128                ASSERT(!isRope());
    101129                return;
     
    108136    }
    109137}
    110    
     138
     139void JSString::outOfMemory(ExecState* exec) const
     140{
     141    for (unsigned i = 0; i < m_fiberCount; ++i) {
     142        RopeImpl::deref(m_other.m_fibers[i]);
     143        m_other.m_fibers[i] = 0;
     144    }
     145    m_fiberCount = 0;
     146    ASSERT(!isRope());
     147    ASSERT(m_value == UString());
     148    if (exec)
     149        throwOutOfMemoryError(exec);
     150}
     151
    111152// This function construsts a substring out of a rope without flattening by reusing the existing fibers.
    112153// This can reduce memory usage substantially. Since traversing ropes is slow the function will revert
Note: See TracChangeset for help on using the changeset viewer.