Changeset 57932 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Apr 20, 2010, 3:34:52 PM (15 years ago)
Author:
[email protected]
Message:

JavaScriptCore: Bug 37895 - Share common code from UStringImplBase with StringImpl

Reviewed by Oliver Hunt.

The implementation of StringImpl & UStringImpl is very similar. Restructure
StringImpl to match UStringImpl, moving the flags and length into a base class,
so that this can be shared between both string types to increase code reuse.

(JSC::RopeImpl::RopeImpl):

  • runtime/UStringImpl.h:

(JSC::UStringImpl::UStringImpl):

  • wtf/text/StringImpl.h:

(WebCore::StringImpl::StringImpl):
(WebCore::StringImpl::characters):

  • wtf/text/StringImplBase.h: Copied from JavaScriptCore/runtime/UStringImpl.h.

(WTF::StringImplBase::length):
(WTF::StringImplBase::operator new):
(WTF::StringImplBase::StringImplBase):

JavaScriptGlue: Bug 37895 - Share common code from UStringImplBase with StringImpl
Add forwarding header.

Reviewed by Oliver Hunt.

  • ForwardingHeaders/wtf/text/StringImplBase.h: Added.

WebCore: Bug 37895 - Share common code from UStringImplBase with StringImpl
Add forwarding header.

Reviewed by Oliver Hunt.

  • ForwardingHeaders/wtf/text/StringImplBase.h: Added.
Location:
trunk/JavaScriptCore
Files:
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r57925 r57932  
     12010-04-20  Gavin Barraclough  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Bug 37895 - Share common code from UStringImplBase with StringImpl
     6
     7        The implementation of StringImpl & UStringImpl is very similar.  Restructure
     8        StringImpl to match UStringImpl, moving the flags and length into a base class,
     9        so that this can be shared between both string types to increase code reuse.
     10
     11        * JavaScriptCore.xcodeproj/project.pbxproj:
     12        * runtime/RopeImpl.h:
     13        (JSC::RopeImpl::RopeImpl):
     14        * runtime/UStringImpl.h:
     15        (JSC::UStringImpl::UStringImpl):
     16        * wtf/text/StringImpl.h:
     17        (WebCore::StringImpl::StringImpl):
     18        (WebCore::StringImpl::characters):
     19        * wtf/text/StringImplBase.h: Copied from JavaScriptCore/runtime/UStringImpl.h.
     20        (WTF::StringImplBase::length):
     21        (WTF::StringImplBase::operator new):
     22        (WTF::StringImplBase::StringImplBase):
     23
    1242010-04-20  Oliver Hunt  <[email protected]>
    225
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r57925 r57932  
    217217                86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */; };
    218218                86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AB7117E391E00DF5A90 /* RopeImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
     219                86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     220                86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE2117E578100DF5A90 /* StringImplBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
    219221                86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
    220222                86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; };
     
    758760                86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RopeImpl.cpp; sourceTree = "<group>"; };
    759761                86B99AB7117E391E00DF5A90 /* RopeImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeImpl.h; sourceTree = "<group>"; };
     762                86B99AE1117E578100DF5A90 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuffer.h; path = text/StringBuffer.h; sourceTree = "<group>"; };
     763                86B99AE2117E578100DF5A90 /* StringImplBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringImplBase.h; path = text/StringImplBase.h; sourceTree = "<group>"; };
    760764                86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; };
    761765                86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; };
     
    16781682                                86565740115BE3DA00291F40 /* CString.cpp */,
    16791683                                86565741115BE3DA00291F40 /* CString.h */,
     1684                                86B99AE1117E578100DF5A90 /* StringBuffer.h */,
    16801685                                868BFA05117CEFD100B908B1 /* StringHash.h */,
    16811686                                868BFA06117CEFD100B908B1 /* StringImpl.cpp */,
    16821687                                868BFA07117CEFD100B908B1 /* StringImpl.h */,
     1688                                86B99AE2117E578100DF5A90 /* StringImplBase.h */,
    16831689                                868BFA15117CF19900B908B1 /* WTFString.cpp */,
    16841690                                868BFA16117CF19900B908B1 /* WTFString.h */,
     
    20852091                                868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */,
    20862092                                86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */,
     2093                                86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */,
     2094                                86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */,
    20872095                        );
    20882096                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/JavaScriptCore/runtime/RopeImpl.h

    r57912 r57932  
    3131namespace JSC {
    3232
    33 class RopeImpl : public UStringImplBase {
     33class RopeImpl : public StringImplBase {
    3434public:
    3535    // A RopeImpl is composed from a set of smaller strings called Fibers.
    3636    // Each Fiber in a rope is either UStringImpl or another RopeImpl.
    37     typedef UStringImplBase* Fiber;
     37    typedef StringImplBase* Fiber;
    3838
    3939    // Creates a RopeImpl comprising of 'fiberCount' Fibers.
     
    7373
    7474private:
    75     RopeImpl(unsigned fiberCount) : UStringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {}
     75    RopeImpl(unsigned fiberCount) : StringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {}
    7676
    7777    void destructNonRecursive();
  • trunk/JavaScriptCore/runtime/UStringImpl.h

    r57912 r57932  
    3434#include <wtf/Vector.h>
    3535#include <wtf/unicode/Unicode.h>
     36#include <wtf/text/StringImplBase.h>
    3637
    3738namespace JSC {
     
    4243typedef CrossThreadRefCounted<SharableUChar> SharedUChar;
    4344
    44 class UStringImplBase : public Noncopyable {
    45 public:
    46     bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; }
    47     unsigned length() const { return m_length; }
    48 
    49     void ref() { m_refCountAndFlags += s_refCountIncrement; }
    50 
    51 protected:
    52     enum BufferOwnership {
    53         BufferInternal,
    54         BufferOwned,
    55         BufferSubstring,
    56         BufferShared,
    57     };
    58 
    59     using Noncopyable::operator new;
    60     void* operator new(size_t, void* inPlace) { return inPlace; }
    61 
    62     // For SmallStringStorage, which allocates an array and uses an in-place new.
    63     UStringImplBase() { }
    64 
    65     UStringImplBase(unsigned length, BufferOwnership ownership)
    66         : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership)
    67         , m_length(length)
    68     {
    69         ASSERT(isStringImpl());
    70     }
    71 
    72     enum StaticStringConstructType { ConstructStaticString };
    73     UStringImplBase(unsigned length, StaticStringConstructType)
    74         : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned)
    75         , m_length(length)
    76     {
    77         ASSERT(isStringImpl());
    78     }
    79 
    80     // This constructor is not used when creating UStringImpl objects,
    81     // and sets the flags into a state marking the object as such.
    82     enum NonStringImplConstructType { ConstructNonStringImpl };
    83     UStringImplBase(NonStringImplConstructType)
    84         : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl)
    85         , m_length(0)
    86     {
    87         ASSERT(!isStringImpl());
    88     }
    89 
    90     // The bottom 5 bits hold flags, the top 27 bits hold the ref count.
    91     // When dereferencing UStringImpls we check for the ref count AND the
    92     // static bit both being zero - static strings are never deleted.
    93     static const unsigned s_refCountMask = 0xFFFFFFE0;
    94     static const unsigned s_refCountIncrement = 0x20;
    95     static const unsigned s_refCountFlagStatic = 0x10;
    96     static const unsigned s_refCountFlagShouldReportedCost = 0x8;
    97     static const unsigned s_refCountFlagIsIdentifier = 0x4;
    98     static const unsigned s_refCountMaskBufferOwnership = 0x3;
    99     // An invalid permutation of flags (static & shouldReportedCost - static strings do not
    100     // set shouldReportedCost in the constructor, and this bit is only ever cleared, not set).
    101     // Used by "ConstructNonStringImpl" constructor, above.
    102     static const unsigned s_refCountInvalidForStringImpl = s_refCountFlagStatic | s_refCountFlagShouldReportedCost;
    103 
    104     unsigned m_refCountAndFlags;
    105     unsigned m_length;
    106 };
    107 
    108 class UStringImpl : public UStringImplBase {
     45class UStringImpl : public StringImplBase {
    10946    friend struct CStringTranslator;
    11047    friend struct UCharBufferTranslator;
     
    12057    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
    12158    UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
    122         : UStringImplBase(length, ConstructStaticString)
     59        : StringImplBase(length, ConstructStaticString)
    12360        , m_data(characters)
    12461        , m_buffer(0)
     
    13067    // Create a normal string with internal storage (BufferInternal)
    13168    UStringImpl(unsigned length)
    132         : UStringImplBase(length, BufferInternal)
     69        : StringImplBase(length, BufferInternal)
    13370        , m_data(reinterpret_cast<UChar*>(this + 1))
    13471        , m_buffer(0)
     
    14178    // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned)
    14279    UStringImpl(const UChar* characters, unsigned length)
    143         : UStringImplBase(length, BufferOwned)
     80        : StringImplBase(length, BufferOwned)
    14481        , m_data(characters)
    14582        , m_buffer(0)
     
    15289    // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring)
    15390    UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base)
    154         : UStringImplBase(length, BufferSubstring)
     91        : StringImplBase(length, BufferSubstring)
    15592        , m_data(characters)
    15693        , m_substringBuffer(base.releaseRef())
     
    164101    // Used to construct new strings sharing an existing SharedUChar (BufferShared)
    165102    UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    166         : UStringImplBase(length, BufferShared)
     103        : StringImplBase(length, BufferShared)
    167104        , m_data(characters)
    168105        , m_sharedBuffer(sharedBuffer.releaseRef())
  • trunk/JavaScriptCore/wtf/text/StringImpl.h

    r57904 r57932  
    3232#include <wtf/StringHashFunctions.h>
    3333#include <wtf/Vector.h>
     34#include <wtf/text/StringImplBase.h>
    3435#include <wtf/unicode/Unicode.h>
    3536
     
    5960typedef bool (*CharacterMatchFunctionPtr)(UChar);
    6061
    61 class StringImpl : public Noncopyable {
     62class StringImpl : public StringImplBase {
    6263    friend struct CStringTranslator;
    6364    friend struct HashAndCharactersTranslator;
    6465    friend struct UCharBufferTranslator;
    6566private:
    66     enum BufferOwnership {
    67         BufferInternal,
    68         BufferOwned,
    69         BufferShared,
    70     };
    7167
    7268    // Used to construct static strings, which have an special refCount that can never hit zero.
    7369    // This means that the static string will never be destroyed, which is important because
    7470    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
    75     enum StaticStringConstructType { ConstructStaticString };
    7671    StringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
    77         : m_data(characters)
     72        : StringImplBase(length, ConstructStaticString)
     73        , m_data(characters)
    7874        , m_sharedBuffer(0)
    79         , m_length(length)
    80         , m_refCountAndFlags(s_refCountFlagStatic | BufferInternal)
    8175        , m_hash(0)
    8276    {
     
    8983    // Create a normal string with internal storage (BufferInternal)
    9084    StringImpl(unsigned length)
    91         : m_data(reinterpret_cast<const UChar*>(this + 1))
     85        : StringImplBase(length, BufferInternal)
     86        , m_data(reinterpret_cast<const UChar*>(this + 1))
    9287        , m_sharedBuffer(0)
    93         , m_length(length)
    94         , m_refCountAndFlags(s_refCountIncrement | BufferInternal)
    9588        , m_hash(0)
    9689    {
     
    10194    // Create a StringImpl adopting ownership of the provided buffer (BufferOwned)
    10295    StringImpl(const UChar* characters, unsigned length)
    103         : m_data(characters)
     96        : StringImplBase(length, BufferOwned)
     97        , m_data(characters)
    10498        , m_sharedBuffer(0)
    105         , m_length(length)
    106         , m_refCountAndFlags(s_refCountIncrement | BufferOwned)
    10799        , m_hash(0)
    108100    {
     
    113105    // Used to construct new strings sharing an existing SharedUChar (BufferShared)
    114106    StringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    115         : m_data(characters)
     107        : StringImplBase(length, BufferShared)
     108        , m_data(characters)
    116109        , m_sharedBuffer(sharedBuffer.releaseRef())
    117         , m_length(length)
    118         , m_refCountAndFlags(s_refCountIncrement | BufferShared)
    119110        , m_hash(0)
    120111    {
     
    157148    SharedUChar* sharedBuffer();
    158149    const UChar* characters() const { return m_data; }
    159     unsigned length() { return m_length; }
    160150
    161151    bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; }
     
    169159    static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
    170160
    171     StringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; }
    172161    ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
    173162    ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; }
     
    242231
    243232private:
    244     using Noncopyable::operator new;
    245     void* operator new(size_t, void* inPlace) { ASSERT(inPlace); return inPlace; }
    246 
    247233    static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length);
    248234   
     
    250236    bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
    251237
    252     static const unsigned s_refCountMask = 0xFFFFFFE0;
    253     static const unsigned s_refCountIncrement = 0x20;
    254     static const unsigned s_refCountFlagStatic = 0x10;
    255     static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x8;
    256     static const unsigned s_refCountFlagInTable = 0x4;
    257     static const unsigned s_refCountMaskBufferOwnership = 0x3;
    258 
    259238    const UChar* m_data;
    260239    SharedUChar* m_sharedBuffer;
    261     unsigned m_length;
    262     unsigned m_refCountAndFlags;
    263240    mutable unsigned m_hash;
    264241};
  • trunk/JavaScriptCore/wtf/text/StringImplBase.h

    r57912 r57932  
    11/*
    2  * Copyright (C) 2009 Apple Inc. All rights reserved.
     2 * Copyright (C) 2010 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 #ifndef UStringImpl_h
    27 #define UStringImpl_h
     26#ifndef StringImplBase_h
     27#define StringImplBase_h
    2828
    29 #include <limits>
    30 #include <wtf/CrossThreadRefCounted.h>
    31 #include <wtf/OwnFastMallocPtr.h>
    32 #include <wtf/PossiblyNull.h>
    33 #include <wtf/StringHashFunctions.h>
    34 #include <wtf/Vector.h>
     29#include <wtf/Noncopyable.h>
    3530#include <wtf/unicode/Unicode.h>
    3631
    37 namespace JSC {
     32namespace WTF {
    3833
    39 class IdentifierTable;
    40 
    41 typedef OwnFastMallocPtr<const UChar> SharableUChar;
    42 typedef CrossThreadRefCounted<SharableUChar> SharedUChar;
    43 
    44 class UStringImplBase : public Noncopyable {
     34class StringImplBase : public Noncopyable {
    4535public:
    4636    bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; }
    4737    unsigned length() const { return m_length; }
    48 
    4938    void ref() { m_refCountAndFlags += s_refCountIncrement; }
    5039
     
    5847
    5948    using Noncopyable::operator new;
    60     void* operator new(size_t, void* inPlace) { return inPlace; }
     49    void* operator new(size_t, void* inPlace) { ASSERT(inPlace); return inPlace; }
    6150
    6251    // For SmallStringStorage, which allocates an array and uses an in-place new.
    63     UStringImplBase() { }
     52    StringImplBase() { }
    6453
    65     UStringImplBase(unsigned length, BufferOwnership ownership)
     54    StringImplBase(unsigned length, BufferOwnership ownership)
    6655        : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership)
    6756        , m_length(length)
     
    7160
    7261    enum StaticStringConstructType { ConstructStaticString };
    73     UStringImplBase(unsigned length, StaticStringConstructType)
     62    StringImplBase(unsigned length, StaticStringConstructType)
    7463        : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned)
    7564        , m_length(length)
     
    7867    }
    7968
    80     // This constructor is not used when creating UStringImpl objects,
     69    // This constructor is not used when creating StringImpl objects,
    8170    // and sets the flags into a state marking the object as such.
    8271    enum NonStringImplConstructType { ConstructNonStringImpl };
    83     UStringImplBase(NonStringImplConstructType)
     72    StringImplBase(NonStringImplConstructType)
    8473        : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl)
    8574        , m_length(0)
     
    8877    }
    8978
    90     // The bottom 5 bits hold flags, the top 27 bits hold the ref count.
    91     // When dereferencing UStringImpls we check for the ref count AND the
     79    // The bottom 7 bits hold flags, the top 25 bits hold the ref count.
     80    // When dereferencing StringImpls we check for the ref count AND the
    9281    // static bit both being zero - static strings are never deleted.
    93     static const unsigned s_refCountMask = 0xFFFFFFE0;
    94     static const unsigned s_refCountIncrement = 0x20;
    95     static const unsigned s_refCountFlagStatic = 0x10;
     82    static const unsigned s_refCountMask = 0xFFFFFF80;
     83    static const unsigned s_refCountIncrement = 0x80;
     84    static const unsigned s_refCountFlagStatic = 0x40;
     85    static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x20;
     86    static const unsigned s_refCountFlagInTable = 0x10;
    9687    static const unsigned s_refCountFlagShouldReportedCost = 0x8;
    9788    static const unsigned s_refCountFlagIsIdentifier = 0x4;
     
    10697};
    10798
    108 class UStringImpl : public UStringImplBase {
    109     friend struct CStringTranslator;
    110     friend struct UCharBufferTranslator;
    111     friend class JIT;
    112     friend class SmallStringsStorage;
    113     friend void initializeUString();
    114 private:
    115     // For SmallStringStorage, which allocates an array and uses an in-place new.
    116     UStringImpl() { }
     99} // namespace WTF
    117100
    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         : UStringImplBase(length, ConstructStaticString)
    123         , m_data(characters)
    124         , m_buffer(0)
    125         , m_hash(0)
    126     {
    127         hash();
    128     }
    129 
    130     // Create a normal string with internal storage (BufferInternal)
    131     UStringImpl(unsigned length)
    132         : UStringImplBase(length, BufferInternal)
    133         , m_data(reinterpret_cast<UChar*>(this + 1))
    134         , m_buffer(0)
    135         , m_hash(0)
    136     {
    137         ASSERT(m_data);
    138         ASSERT(m_length);
    139     }
    140 
    141     // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned)
    142     UStringImpl(const UChar* characters, unsigned length)
    143         : UStringImplBase(length, BufferOwned)
    144         , m_data(characters)
    145         , m_buffer(0)
    146         , m_hash(0)
    147     {
    148         ASSERT(m_data);
    149         ASSERT(m_length);
    150     }
    151 
    152     // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring)
    153     UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base)
    154         : UStringImplBase(length, BufferSubstring)
    155         , m_data(characters)
    156         , m_substringBuffer(base.releaseRef())
    157         , m_hash(0)
    158     {
    159         ASSERT(m_data);
    160         ASSERT(m_length);
    161         ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring);
    162     }
    163 
    164     // Used to construct new strings sharing an existing SharedUChar (BufferShared)
    165     UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
    166         : UStringImplBase(length, BufferShared)
    167         , m_data(characters)
    168         , m_sharedBuffer(sharedBuffer.releaseRef())
    169         , m_hash(0)
    170     {
    171         ASSERT(m_data);
    172         ASSERT(m_length);
    173     }
    174 
    175     // For use only by Identifier's XXXTranslator helpers.
    176     void setHash(unsigned hash)
    177     {
    178         ASSERT(!isStatic());
    179         ASSERT(!m_hash);
    180         ASSERT(hash == computeHash(m_data, m_length));
    181         m_hash = hash;
    182     }
    183 
    184 public:
    185     ~UStringImpl();
    186 
    187     static PassRefPtr<UStringImpl> create(const UChar*, unsigned length);
    188     static PassRefPtr<UStringImpl> create(const char*, unsigned length);
    189     static PassRefPtr<UStringImpl> create(const char*);
    190     static PassRefPtr<UStringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar>);
    191     static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, unsigned offset, unsigned length)
    192     {
    193         ASSERT(rep);
    194         ASSERT(length <= rep->length());
    195 
    196         if (!length)
    197             return empty();
    198 
    199         UStringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get();
    200         return adoptRef(new UStringImpl(rep->m_data + offset, length, ownerRep));
    201     }
    202 
    203     static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output);
    204     static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
    205     {
    206         if (!length) {
    207             output = 0;
    208             return empty();
    209         }
    210 
    211         if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
    212             return 0;
    213         UStringImpl* resultImpl;
    214         if (!tryFastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)).getValue(resultImpl))
    215             return 0;
    216         output = reinterpret_cast<UChar*>(resultImpl + 1);
    217         return adoptRef(new(resultImpl) UStringImpl(length));
    218     }
    219 
    220     template<size_t inlineCapacity>
    221     static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
    222     {
    223         if (size_t size = vector.size()) {
    224             ASSERT(vector.data());
    225             return adoptRef(new UStringImpl(vector.releaseBuffer(), size));
    226         }
    227         return empty();
    228     }
    229 
    230     SharedUChar* sharedBuffer();
    231     const UChar* characters() const { return m_data; }
    232 
    233     size_t cost()
    234     {
    235         // For substrings, return the cost of the base string.
    236         if (bufferOwnership() == BufferSubstring)
    237             return m_substringBuffer->cost();
    238 
    239         if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) {
    240             m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost;
    241             return m_length;
    242         }
    243         return 0;
    244     }
    245 
    246     bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
    247     void setIsIdentifier(bool isIdentifier)
    248     {
    249         ASSERT(!isStatic());
    250         if (isIdentifier)
    251             m_refCountAndFlags |= s_refCountFlagIsIdentifier;
    252         else
    253             m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
    254     }
    255 
    256     unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
    257     unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
    258     static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); }
    259     static unsigned computeHash(const char* data, unsigned length) { return WTF::stringHash(data, length); }
    260     static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
    261 
    262     ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
    263 
    264     static UStringImpl* empty();
    265 
    266     static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
    267     {
    268         if (numCharacters <= s_copyCharsInlineCutOff) {
    269             for (unsigned i = 0; i < numCharacters; ++i)
    270                 destination[i] = source[i];
    271         } else
    272             memcpy(destination, source, numCharacters * sizeof(UChar));
    273     }
    274 
    275 private:
    276     // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
    277     static const unsigned s_copyCharsInlineCutOff = 20;
    278 
    279     BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
    280     bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
    281 
    282     const UChar* m_data;
    283     union {
    284         void* m_buffer;
    285         UStringImpl* m_substringBuffer;
    286         SharedUChar* m_sharedBuffer;
    287     };
    288     mutable unsigned m_hash;
    289 };
    290 
    291 bool equal(const UStringImpl*, const UStringImpl*);
    292 
    293 }
     101using WTF::StringImplBase;
    294102
    295103#endif
Note: See TracChangeset for help on using the changeset viewer.