Changeset 42282 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Apr 7, 2009, 2:15:33 PM (16 years ago)
Author:
[email protected]
Message:

2009-04-07 David Levin <[email protected]>

Reviewed by Sam Weinig and Geoff Garen.

https://bugs.webkit.org/show_bug.cgi?id=25039
UString refactoring to support UChar* sharing.

No change in sunspider perf.

  • runtime/SmallStrings.cpp: (JSC::SmallStringsStorage::SmallStringsStorage):
  • runtime/UString.cpp: (JSC::initializeStaticBaseString): (JSC::initializeUString): (JSC::UString::BaseString::isShared): Encapsulate the meaning behind the refcount == 1 checks because this needs to do slightly more when sharing is added. (JSC::concatenate): (JSC::UString::append): (JSC::UString::operator=):
  • runtime/UString.h: Make m_baseString part of a union to get rid of casts, but make it protected because it is tricky to use it correctly since it is only valid when the Rep is not a BaseString. The void* will be filled in when sharing is added.

Add constructors due to the making members protected and it make ensuring proper
initialization work better (like in SmallStringsStorage).
(JSC::UString::Rep::create):
(JSC::UString::Rep::Rep):
(JSC::UString::Rep::):
(JSC::UString::BaseString::BaseString):
(JSC::UString::Rep::setBaseString):
(JSC::UString::Rep::baseString):

Location:
trunk/JavaScriptCore/runtime
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/SmallStrings.cpp

    r39956 r42282  
    4848
    4949SmallStringsStorage::SmallStringsStorage()
     50    : m_base(m_characters, numCharactersToStore)
    5051{
    51     for (unsigned i = 0; i < numCharactersToStore; ++i)
    52         m_characters[i] = i;
    53 
    5452    m_base.rc = numCharactersToStore + 1;
    55     m_base.buf = m_characters;
    56     m_base.len = numCharactersToStore;
    57     m_base.offset = 0;
    58     m_base._hash = 0;
    59     m_base.m_baseString = 0;
    60     m_base.preCapacity = 0;
    61     m_base.usedPreCapacity = 0;
    62     m_base.reportedCost = 0;
    63 
    6453    // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
    6554    m_base.usedCapacity = numCharactersToStore + 1;
    6655    m_base.capacity = numCharactersToStore + 1;
    6756    m_base.checkConsistency();
     57
     58    for (unsigned i = 0; i < numCharactersToStore; ++i)
     59        m_characters[i] = i;
    6860
    6961    memset(&m_reps, 0, sizeof(m_reps));
  • trunk/JavaScriptCore/runtime/UString.cpp

    r41879 r42282  
    192192UString* UString::nullUString;
    193193
    194 static void initializeStaticBaseString(int len, UChar* buf, UString::BaseString& base)
    195 {
    196     base.offset = 0;
    197     base.len = len;
     194static void initializeStaticBaseString(UString::BaseString& base)
     195{
    198196    base.rc = INT_MAX / 2;
    199     base._hash = 0;
    200197    base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
    201     base.m_baseString = 0;
    202     base.buf = buf;
    203     base.preCapacity = 0;
    204     base.usedPreCapacity = 0;
    205     base.capacity = 0;
    206     base.usedCapacity = 0;
    207     base.reportedCost = 0;
    208198    base.checkConsistency();
    209199}
     
    211201void initializeUString()
    212202{
    213     UString::Rep::nullBaseString = new UString::BaseString;
    214     initializeStaticBaseString(0, 0, *UString::Rep::nullBaseString);
    215 
    216     UString::Rep::emptyBaseString = new UString::BaseString;
    217     initializeStaticBaseString(0, &sharedEmptyChar, *UString::Rep::emptyBaseString);
     203    UString::Rep::nullBaseString = new UString::BaseString(0, 0);
     204    initializeStaticBaseString(*UString::Rep::nullBaseString);
     205
     206    UString::Rep::emptyBaseString = new UString::BaseString(&sharedEmptyChar, 0);
     207    initializeStaticBaseString(*UString::Rep::emptyBaseString);
    218208
    219209    UString::nullUString = new UString;
     
    227217    copyChars(copyD, d, l);
    228218    return create(copyD, l);
    229 }
    230 
    231 PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
    232 {
    233     BaseString* r = new BaseString;
    234     r->offset = 0;
    235     r->len = l;
    236     r->rc = 1;
    237     r->_hash = 0;
    238     r->m_baseString = 0;
    239     r->reportedCost = 0;
    240     r->buf = d;
    241     r->usedCapacity = l;
    242     r->capacity = l;
    243     r->usedPreCapacity = 0;
    244     r->preCapacity = 0;
    245 
    246     r->checkConsistency();
    247 
    248     // steal the single reference this Rep was created with
    249     return adoptRef(r);
    250 }
    251 
    252 PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> rep, int offset, int length)
    253 {
    254     ASSERT(rep);
    255     rep->checkConsistency();
    256 
    257     int repOffset = rep->offset;
    258 
    259     PassRefPtr<BaseString> base = rep->baseString();
    260 
    261     ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
    262     ASSERT(offset + repOffset + length <= base->usedCapacity);
    263 
    264     Rep* r = new Rep;
    265     r->offset = repOffset + offset;
    266     r->len = length;
    267     r->rc = 1;
    268     r->_hash = 0;
    269     r->setBaseString(base);
    270 
    271     r->checkConsistency();
    272 
    273     // steal the single reference this Rep was created with
    274     return adoptRef(r);
    275219}
    276220
     
    565509        // this is empty
    566510        rep = UString::Rep::createCopying(tData, tSize);
    567     } else if (rep == base && rep->rc == 1) {
     511    } else if (rep == base && !base->isShared()) {
    568512        // this is direct and has refcount of 1 (so we can just alter it directly)
    569513        if (!expandCapacity(rep.get(), thisOffset + length))
     
    619563    } else if (tSize == 0) {
    620564        // t is empty, we'll just return *this below.
    621     } else if (rep == base && rep->rc == 1) {
     565    } else if (rep == base && !base->isShared()) {
    622566        // this is direct and has refcount of 1 (so we can just alter it directly)
    623567        expandCapacity(rep.get(), thisOffset + length);
     
    1042986    } else if (tSize == 0) {
    1043987        // t is empty
    1044     } else if (m_rep == base && m_rep->rc == 1) {
     988    } else if (m_rep == base && !base->isShared()) {
    1045989        // this is direct and has refcount of 1 (so we can just alter it directly)
    1046990        expandCapacity(thisOffset + length);
     
    11091053            m_rep->baseString()->capacity = newCapacity;
    11101054        }
    1111     } else if (m_rep == base && m_rep->rc == 1) {
     1055    } else if (m_rep == base && !base->isShared()) {
    11121056        // this is direct and has refcount of 1 (so we can just alter it directly)
    11131057        expandCapacity(thisOffset + length + 1);
     
    12031147    UChar* d;
    12041148    BaseString* base = m_rep->baseString();
    1205     if (m_rep->rc == 1 && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
     1149    if (!base->isShared() && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
    12061150        d = base->buf;
    12071151        m_rep->_hash = 0;
  • trunk/JavaScriptCore/runtime/UString.h

    r39815 r42282  
    8080            friend class JIT;
    8181
    82             static PassRefPtr<Rep> create(UChar*, int);
     82            static PassRefPtr<Rep> create(UChar* buffer, int length)
     83            {
     84                return adoptRef(new BaseString(buffer, length));
     85            }
     86
    8387            static PassRefPtr<Rep> createCopying(const UChar*, int);
    8488            static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length);
     
    125129            mutable unsigned _hash;
    126130            PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
    127             void* m_baseString; // If "this" is a BaseString instance, it is 0. BaseString* otherwise.
    128131
    129132            static BaseString& null() { return *nullBaseString; }
    130133            static BaseString& empty() { return *emptyBaseString; }
    131134
     135        protected:
     136            Rep(int length)
     137                : offset(0)
     138                , len(length)
     139                , rc(1)
     140                , _hash(0)
     141                , m_nothing(0)
     142            {
     143            }
     144
     145            Rep(PassRefPtr<BaseString> base, int offsetInBase, int length)
     146                : offset(offsetInBase)
     147                , len(length)
     148                , rc(1)
     149                , _hash(0)
     150                , m_baseString(base.releaseRef())
     151            {
     152                checkConsistency();
     153            }
     154
     155            union {
     156                // If !baseIsSelf()
     157                BaseString* m_baseString;
     158                // If baseIsSelf()
     159                void* m_nothing;
     160            };
     161
    132162        private:
     163            // For SmallStringStorage which allocates an array and does initialization manually.
     164            Rep() { }
     165
     166            friend class SmallStringsStorage;
    133167            friend void initializeUString();
    134168            static BaseString* nullBaseString;
     
    136170        };
    137171
     172
    138173        struct BaseString : public Rep {
    139             BaseString()
    140             {
    141                 m_identifierTableAndFlags.setFlag(BaseStringFlag);
    142             }
     174            bool isShared() { return rc != 1; }
    143175
    144176            // potentially shared data.
     
    150182
    151183            size_t reportedCost;
     184
     185        private:
     186            BaseString(UChar* buffer, int length)
     187                : Rep(length)
     188                , buf(buffer)
     189                , preCapacity(0)
     190                , usedPreCapacity(0)
     191                , capacity(length)
     192                , usedCapacity(length)
     193                , reportedCost(0)
     194            {
     195                m_identifierTableAndFlags.setFlag(BaseStringFlag);
     196                checkConsistency();
     197            }
     198
     199            friend struct Rep;
     200            friend class SmallStringsStorage;
     201            friend void initializeUString();
    152202        };
    153203
     
    321371    bool equal(const UString::Rep*, const UString::Rep*);
    322372
     373    inline PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<UString::Rep> rep, int offset, int length)
     374    {
     375        ASSERT(rep);
     376        rep->checkConsistency();
     377
     378        int repOffset = rep->offset;
     379
     380        PassRefPtr<BaseString> base = rep->baseString();
     381
     382        ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
     383        ASSERT(offset + repOffset + length <= base->usedCapacity);
     384
     385        // Steal the single reference this Rep was created with.
     386        return adoptRef(new Rep(base, repOffset + offset, length));
     387    }
     388
    323389    inline UChar* UString::Rep::data() const
    324390    {
     
    339405    {
    340406        ASSERT(base != this);
     407        ASSERT(!baseIsSelf());
    341408        m_baseString = base.releaseRef();
    342409    }
     
    344411    inline UString::BaseString* UString::Rep::baseString()
    345412    {
    346         return reinterpret_cast<BaseString*>(baseIsSelf() ? this : m_baseString);
     413        return baseIsSelf() ? reinterpret_cast<BaseString*>(this) : m_baseString;
    347414    }
    348415
    349416    inline const UString::BaseString* UString::Rep::baseString() const
    350417    {
    351         return const_cast<const BaseString*>(const_cast<Rep*>(this)->baseString());
     418        return const_cast<Rep*>(this)->baseString();
    352419    }
    353420
Note: See TracChangeset for help on using the changeset viewer.