Ignore:
Timestamp:
Oct 18, 2011, 7:54:29 PM (14 years ago)
Author:
[email protected]
Message:

Switched ropes from malloc memory to GC memory
https://bugs.webkit.org/show_bug.cgi?id=70364

Reviewed by Gavin Barraclough.

~1% SunSpider speedup. Neutral elsewhere. Removes one cause for strings
having C++ destructors.

  • heap/MarkStack.cpp:

(JSC::visitChildren): Call the JSString visitChildren function now,
since it's no longer a no-op.

  • runtime/JSString.cpp:

(JSC::JSString::~JSString): Moved this destructor out of line because
it's called virtually, so there's no value to inlining.

(JSC::JSString::RopeBuilder::expand): Switched RopeBuilder to be a thin
initializing wrapper around JSString. JSString now represents ropes
directly, rather than relying on an underlying malloc object.

(JSC::JSString::visitChildren): Visit our rope fibers, since they're GC
objects now.

(JSC::JSString::resolveRope):
(JSC::JSString::resolveRopeSlowCase):
(JSC::JSString::outOfMemory): Updated for operating on JSStrings instead
of malloc objects.

(JSC::JSString::replaceCharacter): Removed optimizations for substringing
ropes and replacing subsections of ropes. We want to reimplement versions
of these optimizations in the future, but this patch already has good
performance without them.

  • runtime/JSString.h:

(JSC::RopeBuilder::JSString):
(JSC::RopeBuilder::finishCreation):
(JSC::RopeBuilder::createNull):
(JSC::RopeBuilder::create):
(JSC::RopeBuilder::createHasOtherOwner):
(JSC::jsSingleCharacterString):
(JSC::jsSingleCharacterSubstring):
(JSC::jsNontrivialString):
(JSC::jsString):
(JSC::jsSubstring):
(JSC::jsOwnedString): Lots of mechanical changes here. The two important
things are: (1) The fibers in JSString::m_fibers are JSStrings now, not
malloc objects; (2) I simplified the JSString constructor interface to
only accept PassRefPtr<StringImpl>, instead of variations on that like
UString, reducing refcount churn.

  • runtime/JSValue.h:
  • runtime/JSValue.cpp:

(JSC::JSValue::toPrimitiveString): Updated this function to return a
JSString instead of a UString, since that's what clients want now.

  • runtime/Operations.cpp:

(JSC::jsAddSlowCase):

  • runtime/Operations.h:

(JSC::jsString):

  • runtime/SmallStrings.cpp:

(JSC::SmallStrings::createEmptyString): Updated for interface changes above.

  • runtime/StringConstructor.cpp:

(JSC::constructWithStringConstructor):

  • runtime/StringObject.h:

(JSC::StringObject::create): Don't create a new JSString if we already
have a JSString.

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncConcat): Updated for interface changes above.

File:
1 edited

Legend:

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

    r97537 r97827  
    6060    JSString* jsOwnedString(ExecState*, const UString&);
    6161
     62    JSString* jsStringBuilder(JSGlobalData*);
     63
    6264    class JS_EXPORTCLASS JSString : public JSCell {
    6365    public:
     
    6668        friend class SpecializedThunkJIT;
    6769        friend struct ThunkHelpers;
     70        friend JSString* jsStringBuilder(JSGlobalData*);
    6871
    6972        typedef JSCell Base;
     
    7174        class RopeBuilder {
    7275        public:
    73             RopeBuilder(unsigned fiberCount)
    74                 : m_index(0)
    75                 , m_rope(RopeImpl::tryCreateUninitialized(fiberCount))
     76            RopeBuilder(JSGlobalData& globalData)
     77                : m_globalData(globalData)
     78                , m_jsString(jsStringBuilder(&globalData))
    7679            {
    7780            }
    7881
    79             bool isOutOfMemory() { return !m_rope; }
    80 
    81             void append(RopeImpl::Fiber& fiber)
    82             {
    83                 ASSERT(m_rope);
    84                 m_rope->initializeFiber(m_index, fiber);
    85             }
    86             void append(const UString& string)
    87             {
    88                 ASSERT(m_rope);
    89                 m_rope->initializeFiber(m_index, string.impl());
    90             }
    9182            void append(JSString* jsString)
    9283            {
    93                 if (jsString->isRope()) {
    94                     for (unsigned i = 0; i < jsString->m_fiberCount; ++i)
    95                         append(jsString->m_fibers[i]);
    96                 } else
    97                     append(jsString->string());
     84                if (m_jsString->m_fiberCount == JSString::s_maxInternalRopeLength)
     85                    expand();
     86                m_jsString->m_fibers[m_jsString->m_fiberCount].set(m_globalData, m_jsString, jsString);
     87                m_jsString->m_fiberCount += 1;
     88                m_jsString->m_length += jsString->m_length;
    9889            }
    9990
    100             PassRefPtr<RopeImpl> release()
     91            JSString* release()
    10192            {
    102                 ASSERT(m_index == m_rope->fiberCount());
    103                 return m_rope.release();
     93                JSString* tmp = m_jsString;
     94                m_jsString = 0;
     95                return tmp;
    10496            }
    10597
    106             unsigned length() { return m_rope->length(); }
     98            unsigned length() { return m_jsString->m_length; }
    10799
    108100        private:
    109             unsigned m_index;
    110             RefPtr<RopeImpl> m_rope;
     101            void expand();
     102
     103            JSGlobalData& m_globalData;
     104            JSString* m_jsString;
    111105        };
    112106
    113         class RopeIterator {
    114             public:
    115                 RopeIterator() { }
    116 
    117                 RopeIterator(RopeImpl::Fiber* fibers, size_t fiberCount)
    118                 {
    119                     ASSERT(fiberCount);
    120                     m_workQueue.append(WorkItem(fibers, fiberCount));
    121                     skipRopes();
    122                 }
    123 
    124                 RopeIterator& operator++()
    125                 {
    126                     WorkItem& item = m_workQueue.last();
    127                     ASSERT(!RopeImpl::isRope(item.fibers[item.i]));
    128                     if (++item.i == item.fiberCount)
    129                         m_workQueue.removeLast();
    130                     skipRopes();
    131                     return *this;
    132                 }
    133 
    134                 StringImpl* operator*()
    135                 {
    136                     WorkItem& item = m_workQueue.last();
    137                     RopeImpl::Fiber fiber = item.fibers[item.i];
    138                     ASSERT(!RopeImpl::isRope(fiber));
    139                     return static_cast<StringImpl*>(fiber);
    140                 }
    141 
    142                 bool operator!=(const RopeIterator& other) const
    143                 {
    144                     return m_workQueue != other.m_workQueue;
    145                 }
    146 
    147             private:
    148                 struct WorkItem {
    149                     WorkItem(RopeImpl::Fiber* fibers, size_t fiberCount)
    150                         : fibers(fibers)
    151                         , fiberCount(fiberCount)
    152                         , i(0)
    153                     {
    154                     }
    155 
    156                     bool operator!=(const WorkItem& other) const
    157                     {
    158                         return fibers != other.fibers || fiberCount != other.fiberCount || i != other.i;
    159                     }
    160 
    161                     RopeImpl::Fiber* fibers;
    162                     size_t fiberCount;
    163                     size_t i;
    164                 };
    165 
    166                 void skipRopes()
    167                 {
    168                     if (m_workQueue.isEmpty())
    169                         return;
    170 
    171                     while (1) {
    172                         WorkItem& item = m_workQueue.last();
    173                         RopeImpl::Fiber fiber = item.fibers[item.i];
    174                         if (!RopeImpl::isRope(fiber))
    175                             break;
    176                         RopeImpl* rope = static_cast<RopeImpl*>(fiber);
    177                         if (++item.i == item.fiberCount)
    178                             m_workQueue.removeLast();
    179                         m_workQueue.append(WorkItem(rope->fibers(), rope->fiberCount()));
    180                     }
    181                 }
    182 
    183                 Vector<WorkItem, 16> m_workQueue;
    184         };
    185        
    186107    private:
    187         ALWAYS_INLINE JSString(JSGlobalData& globalData, const UString& value)
     108        JSString(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
    188109            : JSCell(globalData, globalData.stringStructure.get())
    189             , m_length(value.length())
    190110            , m_value(value)
    191111            , m_fiberCount(0)
     
    193113        }
    194114
    195         enum HasOtherOwnerType { HasOtherOwner };
    196         JSString(JSGlobalData& globalData, const UString& value, HasOtherOwnerType)
     115        JSString(JSGlobalData& globalData)
    197116            : JSCell(globalData, globalData.stringStructure.get())
    198             , m_length(value.length())
    199             , m_value(value)
    200117            , m_fiberCount(0)
    201118        {
    202119        }
    203         JSString(JSGlobalData& globalData, PassRefPtr<StringImpl> value, HasOtherOwnerType)
    204             : JSCell(globalData, globalData.stringStructure.get())
    205             , m_length(value->length())
    206             , m_value(value)
    207             , m_fiberCount(0)
    208         {
    209         }
    210         JSString(JSGlobalData& globalData, PassRefPtr<RopeImpl> rope)
    211             : JSCell(globalData, globalData.stringStructure.get())
    212             , m_length(rope->length())
    213             , m_fiberCount(1)
    214         {
    215         }
    216         // This constructor constructs a new string by concatenating s1 & s2.
    217         // This should only be called with fiberCount <= 3.
    218         JSString(JSGlobalData& globalData, unsigned fiberCount, JSString* s1, JSString* s2)
    219             : JSCell(globalData, globalData.stringStructure.get())
    220             , m_length(s1->length() + s2->length())
    221             , m_fiberCount(fiberCount)
    222         {
    223         }
    224         // This constructor constructs a new string by concatenating s1 & s2.
    225         // This should only be called with fiberCount <= 3.
    226         JSString(JSGlobalData& globalData, unsigned fiberCount, JSString* s1, const UString& u2)
    227             : JSCell(globalData, globalData.stringStructure.get())
    228             , m_length(s1->length() + u2.length())
    229             , m_fiberCount(fiberCount)
    230         {
    231         }
    232         // This constructor constructs a new string by concatenating s1 & s2.
    233         // This should only be called with fiberCount <= 3.
    234         JSString(JSGlobalData& globalData, unsigned fiberCount, const UString& u1, JSString* s2)
    235             : JSCell(globalData, globalData.stringStructure.get())
    236             , m_length(u1.length() + s2->length())
    237             , m_fiberCount(fiberCount)
    238         {
    239         }
    240         JSString(ExecState* exec)
    241             : JSCell(exec->globalData(), exec->globalData().stringStructure.get())
    242             , m_length(0)
    243             , m_fiberCount(s_maxInternalRopeLength)
    244         {
    245         }
    246 
    247         // This constructor constructs a new string by concatenating u1 & u2.
    248         JSString(JSGlobalData& globalData, const UString& u1, const UString& u2)
    249             : JSCell(globalData, globalData.stringStructure.get())
    250             , m_length(u1.length() + u2.length())
    251             , m_fiberCount(2)
    252         {
    253         }
    254 
    255         // This constructor constructs a new string by concatenating u1, u2 & u3.
    256         JSString(JSGlobalData& globalData, const UString& u1, const UString& u2, const UString& u3)
    257             : JSCell(globalData, globalData.stringStructure.get())
    258             , m_length(u1.length() + u2.length() + u3.length())
    259             , m_fiberCount(s_maxInternalRopeLength)
    260         {
    261         }
    262 
    263         void finishCreation(JSGlobalData& globalData, const UString& value)
     120
     121        void finishCreation(JSGlobalData& globalData)
    264122        {
    265123            Base::finishCreation(globalData);
     124            m_length = 0;
     125        }
     126
     127        void finishCreation(JSGlobalData& globalData, size_t length)
     128        {
    266129            ASSERT(!m_value.isNull());
    267             Heap::heap(this)->reportExtraMemoryCost(value.impl()->cost());
    268         }
    269 
    270         void finishCreation(JSGlobalData& globalData)
    271         {
    272130            Base::finishCreation(globalData);
     131            m_length = length;
     132        }
     133
     134        void finishCreation(JSGlobalData& globalData, size_t length, size_t cost)
     135        {
    273136            ASSERT(!m_value.isNull());
    274         }
    275 
    276         void finishCreation(JSGlobalData& globalData, PassRefPtr<RopeImpl> rope)
    277         {
    278137            Base::finishCreation(globalData);
    279             m_fibers[0] = rope.leakRef();
    280         }
    281 
    282         void finishCreation(JSGlobalData& globalData, unsigned fiberCount, JSString* s1, JSString* s2)
     138            m_length = length;
     139            Heap::heap(this)->reportExtraMemoryCost(cost);
     140        }
     141
     142        void finishCreation(JSGlobalData& globalData, JSString* s1, JSString* s2)
    283143        {
    284144            Base::finishCreation(globalData);
    285             ASSERT_UNUSED(fiberCount, fiberCount <= s_maxInternalRopeLength);
    286             unsigned index = 0;
    287             appendStringInCreate(index, s1);
    288             appendStringInCreate(index, s2);
    289             ASSERT(fiberCount == index);
    290         }
    291 
    292         void finishCreation(JSGlobalData& globalData, unsigned fiberCount, JSString* s1, const UString& u2)
     145            m_length = s1->length() + s2->length();
     146            m_fiberCount = 2;
     147            m_fibers[0].set(globalData, this, s1);
     148            m_fibers[1].set(globalData, this, s2);
     149        }
     150
     151        void finishCreation(JSGlobalData& globalData, JSString* s1, JSString* s2, JSString* s3)
    293152        {
    294153            Base::finishCreation(globalData);
    295             ASSERT_UNUSED(fiberCount, fiberCount <= s_maxInternalRopeLength);
    296             unsigned index = 0;
    297             appendStringInCreate(index, s1);
    298             appendStringInCreate(index, u2);
    299             ASSERT(fiberCount == index);
    300         }
    301 
    302         void finishCreation(JSGlobalData& globalData, unsigned fiberCount, const UString& u1, JSString* s2)
    303         {
    304             Base::finishCreation(globalData);
    305             ASSERT_UNUSED(fiberCount, fiberCount <= s_maxInternalRopeLength);
    306             unsigned index = 0;
    307             appendStringInCreate(index, u1);
    308             appendStringInCreate(index, s2);
    309             ASSERT(fiberCount == index);
    310         }
    311 
    312         // Fills in the new string by concatenating v1, v2 & v3.
    313         // This should only be called with fiberCount <= 3 ... which since every
    314         // value must require a fiberCount of at least one implies that the length
    315         // for each value must be exactly 1!
    316         void finishCreation(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
    317         {
    318             Base::finishCreation(exec->globalData());
    319             unsigned index = 0;
    320             appendValueInCreateAndIncrementLength(exec, index, v1);
    321             appendValueInCreateAndIncrementLength(exec, index, v2);
    322             appendValueInCreateAndIncrementLength(exec, index, v3);
    323             ASSERT(index == s_maxInternalRopeLength);
    324         }
    325 
    326         void finishCreation(JSGlobalData& globalData, const UString& u1, const UString& u2)
    327         {
    328             Base::finishCreation(globalData);
    329             unsigned index = 0;
    330             appendStringInCreate(index, u1);
    331             appendStringInCreate(index, u2);
    332             ASSERT(index <= s_maxInternalRopeLength);
    333         }
    334 
    335         void finishCreation(JSGlobalData& globalData, const UString& u1, const UString& u2, const UString& u3)
    336         {
    337             Base::finishCreation(globalData);
    338             unsigned index = 0;
    339             appendStringInCreate(index, u1);
    340             appendStringInCreate(index, u2);
    341             appendStringInCreate(index, u3);
    342             ASSERT(index <= s_maxInternalRopeLength);
    343         }
    344 
    345     public:
    346         static JSString* create(JSGlobalData& globalData, const UString& value)
    347         {
    348             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
    349             newString->finishCreation(globalData, value);
    350             return newString;
    351         }
    352         static JSString* createHasOtherOwner(JSGlobalData& globalData, const UString& value)
    353         {
    354             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, value, HasOtherOwner);
    355             newString->finishCreation(globalData, value);
    356             return newString;
    357         }
    358         static JSString* createHasOtherOwner(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
    359         {
    360             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, value, HasOtherOwner);
     154            m_length = s1->length() + s2->length() + s3->length();
     155            m_fiberCount = 3;
     156            m_fibers[0].set(globalData, this, s1);
     157            m_fibers[1].set(globalData, this, s2);
     158            m_fibers[2].set(globalData, this, s3);
     159        }
     160
     161        static JSString* createNull(JSGlobalData& globalData)
     162        {
     163            JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData);
    361164            newString->finishCreation(globalData);
    362165            return newString;
    363166        }
    364         static JSString* create(JSGlobalData& globalData, PassRefPtr<RopeImpl> rope)
    365         {
    366             RefPtr<RopeImpl> tempRope = rope;
    367             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, tempRope);
    368             newString->finishCreation(globalData, tempRope);
     167
     168    public:
     169        static JSString* create(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
     170        {
     171            ASSERT(value);
     172            size_t length = value->length();
     173            size_t cost = value->cost();
     174            JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
     175            newString->finishCreation(globalData, length, cost);
    369176            return newString;
    370177        }
    371         static JSString* create(JSGlobalData& globalData, unsigned fiberCount, JSString* s1, JSString* s2)
    372         {
    373             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, fiberCount, s1, s2);
    374             newString->finishCreation(globalData, fiberCount, s1, s2);
     178        static JSString* create(JSGlobalData& globalData, JSString* s1, JSString* s2)
     179        {
     180            JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData);
     181            newString->finishCreation(globalData, s1, s2);
    375182            return newString;
    376183        }
    377         static JSString* create(JSGlobalData& globalData, unsigned fiberCount, JSString* s1, const UString& u2)
    378         {
    379             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, fiberCount, s1, u2);
    380             newString->finishCreation(globalData, fiberCount, s1, u2);
     184        static JSString* create(JSGlobalData& globalData, JSString* s1, JSString* s2, JSString* s3)
     185        {
     186            JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData);
     187            newString->finishCreation(globalData, s1, s2, s3);
    381188            return newString;
    382189        }
    383         static JSString* create(JSGlobalData& globalData, unsigned fiberCount, const UString& u1, JSString* s2)
    384         {
    385             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, fiberCount, u1, s2);
    386             newString->finishCreation(globalData, fiberCount, u1, s2);
     190        static JSString* createHasOtherOwner(JSGlobalData& globalData, PassRefPtr<StringImpl> value)
     191        {
     192            ASSERT(value);
     193            size_t length = value->length();
     194            JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, value);
     195            newString->finishCreation(globalData, length);
    387196            return newString;
    388197        }
    389         static JSString* create(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
    390         {
    391             JSString* newString = new (allocateCell<JSString>(*exec->heap())) JSString(exec);
    392             newString->finishCreation(exec, v1, v2, v3);
    393             return newString;
    394         }
    395         static JSString* create(JSGlobalData& globalData, const UString& u1, const UString& u2)
    396         {
    397             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, u1, u2);
    398             newString->finishCreation(globalData, u1, u2);
    399             return newString;
    400         }
    401         static JSString* create(JSGlobalData& globalData, const UString& u1, const UString& u2, const UString& u3)
    402         {
    403             JSString* newString = new (allocateCell<JSString>(globalData.heap)) JSString(globalData, u1, u2, u3);
    404             newString->finishCreation(globalData, u1, u2, u3);
    405             return newString;
    406         }
    407 
    408         ~JSString()
    409         {
    410             ASSERT(vptr() == JSGlobalData::jsStringVPtr);
    411             for (unsigned i = 0; i < m_fiberCount; ++i)
    412                 RopeImpl::deref(m_fibers[i]);
    413         }
     198
     199        virtual ~JSString();
    414200
    415201        const UString& value(ExecState* exec) const
     
    455241        static const ClassInfo s_info;
    456242
     243        static void visitChildren(JSCell*, SlotVisitor&);
     244
    457245    private:
    458246        JSString(VPtrStealingHackType)
     
    465253        void resolveRopeSlowCase(ExecState*, UChar*) const;
    466254        void outOfMemory(ExecState*) const;
    467         JSString* substringFromRope(ExecState*, unsigned offset, unsigned length);
    468 
    469         void appendStringInCreate(unsigned& index, const UString& string)
    470         {
    471             StringImpl* impl = string.impl();
    472             impl->ref();
    473             m_fibers[index++] = impl;
    474             Heap::heap(this)->reportExtraMemoryCost(string.impl()->cost());
    475         }
    476 
    477         void appendStringInCreate(unsigned& index, JSString* jsString)
    478         {
    479             if (jsString->isRope()) {
    480                 for (unsigned i = 0; i < jsString->m_fiberCount; ++i) {
    481                     RopeImpl::Fiber fiber = jsString->m_fibers[i];
    482                     fiber->ref();
    483                     m_fibers[index++] = fiber;
    484                 }
    485             } else
    486                 appendStringInCreate(index, jsString->string());
    487         }
    488 
    489         void appendValueInCreateAndIncrementLength(ExecState* exec, unsigned& index, JSValue v)
    490         {
    491             if (v.isString()) {
    492                 ASSERT(v.asCell()->isString());
    493                 JSString* s = static_cast<JSString*>(v.asCell());
    494                 ASSERT(s->fiberCount() == 1);
    495                 appendStringInCreate(index, s);
    496                 m_length += s->length();
    497             } else {
    498                 UString u(v.toString(exec));
    499                 StringImpl* impl = u.impl();
    500                 impl->ref();
    501                 m_fibers[index++] = impl;
    502                 m_length += u.length();
    503             }
    504         }
    505255
    506256        virtual JSObject* toThisObject(ExecState*) const;
     
    519269        mutable UString m_value;
    520270        mutable unsigned m_fiberCount;
    521         mutable FixedArray<RopeImpl::Fiber, s_maxInternalRopeLength> m_fibers;
     271        mutable FixedArray<WriteBarrier<JSString>, s_maxInternalRopeLength> m_fibers;
    522272
    523273        bool isRope() const { return m_fiberCount; }
     
    526276
    527277        friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
    528         friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
    529         friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2);
    530278        friend JSValue jsString(ExecState* exec, Register* strings, unsigned count);
    531279        friend JSValue jsString(ExecState* exec, JSValue thisValue);
     
    560308        if (c <= maxSingleCharacterString)
    561309            return globalData->smallStrings.singleCharacterString(globalData, c);
    562         return fixupVPtr(globalData, JSString::create(*globalData, UString(&c, 1)));
     310        return fixupVPtr(globalData, JSString::create(*globalData, UString(&c, 1).impl()));
    563311    }
    564312
     
    570318        if (c <= maxSingleCharacterString)
    571319            return globalData->smallStrings.singleCharacterString(globalData, c);
    572         return fixupVPtr(globalData, JSString::create(*globalData, UString(StringImpl::create(s.impl(), offset, 1))));
     320        return fixupVPtr(globalData, JSString::create(*globalData, StringImpl::create(s.impl(), offset, 1)));
    573321    }
    574322
     
    578326        ASSERT(s[0]);
    579327        ASSERT(s[1]);
    580         return fixupVPtr(globalData, JSString::create(*globalData, s));
     328        return fixupVPtr(globalData, JSString::create(*globalData, UString(s).impl()));
    581329    }
    582330
     
    584332    {
    585333        ASSERT(s.length() > 1);
    586         return fixupVPtr(globalData, JSString::create(*globalData, s));
     334        return fixupVPtr(globalData, JSString::create(*globalData, s.impl()));
    587335    }
    588336
     
    606354                return globalData->smallStrings.singleCharacterString(globalData, c);
    607355        }
    608         return fixupVPtr(globalData, JSString::create(*globalData, s));
     356        return fixupVPtr(globalData, JSString::create(*globalData, s.impl()));
    609357    }
    610358
     
    617365        if (!length)
    618366            return globalData->smallStrings.emptyString(globalData);
    619         if (s->isRope())
    620             return s->substringFromRope(exec, offset, length);
    621         return jsSubstring(globalData, s->m_value, offset, length);
     367        return jsSubstring(globalData, s->value(exec), offset, length);
    622368    }
    623369
     
    634380                return globalData->smallStrings.singleCharacterString(globalData, c);
    635381        }
    636         return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, UString(StringImpl::create(s.impl(), offset, length))));
     382        return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length)));
    637383    }
    638384
     
    647393                return globalData->smallStrings.singleCharacterString(globalData, c);
    648394        }
    649         return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, s));
     395        return fixupVPtr(globalData, JSString::createHasOtherOwner(*globalData, s.impl()));
     396    }
     397
     398    inline JSString* jsStringBuilder(JSGlobalData* globalData)
     399    {
     400        return fixupVPtr(globalData, JSString::createNull(*globalData));
    650401    }
    651402
     
    727478    }
    728479
    729     inline UString JSValue::toPrimitiveString(ExecState* exec) const
    730     {
    731         ASSERT(!isString());
    732         if (isInt32())
    733             return exec->globalData().numericStrings.add(asInt32());
    734         if (isDouble())
    735             return exec->globalData().numericStrings.add(asDouble());
    736         if (isTrue())
    737             return "true";
    738         if (isFalse())
    739             return "false";
    740         if (isNull())
    741             return "null";
    742         if (isUndefined())
    743             return "undefined";
    744         ASSERT(isCell());
    745         return asCell()->toPrimitive(exec, NoPreference).toString(exec);
    746     }
    747 
    748480} // namespace JSC
    749481
Note: See TracChangeset for help on using the changeset viewer.