Ignore:
Timestamp:
May 11, 2010, 11:42:46 AM (15 years ago)
Author:
[email protected]
Message:

Start using ropes in String.prototype.replace.

Reviewed by Oliver Hunt and Darin Adler.

1%-1.5% speedup on SunSpider.

  • runtime/JSString.cpp:

(JSC::JSString::resolveRope): Updated for RopeImpl refactoring.

(JSC::JSString::replaceCharacter): Added a replaceCharacter function, which creates
a rope for the resulting replacement.

  • runtime/JSString.h: A few changes here:

(JSC::):
(JSC::RopeBuilder::RopeIterator::RopeIterator):
(JSC::RopeBuilder::RopeIterator::operator++):
(JSC::RopeBuilder::RopeIterator::operator*):
(JSC::RopeBuilder::RopeIterator::operator!=):
(JSC::RopeBuilder::RopeIterator::WorkItem::WorkItem):
(JSC::RopeBuilder::RopeIterator::WorkItem::operator!=):
(JSC::RopeBuilder::RopeIterator::skipRopes): Created a RopeIterator abstraction.
We use this to do a substring find without having to resolve the rope.
(We could use this iterator when resolving ropes, too, but resolving
ropes backwards is usually more efficient.)

(JSC::RopeBuilder::JSString): Added constructors for 2 & 3 UStrings.

(JSC::RopeBuilder::appendValueInConstructAndIncrementLength):
(JSC::RopeBuilder::size): Updated for RopeImpl refactoring.

  • runtime/Operations.h: Updated for RopeImpl refactoring.

(JSC::jsString): Added jsString functions for 2 & 3 UStrings.

  • runtime/RopeImpl.cpp:

(JSC::RopeImpl::derefFibersNonRecursive):

  • runtime/RopeImpl.h:

(JSC::RopeImpl::initializeFiber):
(JSC::RopeImpl::size):
(JSC::RopeImpl::fibers):
(JSC::RopeImpl::deref):
(JSC::RopeImpl::RopeImpl): A little refactoring to make this patch easier:
Moved statics to the top of the class; put multi-statement functions on
multiple lines; renamed "fiberCount" to "size" to match other collections;
changed the "fibers" accessor to return the fibers buffer, instead of an
item in the buffer, to make iteration easier.

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncReplace): Don't resolve a rope unless we need to. Do
use our new replaceCharacter function if possible. Do use a rope to
represent splicing three strings together.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Operations.h

    r54925 r59161  
    4747            return throwOutOfMemoryError(exec);
    4848
    49         unsigned fiberCount = s1->fiberCount() + s2->fiberCount();
     49        unsigned fiberCount = s1->size() + s2->size();
    5050        JSGlobalData* globalData = &exec->globalData();
    5151
     
    7272            return throwOutOfMemoryError(exec);
    7373
    74         unsigned fiberCount = 1 + s2->fiberCount();
     74        unsigned fiberCount = 1 + s2->size();
    7575        JSGlobalData* globalData = &exec->globalData();
    7676
     
    9797            return throwOutOfMemoryError(exec);
    9898
    99         unsigned fiberCount = s1->fiberCount() + 1;
     99        unsigned fiberCount = s1->size() + 1;
    100100        JSGlobalData* globalData = &exec->globalData();
    101101
     
    109109        ropeBuilder.append(u2);
    110110        return new (globalData) JSString(globalData, ropeBuilder.release());
     111    }
     112
     113    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2)
     114    {
     115        unsigned length1 = u1.size();
     116        if (!length1)
     117            return jsString(exec, u2);
     118        unsigned length2 = u2.size();
     119        if (!length2)
     120            return jsString(exec, u1);
     121        if ((length1 + length2) < length1)
     122            return throwOutOfMemoryError(exec);
     123
     124        JSGlobalData* globalData = &exec->globalData();
     125        return new (globalData) JSString(globalData, u1, u2);
     126    }
     127
     128    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3)
     129    {
     130        unsigned length1 = u1.size();
     131        unsigned length2 = u2.size();
     132        unsigned length3 = u3.size();
     133        if (!length1)
     134            return jsString(exec, u2, u3);
     135        if (!length2)
     136            return jsString(exec, u1, u3);
     137        if (!length3)
     138            return jsString(exec, u1, u2);
     139
     140        if ((length1 + length2) < length1)
     141            return throwOutOfMemoryError(exec);
     142        if ((length1 + length2 + length3) < length3)
     143            return throwOutOfMemoryError(exec);
     144
     145        JSGlobalData* globalData = &exec->globalData();
     146        return new (globalData) JSString(globalData, u1, u2, u3);
    111147    }
    112148
     
    119155            JSValue v = strings[i].jsValue();
    120156            if (LIKELY(v.isString()))
    121                 fiberCount += asString(v)->fiberCount();
     157                fiberCount += asString(v)->size();
    122158            else
    123159                ++fiberCount;
     
    158194        unsigned fiberCount = 0;
    159195        if (LIKELY(thisValue.isString()))
    160             fiberCount += asString(thisValue)->fiberCount();
     196            fiberCount += asString(thisValue)->size();
    161197        else
    162198            ++fiberCount;
     
    164200            JSValue v = args.at(i);
    165201            if (LIKELY(v.isString()))
    166                 fiberCount += asString(v)->fiberCount();
     202                fiberCount += asString(v)->size();
    167203            else
    168204                ++fiberCount;
Note: See TracChangeset for help on using the changeset viewer.