Changeset 39815 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Jan 11, 2009, 7:19:23 PM (16 years ago)
Author:
Darin Adler
Message:

2009-01-11 David Levin <[email protected]>

Reviewed by Darin Adler.

https://bugs.webkit.org/show_bug.cgi?id=23175

Separate out BaseString information from UString::Rep and make all baseString access go through
a member function, so that it may be used for something else (in the future) in the BaseString
case.

  • runtime/SmallStrings.cpp: (JSC::SmallStringsStorage::rep): (JSC::SmallStringsStorage::SmallStringsStorage): (JSC::SmallStrings::SmallStrings): (JSC::SmallStrings::mark): Adjust to account for the changes in UString and put the UString in place in SmallStringsStorage to aid in locality of reference among the UChar[] and UString::Rep's.
  • runtime/SmallStrings.h:
  • runtime/UString.cpp: (JSC::initializeStaticBaseString): (JSC::initializeUString): (JSC::UString::Rep::create): (JSC::UString::Rep::destroy): (JSC::UString::Rep::checkConsistency): (JSC::expandCapacity): (JSC::UString::expandPreCapacity): (JSC::concatenate): (JSC::UString::append): (JSC::UString::operator=):
  • runtime/UString.h: (JSC::UString::Rep::baseIsSelf): (JSC::UString::Rep::setBaseString): (JSC::UString::Rep::baseString): (JSC::UString::Rep::): (JSC::UString::Rep::null): (JSC::UString::Rep::empty): (JSC::UString::Rep::data): (JSC::UString::cost): Separate out the items out used by base strings from those used in Rep's that only point to base strings. (This potentially saves 24 bytes per Rep.)
Location:
trunk/JavaScriptCore/runtime
Files:
4 edited

Legend:

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

    r37938 r39815  
    3030#include "JSString.h"
    3131
     32#include <wtf/Noncopyable.h>
     33
    3234namespace JSC {
     35static const unsigned numCharactersToStore = 0x100;
    3336
    34 class SmallStringsStorage {
     37class SmallStringsStorage : Noncopyable {
    3538public:
    3639    SmallStringsStorage();
    37     ~SmallStringsStorage();
    3840
    39     UString::Rep* rep(unsigned char character) { return &reps[character]; }
     41    UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
    4042
    4143private:
    42     UChar characters[0x100];
    43     UString::Rep* reps;
     44    UChar m_characters[numCharactersToStore];
     45    UString::BaseString m_base;
     46    UString::Rep m_reps[numCharactersToStore];
    4447};
    4548
    4649SmallStringsStorage::SmallStringsStorage()
    47     : reps(static_cast<UString::Rep*>(fastZeroedMalloc(sizeof(UString::Rep) * 0x100)))
    4850{
    49     for (unsigned i = 0; i < 0x100; ++i) {
    50         characters[i] = i;
    51         reps[i].offset = i;
    52         reps[i].len = 1;
    53         reps[i].rc = 1;
    54         reps[i].baseString = &reps[0];
    55     }
    56     reps[0].rc = 0x101;
    57     reps[0].buf = characters;
     51    for (unsigned i = 0; i < numCharactersToStore; ++i)
     52        m_characters[i] = i;
     53
     54    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;
    5863
    5964    // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
    60     reps[0].usedCapacity = 0x101;
    61     reps[0].capacity = 0x101;
    62 }
     65    m_base.usedCapacity = numCharactersToStore + 1;
     66    m_base.capacity = numCharactersToStore + 1;
     67    m_base.checkConsistency();
    6368
    64 SmallStringsStorage::~SmallStringsStorage()
    65 {
    66     fastFree(reps);
     69    memset(&m_reps, 0, sizeof(m_reps));
     70    for (unsigned i = 0; i < numCharactersToStore; ++i) {
     71        m_reps[i].offset = i;
     72        m_reps[i].len = 1;
     73        m_reps[i].rc = 1;
     74        m_reps[i].setBaseString(&m_base);
     75        m_reps[i].checkConsistency();
     76    }
    6777}
    6878
     
    7181    , m_storage(0)
    7282{
    73     for (unsigned i = 0; i < 0x100; ++i)
     83    COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
     84
     85    for (unsigned i = 0; i < numCharactersToStore; ++i)
    7486        m_singleCharacterStrings[i] = 0;
    7587}
     
    8395    if (m_emptyString && !m_emptyString->marked())
    8496        m_emptyString->mark();
    85     for (unsigned i = 0; i < 0x100; ++i) {
     97    for (unsigned i = 0; i < numCharactersToStore; ++i) {
    8698        if (m_singleCharacterStrings[i] && !m_singleCharacterStrings[i]->marked())
    8799            m_singleCharacterStrings[i]->mark();
     
    110122}
    111123
    112 }
     124} // namespace JSC
  • trunk/JavaScriptCore/runtime/SmallStrings.h

    r38137 r39815  
    5656
    5757        UString::Rep* singleCharacterStringRep(unsigned char character);
    58        
     58
    5959        void mark();
    60        
     60
    6161    private:
    6262        void createEmptyString(JSGlobalData*);
     
    6767        OwnPtr<SmallStringsStorage> m_storage;
    6868    };
    69    
    70 }
    7169
    72 #endif
     70} // namespace JSC
     71
     72#endif // SmallStrings_h
  • trunk/JavaScriptCore/runtime/UString.cpp

    r39747 r39815  
    188188// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
    189189static UChar sharedEmptyChar;
    190 UString::Rep* UString::Rep::nullBaseString;
    191 UString::Rep* UString::Rep::emptyBaseString;
     190UString::BaseString* UString::Rep::nullBaseString;
     191UString::BaseString* UString::Rep::emptyBaseString;
    192192UString* UString::nullUString;
    193193
    194 void initializeStaticBaseString(int len, UChar* buf, UString::Rep& base)
     194void initializeStaticBaseString(int len, UChar* buf, UString::BaseString& base)
    195195{
    196196    base.offset = 0;
     
    199199    base._hash = 0;
    200200    base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
    201     base.baseString = &base;
     201    base.m_baseString = 0;
    202202    base.buf = buf;
    203203    base.preCapacity = 0;
     
    206206    base.usedCapacity = 0;
    207207    base.reportedCost = 0;
     208    base.checkConsistency();
    208209}
    209210
    210211void initializeUString()
    211212{
    212     UString::Rep::nullBaseString = new UString::Rep;
     213    UString::Rep::nullBaseString = new UString::BaseString;
    213214    initializeStaticBaseString(0, 0, *UString::Rep::nullBaseString);
    214215
    215     UString::Rep::emptyBaseString = new UString::Rep;
     216    UString::Rep::emptyBaseString = new UString::BaseString;
    216217    initializeStaticBaseString(0, &sharedEmptyChar, *UString::Rep::emptyBaseString);
    217218
     
    230231PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
    231232{
    232     Rep* r = new Rep;
     233    BaseString* r = new BaseString;
    233234    r->offset = 0;
    234235    r->len = l;
    235236    r->rc = 1;
    236237    r->_hash = 0;
    237     r->baseString = r;
     238    r->m_baseString = 0;
    238239    r->reportedCost = 0;
    239240    r->buf = d;
     
    249250}
    250251
    251 PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length)
    252 {
    253     ASSERT(base);
    254     base->checkConsistency();
    255 
    256     int baseOffset = base->offset;
    257 
    258     base = base->baseString;
    259 
    260     ASSERT(-(offset + baseOffset) <= base->usedPreCapacity);
    261     ASSERT(offset + baseOffset + length <= base->usedCapacity);
     252PassRefPtr<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);
    262263
    263264    Rep* r = new Rep;
    264     r->offset = baseOffset + offset;
     265    r->offset = repOffset + offset;
    265266    r->len = length;
    266267    r->rc = 1;
    267268    r->_hash = 0;
    268     r->baseString = base.releaseRef();
    269     r->reportedCost = 0;
    270     r->buf = 0;
    271     r->usedCapacity = 0;
    272     r->capacity = 0;
    273     r->usedPreCapacity = 0;
    274     r->preCapacity = 0;
     269    r->setBaseString(base);
    275270
    276271    r->checkConsistency();
     
    303298        if (identifierTable())
    304299            Identifier::remove(this);
    305         if (baseString == this)
    306             fastFree(buf);
     300        UString::BaseString* base = baseString();
     301        if (base == this)
     302            fastFree(base->buf);
    307303        else
    308             baseString->deref();
     304            base->deref();
    309305
    310306        delete this;
     
    408404void UString::Rep::checkConsistency() const
    409405{
    410     // Only base strings have non-zero shared data.
    411     if (this != baseString) {
    412         ASSERT(!buf);
    413         ASSERT(!usedCapacity);
    414         ASSERT(!capacity);
    415         ASSERT(!usedPreCapacity);
    416         ASSERT(!preCapacity);
    417     }
     406    const UString::BaseString* base = baseString();
    418407
    419408    // There is no recursion for base strings.
    420     ASSERT(baseString == baseString->baseString);
     409    ASSERT(base == base->baseString());
    421410
    422411    if (isStatic()) {
     
    429418
    430419    // The string fits in buffer.
    431     ASSERT(baseString->usedPreCapacity <= baseString->preCapacity);
    432     ASSERT(baseString->usedCapacity <= baseString->capacity);
    433     ASSERT(-offset <= baseString->usedPreCapacity);
    434     ASSERT(offset + len <= baseString->usedCapacity);
     420    ASSERT(base->usedPreCapacity <= base->preCapacity);
     421    ASSERT(base->usedCapacity <= base->capacity);
     422    ASSERT(-offset <= base->usedPreCapacity);
     423    ASSERT(offset + len <= base->usedCapacity);
    435424}
    436425#endif
     
    452441}
    453442
    454 inline int UString::usedCapacity() const
    455 {
    456     return m_rep->baseString->usedCapacity;
    457 }
    458 
    459 inline int UString::usedPreCapacity() const
    460 {
    461     return m_rep->baseString->usedPreCapacity;
    462 }
    463 
    464 
    465443static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
    466444{
    467445    rep->checkConsistency();
    468446
    469     UString::Rep* r = rep->baseString;
    470 
    471     if (requiredLength > r->capacity) {
    472         size_t newCapacity = expandedSize(requiredLength, r->preCapacity);
    473         UChar* oldBuf = r->buf;
    474         r->buf = reallocChars(r->buf, newCapacity);
    475         if (!r->buf) {
    476             r->buf = oldBuf;
     447    UString::BaseString* base = rep->baseString();
     448
     449    if (requiredLength > base->capacity) {
     450        size_t newCapacity = expandedSize(requiredLength, base->preCapacity);
     451        UChar* oldBuf = base->buf;
     452        base->buf = reallocChars(base->buf, newCapacity);
     453        if (!base->buf) {
     454            base->buf = oldBuf;
    477455            return false;
    478456        }
    479         r->capacity = newCapacity - r->preCapacity;
    480     }
    481     if (requiredLength > r->usedCapacity)
    482         r->usedCapacity = requiredLength;
     457        base->capacity = newCapacity - base->preCapacity;
     458    }
     459    if (requiredLength > base->usedCapacity)
     460        base->usedCapacity = requiredLength;
    483461
    484462    rep->checkConsistency();
     
    496474    m_rep->checkConsistency();
    497475
    498     Rep* r = m_rep->baseString;
    499 
    500     if (requiredPreCap > r->preCapacity) {
    501         size_t newCapacity = expandedSize(requiredPreCap, r->capacity);
    502         int delta = newCapacity - r->capacity - r->preCapacity;
     476    BaseString* base = m_rep->baseString();
     477
     478    if (requiredPreCap > base->preCapacity) {
     479        size_t newCapacity = expandedSize(requiredPreCap, base->capacity);
     480        int delta = newCapacity - base->capacity - base->preCapacity;
    503481
    504482        UChar* newBuf = allocChars(newCapacity);
     
    507485            return;
    508486        }
    509         copyChars(newBuf + delta, r->buf, r->capacity + r->preCapacity);
    510         fastFree(r->buf);
    511         r->buf = newBuf;
    512 
    513         r->preCapacity = newCapacity - r->capacity;
    514     }
    515     if (requiredPreCap > r->usedPreCapacity)
    516         r->usedPreCapacity = requiredPreCap;
     487        copyChars(newBuf + delta, base->buf, base->capacity + base->preCapacity);
     488        fastFree(base->buf);
     489        base->buf = newBuf;
     490
     491        base->preCapacity = newCapacity - base->capacity;
     492    }
     493    if (requiredPreCap > base->usedPreCapacity)
     494        base->usedPreCapacity = requiredPreCap;
    517495
    518496    m_rep->checkConsistency();
     
    579557    int thisOffset = rep->offset;
    580558    int length = thisSize + tSize;
     559    UString::BaseString* base = rep->baseString();
    581560
    582561    // possible cases:
     
    586565        // this is empty
    587566        rep = UString::Rep::createCopying(tData, tSize);
    588     } else if (rep->baseIsSelf() && rep->rc == 1) {
     567    } else if (rep == base && rep->rc == 1) {
    589568        // this is direct and has refcount of 1 (so we can just alter it directly)
    590569        if (!expandCapacity(rep.get(), thisOffset + length))
     
    595574            rep->_hash = 0;
    596575        }
    597     } else if (thisOffset + thisSize == rep->baseString->usedCapacity && thisSize >= minShareSize) {
     576    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
    598577        // this reaches the end of the buffer - extend it if it's long enough to append to
    599578        if (!expandCapacity(rep.get(), thisOffset + length))
     
    613592            copyChars(d + thisSize, tData, tSize);
    614593            rep = UString::Rep::create(d, length);
    615             rep->capacity = newCapacity;
     594            rep->baseString()->capacity = newCapacity;
    616595        }
    617596    }
     
    632611    int tSize = static_cast<int>(strlen(t));
    633612    int length = thisSize + tSize;
     613    UString::BaseString* base = rep->baseString();
    634614
    635615    // possible cases:
     
    639619    } else if (tSize == 0) {
    640620        // t is empty, we'll just return *this below.
    641     } else if (rep->baseIsSelf() && rep->rc == 1) {
     621    } else if (rep == base && rep->rc == 1) {
    642622        // this is direct and has refcount of 1 (so we can just alter it directly)
    643623        expandCapacity(rep.get(), thisOffset + length);
     
    649629            rep->_hash = 0;
    650630        }
    651     } else if (thisOffset + thisSize == rep->baseString->usedCapacity && thisSize >= minShareSize) {
     631    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
    652632        // this string reaches the end of the buffer - extend it
    653633        expandCapacity(rep.get(), thisOffset + length);
     
    669649                d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend
    670650            rep = UString::Rep::create(d, length);
    671             rep->capacity = newCapacity;
     651            rep->baseString()->capacity = newCapacity;
    672652        }
    673653    }
     
    698678        return a;
    699679
    700     if (bSize == 1 && aOffset + aSize == a->baseString->usedCapacity && aOffset + length <= a->baseString->capacity) {
     680    UString::BaseString* aBase = a->baseString();
     681    if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + length <= aBase->capacity) {
    701682        // b is a single character (common fast case)
    702         a->baseString->usedCapacity = aOffset + length;
     683        aBase->usedCapacity = aOffset + length;
    703684        a->data()[aSize] = b->data()[0];
    704685        return UString::Rep::create(a, 0, length);
    705686    }
    706687
    707     if (aOffset + aSize == a->baseString->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize &&
    708                (-bOffset != b->baseString->usedPreCapacity || aSize >= bSize)) {
     688    UString::BaseString* bBase = b->baseString();
     689    if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize
     690        && (-bOffset != bBase->usedPreCapacity || aSize >= bSize)) {
    709691        // - a reaches the end of its buffer so it qualifies for shared append
    710692        // - also, it's at least a quarter the length of b - appending to a much shorter
     
    725707    }
    726708
    727     if (-bOffset == b->baseString->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
     709    if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
    728710        // - b reaches the beginning of its buffer so it qualifies for shared prepend
    729711        // - also, it's at least a quarter the length of a - prepending to a much shorter
     
    751733    copyChars(d + aSize, b->data(), bSize);
    752734    PassRefPtr<UString::Rep> result = UString::Rep::create(d, length);
    753     result->capacity = newCapacity;
     735    result->baseString()->capacity = newCapacity;
    754736
    755737    a->checkConsistency();
     
    10521034    int tSize = t.size();
    10531035    int length = thisSize + tSize;
     1036    BaseString* base = m_rep->baseString();
    10541037
    10551038    // possible cases:
     
    10591042    } else if (tSize == 0) {
    10601043        // t is empty
    1061     } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
     1044    } else if (m_rep == base && m_rep->rc == 1) {
    10621045        // this is direct and has refcount of 1 (so we can just alter it directly)
    10631046        expandCapacity(thisOffset + length);
     
    10671050            m_rep->_hash = 0;
    10681051        }
    1069     } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) {
     1052    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
    10701053        // this reaches the end of the buffer - extend it if it's long enough to append to
    10711054        expandCapacity(thisOffset + length);
     
    10841067            copyChars(d + thisSize, t.data(), tSize);
    10851068            m_rep = Rep::create(d, length);
    1086             m_rep->capacity = newCapacity;
     1069            m_rep->baseString()->capacity = newCapacity;
    10871070        }
    10881071    }
     
    11121095    int thisOffset = m_rep->offset;
    11131096    int length = size();
     1097    BaseString* base = m_rep->baseString();
    11141098
    11151099    // possible cases:
     
    11231107            d[0] = c;
    11241108            m_rep = Rep::create(d, 1);
    1125             m_rep->capacity = newCapacity;
    1126         }
    1127     } else if (m_rep->baseIsSelf() && m_rep->rc == 1) {
     1109            m_rep->baseString()->capacity = newCapacity;
     1110        }
     1111    } else if (m_rep == base && m_rep->rc == 1) {
    11281112        // this is direct and has refcount of 1 (so we can just alter it directly)
    11291113        expandCapacity(thisOffset + length + 1);
     
    11341118            m_rep->_hash = 0;
    11351119        }
    1136     } else if (thisOffset + length == usedCapacity() && length >= minShareSize) {
     1120    } else if (thisOffset + length == base->usedCapacity && length >= minShareSize) {
    11371121        // this reaches the end of the string - extend it and share
    11381122        expandCapacity(thisOffset + length + 1);
     
    11521136            d[length] = c;
    11531137            m_rep = Rep::create(d, length + 1);
    1154             m_rep->capacity = newCapacity;
     1138            m_rep->baseString()->capacity = newCapacity;
    11551139        }
    11561140    }
     
    12181202    int l = static_cast<int>(strlen(c));
    12191203    UChar* d;
    1220     if (m_rep->rc == 1 && l <= m_rep->capacity && m_rep->baseIsSelf() && m_rep->offset == 0 && m_rep->preCapacity == 0) {
    1221         d = m_rep->buf;
     1204    BaseString* base = m_rep->baseString();
     1205    if (m_rep->rc == 1 && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
     1206        d = base->buf;
    12221207        m_rep->_hash = 0;
    12231208        m_rep->len = l;
  • trunk/JavaScriptCore/runtime/UString.h

    r39747 r39815  
    2828#include <string.h>
    2929#include <wtf/Assertions.h>
    30 #include <wtf/FastMalloc.h>
    3130#include <wtf/PassRefPtr.h>
    3231#include <wtf/PtrAndFlags.h>
     
    7776
    7877    public:
    79         struct Rep {
     78        struct BaseString;
     79        struct Rep : Noncopyable {
    8080            friend class JIT;
    8181
     
    9090            void destroy();
    9191
    92             bool baseIsSelf() const { return baseString == this; }
    93             UChar* data() const { return baseString->buf + baseString->preCapacity + offset; }
     92            bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); }
     93            UChar* data() const;
    9494            int size() const { return len; }
    9595
     
    105105
    106106            bool isStatic() const { return m_identifierTableAndFlags.isFlagSet(StaticFlag); }
    107             void setStatic(bool v) { ASSERT(!identifierTable()); if (v) m_identifierTableAndFlags.setFlag(StaticFlag); else m_identifierTableAndFlags.clearFlag(StaticFlag); }
     107            void setStatic(bool);
     108            void setBaseString(PassRefPtr<BaseString>);
     109            BaseString* baseString();
     110            const BaseString* baseString() const;
    108111
    109112            Rep* ref() { ++rc; return this; }
     
    112115            void checkConsistency() const;
    113116            enum UStringFlags {
    114                 StaticFlag
     117                StaticFlag,
     118                BaseStringFlag
    115119            };
    116120
     
    121125            mutable unsigned _hash;
    122126            PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
    123             UString::Rep* baseString;
    124             size_t reportedCost;
    125 
    126             // potentially shared data. 0 if backed up by a base string.
    127             UChar* buf;
    128             int usedCapacity;
    129             int capacity;
    130             int usedPreCapacity;
    131             int preCapacity;
    132 
    133             static Rep& null() { return *nullBaseString; }
    134             static Rep& empty() { return *emptyBaseString; }
     127            void* m_baseString; // If "this" is a BaseString instance, it is 0. BaseString* otherwise.
     128
     129            static BaseString& null() { return *nullBaseString; }
     130            static BaseString& empty() { return *emptyBaseString; }
     131
    135132        private:
    136133            friend void initializeUString();
    137             static Rep* nullBaseString;
    138             static Rep* emptyBaseString;
     134            static BaseString* nullBaseString;
     135            static BaseString* emptyBaseString;
     136        };
     137
     138        struct BaseString : public Rep {
     139            BaseString()
     140            {
     141                m_identifierTableAndFlags.setFlag(BaseStringFlag);
     142            }
     143
     144            // potentially shared data.
     145            UChar* buf;
     146            int preCapacity;
     147            int usedPreCapacity;
     148            int capacity;
     149            int usedCapacity;
     150
     151            size_t reportedCost;
    139152        };
    140153
     
    254267
    255268    private:
    256         int usedCapacity() const;
    257         int usedPreCapacity() const;
    258269        void expandCapacity(int requiredLength);
    259270        void expandPreCapacity(int requiredPreCap);
     
    309320
    310321    bool equal(const UString::Rep*, const UString::Rep*);
     322
     323    inline UChar* UString::Rep::data() const
     324    {
     325        const BaseString* base = baseString();
     326        return base->buf + base->preCapacity + offset;
     327    }
     328
     329    inline void UString::Rep::setStatic(bool v)
     330    {
     331        ASSERT(!identifierTable());
     332        if (v)
     333            m_identifierTableAndFlags.setFlag(StaticFlag);
     334        else
     335            m_identifierTableAndFlags.clearFlag(StaticFlag);
     336    }
     337
     338    inline void UString::Rep::setBaseString(PassRefPtr<BaseString> base)
     339    {
     340        ASSERT(base != this);
     341        m_baseString = base.releaseRef();
     342    }
     343
     344    inline UString::BaseString* UString::Rep::baseString()
     345    {
     346        return reinterpret_cast<BaseString*>(baseIsSelf() ? this : m_baseString);
     347    }
     348
     349    inline const UString::BaseString* UString::Rep::baseString() const
     350    {
     351        return const_cast<const BaseString*>(const_cast<Rep*>(this)->baseString());
     352    }
    311353
    312354#ifdef NDEBUG
     
    340382    inline size_t UString::cost() const
    341383    {
    342         size_t capacity = (m_rep->baseString->capacity + m_rep->baseString->preCapacity) * sizeof(UChar);
    343         size_t reportedCost = m_rep->baseString->reportedCost;
     384        BaseString* base = m_rep->baseString();
     385        size_t capacity = (base->capacity + base->preCapacity) * sizeof(UChar);
     386        size_t reportedCost = base->reportedCost;
    344387        ASSERT(capacity >= reportedCost);
    345388
     
    349392            return 0;
    350393
    351         m_rep->baseString->reportedCost = capacity;
     394        base->reportedCost = capacity;
    352395
    353396        return capacityDelta;
Note: See TracChangeset for help on using the changeset viewer.