Ignore:
Timestamp:
Dec 10, 2009, 2:13:15 PM (15 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=32367
Add support for short Ropes (up to 3 entries) inline within JSString.
(rather than externally allocating an object to hold the rope).
Switch jsAdd of (JSString* + JSString*) to now make use of Ropes.

Reviewed by Oliver Hunt & Mark Rowe.

~1% progression on Sunspidey.

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::privateExecute):

  • jit/JITOpcodes.cpp:

(JSC::JIT::privateCompileCTIMachineTrampolines):

  • jit/JITStubs.cpp:

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/JSString.cpp:

(JSC::JSString::resolveRope):
(JSC::JSString::toBoolean):
(JSC::JSString::getStringPropertyDescriptor):

  • runtime/JSString.h:

(JSC::JSString::Rope::Fiber::deref):
(JSC::JSString::Rope::Fiber::ref):
(JSC::JSString::Rope::Fiber::refAndGetLength):
(JSC::JSString::Rope::append):
(JSC::JSString::JSString):
(JSC::JSString::~JSString):
(JSC::JSString::value):
(JSC::JSString::tryGetValue):
(JSC::JSString::length):
(JSC::JSString::canGetIndex):
(JSC::JSString::appendStringInConstruct):
(JSC::JSString::appendValueInConstructAndIncrementLength):
(JSC::JSString::isRope):
(JSC::JSString::string):
(JSC::JSString::ropeLength):
(JSC::JSString::getStringPropertySlot):

  • runtime/Operations.h:

(JSC::jsString):
(JSC::jsAdd):
(JSC::resolveBase):

File:
1 edited

Legend:

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

    r51933 r51964  
    3636    bool jsIsFunctionType(JSValue);
    3737
     38    ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
     39    {
     40        unsigned ropeLength = s1->ropeLength() + s2->ropeLength();
     41        JSGlobalData* globalData = &exec->globalData();
     42
     43        if (ropeLength <= JSString::s_maxInternalRopeLength)
     44            return new (globalData) JSString(globalData, ropeLength, s1, s2);
     45
     46        unsigned index = 0;
     47        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
     48        if (UNLIKELY(!rope))
     49            return throwOutOfMemoryError(exec);
     50        rope->append(index, s1);
     51        rope->append(index, s2);
     52        ASSERT(index == ropeLength);
     53        return new (globalData) JSString(globalData, rope.release());
     54    }
     55
     56    ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
     57    {
     58        ASSERT(count >= 3);
     59
     60        unsigned ropeLength = 0;
     61        for (unsigned i = 0; i < count; ++i) {
     62            JSValue v = strings[i].jsValue();
     63            if (LIKELY(v.isString()))
     64                ropeLength += asString(v)->ropeLength();
     65            else
     66                ++ropeLength;
     67        }
     68
     69        JSGlobalData* globalData = &exec->globalData();
     70        if (ropeLength == 3)
     71            return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue());
     72
     73        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
     74        if (UNLIKELY(!rope))
     75            return throwOutOfMemoryError(exec);
     76
     77        unsigned index = 0;
     78        for (unsigned i = 0; i < count; ++i) {
     79            JSValue v = strings[i].jsValue();
     80            if (LIKELY(v.isString()))
     81                rope->append(index, asString(v));
     82            else
     83                rope->append(index, v.toString(exec));
     84        }
     85
     86        ASSERT(index == ropeLength);
     87        return new (globalData) JSString(globalData, rope.release());
     88    }
     89
    3890    // ECMA 11.9.3
    3991    inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
     
    205257        bool leftIsString = v1.isString();
    206258        if (leftIsString && v2.isString()) {
    207             if (asString(v1)->isRope() || asString(v2)->isRope()) {
    208                 RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(2);
    209                 if (UNLIKELY(!rope))
    210                     return throwOutOfMemoryError(callFrame);
    211                 rope->initializeFiber(0, asString(v1));
    212                 rope->initializeFiber(1, asString(v2));
    213                 JSGlobalData* globalData = &callFrame->globalData();
    214                 return new (globalData) JSString(globalData, rope.release());
    215             }
    216 
    217             RefPtr<UString::Rep> value = concatenate(asString(v1)->value(callFrame).rep(), asString(v2)->value(callFrame).rep());
    218             if (!value)
    219                 return throwOutOfMemoryError(callFrame);
    220             return jsString(callFrame, value.release());
     259            if (!asString(v1)->length())
     260                return asString(v2);
     261            if (!asString(v2)->length())
     262                return asString(v1);
     263            return jsString(callFrame, asString(v1), asString(v2));
    221264        }
    222265
     
    304347        return JSValue();
    305348    }
    306 
    307     ALWAYS_INLINE JSValue concatenateStrings(CallFrame* callFrame, Register* strings, unsigned count)
    308     {
    309         ASSERT(count >= 3);
    310 
    311         RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(count);
    312         if (UNLIKELY(!rope))
    313             return throwOutOfMemoryError(callFrame);
    314 
    315         for (unsigned i = 0; i < count; ++i) {
    316             JSValue v = strings[i].jsValue();
    317             if (LIKELY(v.isString()))
    318                 rope->initializeFiber(i, asString(v));
    319             else
    320                 rope->initializeFiber(i, v.toString(callFrame));
    321         }
    322 
    323         JSGlobalData* globalData = &callFrame->globalData();
    324         return new (globalData) JSString(globalData, rope.release());
    325     }
    326349} // namespace JSC
    327350
Note: See TracChangeset for help on using the changeset viewer.