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.)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.