Ignore:
Timestamp:
Mar 11, 2010, 7:14:17 PM (15 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=36041
Remove unnecessary differences in common code between WebCore::StringImpl & JSC::UStringImpl

Reviewed by Oliver Hunt.

Much of the code in WebCore::StringImpl and JSC::UStringImpl is now very similar,
but has trivial and unnecessary formatting differences, such as the exact wording
of comments, missing ASSERTs, functions implemented in the .h vs .cpp etc.

JavaScriptCore:

  • runtime/Identifier.cpp:

(JSC::Identifier::add): UStringImpl::empty() now automatically hashes, uas per WebCore strings.
(JSC::Identifier::addSlowCase): UStringImpl::empty() now automatically hashes, uas per WebCore strings.

  • runtime/UStringImpl.cpp:

(JSC::UStringImpl::~UStringImpl): Only call bufferOwnership() once, add missing ASSERTs.
(JSC::UStringImpl::createUninitialized): Move from .h, not commonly called, no need to inline.
(JSC::UStringImpl::create): Move from .h, not commonly called, no need to inline.
(JSC::UStringImpl::sharedBuffer): Rewritten to more closely match WebCore implementation, remove need for separate baseSharedBuffer() method.

  • runtime/UStringImpl.h:

(JSC::UStringImpl::UStringImpl): Automatically hash static strings, ASSERT m_data & m_length are non-null/non-zero in non-static strings.
(JSC::UStringImpl::setHash): Add missing ASSERT.
(JSC::UStringImpl::create): Moved to .cpp / added missing check for empty string creation.
(JSC::UStringImpl::adopt): Vector.size() returns size_t, not unsigned.
(JSC::UStringImpl::cost): Renamed m_bufferSubstring -> m_substringBuffer
(JSC::UStringImpl::hash): Reordered in file.
(JSC::UStringImpl::existingHash): Reordered in file.
(JSC::UStringImpl::computeHash): Reordered in file, renamed parameter.
(JSC::UStringImpl::checkConsistency): rewrote ASSERT.
(JSC::UStringImpl::bufferOwnership): Return type should be BufferOwnership.
(JSC::UStringImpl::): Moved friends to head of class.

WebCore:

  • platform/text/StringImpl.cpp:

(WebCore::StringImpl::empty): Reordered in file, made empty()->characters() return a non-null value to match JSC.
(WebCore::StringImpl::createUninitialized): Added overflow check.
(WebCore::StringImpl::create): Reordered in file.
(WebCore::StringImpl::sharedBuffer): Reordered in file.

  • platform/text/StringImpl.h:

(WebCore::StringImpl::): Remove ThreadGlobalData as friend, move SharableUChar & SharedUChar to WebCore namespace.
(WebCore::StringImpl::StringImpl): Made static constructor method (used to create empty string) take arguments, to match JSC & prevent accidental use.
(WebCore::StringImpl::setHash): Added missing ASSERT.
(WebCore::StringImpl::adopt): Make adpot work with Vectors with a non-zero inline capacity.
(WebCore::StringImpl::characters): Mark as const to match JSC.
(WebCore::StringImpl::hash): Use !m_hash instead of m_hash == 0.
(WebCore::StringImpl::computeHash): Remove redundant 'inline'.

File:
1 edited

Legend:

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

    r55833 r55878  
    106106
    107107class UStringImpl : public UStringOrRopeImpl {
     108    friend class CStringTranslator;
     109    friend class UCharBufferTranslator;
     110    friend class JIT;
     111    friend class SmallStringsStorage;
     112    friend class UStringOrRopeImpl;
     113    friend void initializeUString();
     114private:
     115    // For SmallStringStorage, which allocates an array and uses an in-place new.
     116    UStringImpl() { }
     117
     118    // Used to construct static strings, which have an special refCount that can never hit zero.
     119    // This means that the static string will never be destroyed, which is important because
     120    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
     121    UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
     122        : UStringOrRopeImpl(length, ConstructStaticString)
     123        , m_data(characters)
     124        , m_buffer(0)
     125        , m_hash(0)
     126    {
     127        hash();
     128        checkConsistency();
     129    }
     130
     131    // Create a normal string with internal storage (BufferInternal)
     132    UStringImpl(unsigned length)
     133        : UStringOrRopeImpl(length, BufferInternal)
     134        , m_data(reinterpret_cast<UChar*>(this + 1))
     135        , m_buffer(0)
     136        , m_hash(0)
     137    {
     138        ASSERT(m_data);
     139        ASSERT(m_length);
     140        checkConsistency();
     141    }
     142
     143    // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned)
     144    UStringImpl(const UChar* characters, unsigned length)
     145        : UStringOrRopeImpl(length, BufferOwned)
     146        , m_data(characters)
     147        , m_buffer(0)
     148        , m_hash(0)
     149    {
     150        ASSERT(m_data);
     151        ASSERT(m_length);
     152        checkConsistency();
     153    }
     154
     155    // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring)
     156    UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base)
     157        : UStringOrRopeImpl(length, BufferSubstring)
     158        , m_data(characters)
     159        , m_substringBuffer(base.releaseRef())
     160        , m_hash(0)
     161    {
     162        ASSERT(m_data);
     163        ASSERT(m_length);
     164        checkConsistency();
     165    }
     166
     167    // Used to construct new strings sharing an existing SharedUChar (BufferShared)
     168    UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
     169        : UStringOrRopeImpl(length, BufferShared)
     170        , m_data(characters)
     171        , m_sharedBuffer(sharedBuffer.releaseRef())
     172        , m_hash(0)
     173    {
     174        ASSERT(m_data);
     175        ASSERT(m_length);
     176        checkConsistency();
     177    }
     178
     179    // For use only by Identifier's XXXTranslator helpers.
     180    void setHash(unsigned hash)
     181    {
     182        ASSERT(!m_hash);
     183        ASSERT(hash == computeHash(m_data, m_length));
     184        m_hash = hash;
     185    }
     186
    108187public:
    109     template<size_t inlineCapacity>
    110     static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
    111     {
    112         if (unsigned length = vector.size()) {
    113             ASSERT(vector.data());
    114             return adoptRef(new UStringImpl(vector.releaseBuffer(), length));
    115         }
    116         return empty();
    117     }
    118 
    119     static PassRefPtr<UStringImpl> create(const UChar* buffer, unsigned length);
    120     static PassRefPtr<UStringImpl> create(const char* c, unsigned length);
    121     static PassRefPtr<UStringImpl> create(const char* c);
    122 
     188    ~UStringImpl();
     189
     190    static PassRefPtr<UStringImpl> create(const UChar*, unsigned length);
     191    static PassRefPtr<UStringImpl> create(const char*, unsigned length);
     192    static PassRefPtr<UStringImpl> create(const char*);
     193    static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar>, const UChar*, unsigned length);
    123194    static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, unsigned offset, unsigned length)
    124195    {
     196        if (!length)
     197            return empty();
    125198        ASSERT(rep);
    126199        rep->checkConsistency();
    127         return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString()));
    128     }
    129 
    130     static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar> sharedBuffer, const UChar* buffer, unsigned length)
    131     {
    132         return adoptRef(new UStringImpl(buffer, length, sharedBuffer));
    133     }
    134 
    135     static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output)
    136     {
    137         if (!length) {
    138             output = 0;
    139             return empty();
    140         }
    141 
    142         if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
    143             CRASH();
    144         UStringImpl* resultImpl = static_cast<UStringImpl*>(fastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)));
    145         output = reinterpret_cast<UChar*>(resultImpl + 1);
    146         return adoptRef(new(resultImpl) UStringImpl(length));
    147     }
    148 
     200        UStringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get();
     201        return adoptRef(new UStringImpl(rep->m_data + offset, length, ownerRep));
     202    }
     203
     204    static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output);
    149205    static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
    150206    {
     
    163219    }
    164220
     221    template<size_t inlineCapacity>
     222    static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
     223    {
     224        if (size_t size = vector.size()) {
     225            ASSERT(vector.data());
     226            return adoptRef(new UStringImpl(vector.releaseBuffer(), size));
     227        }
     228        return empty();
     229    }
     230
    165231    SharedUChar* sharedBuffer();
    166232    const UChar* characters() const { return m_data; }
     233
    167234    size_t cost()
    168235    {
    169236        // For substrings, return the cost of the base string.
    170237        if (bufferOwnership() == BufferSubstring)
    171             return m_bufferSubstring->cost();
     238            return m_substringBuffer->cost();
    172239
    173240        if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) {
     
    177244        return 0;
    178245    }
    179     unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
    180     unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers
    181     void setHash(unsigned hash) { ASSERT(hash == computeHash(m_data, m_length)); m_hash = hash; } // fast path for Identifiers
     246
    182247    bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
    183248    void setIsIdentifier(bool isIdentifier)
     
    189254    }
    190255
     256// SYNC SYNC SYNC
     257// SYNC SYNC SYNC
     258// SYNC SYNC SYNC
     259// SYNC SYNC SYNC
     260// SYNC SYNC SYNC
     261
     262    unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
     263    unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
     264    static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); }
     265    static unsigned computeHash(const char* data, unsigned length) { return WTF::stringHash(data, length); }
     266    static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
     267
    191268    ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
     269
     270    static UStringImpl* empty();
    192271
    193272    static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
     
    200279    }
    201280
    202     static unsigned computeHash(const UChar* s, unsigned length) { return WTF::stringHash(s, length); }
    203     static unsigned computeHash(const char* s, unsigned length) { return WTF::stringHash(s, length); }
    204     static unsigned computeHash(const char* s) { return WTF::stringHash(s); }
    205 
    206     static UStringImpl* empty();
    207 
    208281    ALWAYS_INLINE void checkConsistency() const
    209282    {
    210283        // There is no recursion of substrings.
    211         ASSERT(bufferOwnerString()->bufferOwnership() != BufferSubstring);
     284        ASSERT((bufferOwnership() != BufferSubstring) || (m_substringBuffer->bufferOwnership() != BufferSubstring));
    212285        // Static strings cannot be put in identifier tables, because they are globally shared.
    213286        ASSERT(!isStatic() || !isIdentifier());
     
    215288
    216289private:
    217     // For SmallStringStorage, which allocates an array and uses an in-place new.
    218     UStringImpl() { }
    219 
    220     // Used to construct normal strings with an internal buffer.
    221     UStringImpl(unsigned length)
    222         : UStringOrRopeImpl(length, BufferInternal)
    223         , m_data(reinterpret_cast<UChar*>(this + 1))
    224         , m_buffer(0)
    225         , m_hash(0)
    226     {
    227         checkConsistency();
    228     }
    229 
    230     // Used to construct normal strings with an external buffer.
    231     UStringImpl(const UChar* data, unsigned length)
    232         : UStringOrRopeImpl(length, BufferOwned)
    233         , m_data(data)
    234         , m_buffer(0)
    235         , m_hash(0)
    236     {
    237         checkConsistency();
    238     }
    239 
    240     // Used to construct static strings, which have an special refCount that can never hit zero.
    241     // This means that the static string will never be destroyed, which is important because
    242     // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
    243     UStringImpl(const UChar* data, unsigned length, StaticStringConstructType)
    244         : UStringOrRopeImpl(length, ConstructStaticString)
    245         , m_data(data)
    246         , m_buffer(0)
    247         , m_hash(0)
    248     {
    249         checkConsistency();
    250     }
    251 
    252     // Used to create new strings that are a substring of an existing string.
    253     UStringImpl(const UChar* data, unsigned length, PassRefPtr<UStringImpl> base)
    254         : UStringOrRopeImpl(length, BufferSubstring)
    255         , m_data(data)
    256         , m_bufferSubstring(base.releaseRef())
    257         , m_hash(0)
    258     {
    259         // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes
    260         // that all pointers will be at least 8-byte aligned, we cannot guarantee that of
    261         // UStringImpls that are not heap allocated.
    262         ASSERT(m_bufferSubstring->length());
    263         ASSERT(!m_bufferSubstring->isStatic());
    264         checkConsistency();
    265     }
    266 
    267     // Used to construct new strings sharing an existing shared buffer.
    268     UStringImpl(const UChar* data, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    269         : UStringOrRopeImpl(length, BufferShared)
    270         , m_data(data)
    271         , m_bufferShared(sharedBuffer.releaseRef())
    272         , m_hash(0)
    273     {
    274         checkConsistency();
    275     }
    276 
    277     ~UStringImpl();
    278 
    279290    // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
    280     static const unsigned s_minLengthToShare = 10;
    281291    static const unsigned s_copyCharsInlineCutOff = 20;
    282292
    283     UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring :  this; }
    284     const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring :  this; }
    285     SharedUChar* baseSharedBuffer();
    286     unsigned bufferOwnership() const { return m_refCountAndFlags & s_refCountMaskBufferOwnership; }
     293    BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
    287294    bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
    288295
     
    291298    union {
    292299        void* m_buffer;
    293         UStringImpl* m_bufferSubstring;
    294         SharedUChar* m_bufferShared;
     300        UStringImpl* m_substringBuffer;
     301        SharedUChar* m_sharedBuffer;
    295302    };
    296303    mutable unsigned m_hash;
    297 
    298     friend class JIT;
    299     friend class SmallStringsStorage;
     304};
     305
     306class URopeImpl : public UStringOrRopeImpl {
    300307    friend class UStringOrRopeImpl;
    301     friend void initializeUString();
    302 };
    303 
    304 class URopeImpl : public UStringOrRopeImpl {
    305308public:
    306309    // A URopeImpl is composed from a set of smaller strings called Fibers.
     
    340343    unsigned m_fiberCount;
    341344    Fiber m_fibers[1];
    342 
    343     friend class UStringOrRopeImpl;
    344345};
    345346
Note: See TracChangeset for help on using the changeset viewer.