Changeset 57932 in webkit for trunk/JavaScriptCore
- Timestamp:
- Apr 20, 2010, 3:34:52 PM (15 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r57925 r57932 1 2010-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 1 24 2010-04-20 Oliver Hunt <[email protected]> 2 25 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r57925 r57932 217 217 86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */; }; 218 218 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, ); }; }; 219 221 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; }; 220 222 86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; }; … … 758 760 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RopeImpl.cpp; sourceTree = "<group>"; }; 759 761 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>"; }; 760 764 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; }; 761 765 86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; }; … … 1678 1682 86565740115BE3DA00291F40 /* CString.cpp */, 1679 1683 86565741115BE3DA00291F40 /* CString.h */, 1684 86B99AE1117E578100DF5A90 /* StringBuffer.h */, 1680 1685 868BFA05117CEFD100B908B1 /* StringHash.h */, 1681 1686 868BFA06117CEFD100B908B1 /* StringImpl.cpp */, 1682 1687 868BFA07117CEFD100B908B1 /* StringImpl.h */, 1688 86B99AE2117E578100DF5A90 /* StringImplBase.h */, 1683 1689 868BFA15117CF19900B908B1 /* WTFString.cpp */, 1684 1690 868BFA16117CF19900B908B1 /* WTFString.h */, … … 2085 2091 868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */, 2086 2092 86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */, 2093 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */, 2094 86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */, 2087 2095 ); 2088 2096 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/runtime/RopeImpl.h
r57912 r57932 31 31 namespace JSC { 32 32 33 class RopeImpl : public UStringImplBase {33 class RopeImpl : public StringImplBase { 34 34 public: 35 35 // A RopeImpl is composed from a set of smaller strings called Fibers. 36 36 // Each Fiber in a rope is either UStringImpl or another RopeImpl. 37 typedef UStringImplBase* Fiber;37 typedef StringImplBase* Fiber; 38 38 39 39 // Creates a RopeImpl comprising of 'fiberCount' Fibers. … … 73 73 74 74 private: 75 RopeImpl(unsigned fiberCount) : UStringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {}75 RopeImpl(unsigned fiberCount) : StringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {} 76 76 77 77 void destructNonRecursive(); -
trunk/JavaScriptCore/runtime/UStringImpl.h
r57912 r57932 34 34 #include <wtf/Vector.h> 35 35 #include <wtf/unicode/Unicode.h> 36 #include <wtf/text/StringImplBase.h> 36 37 37 38 namespace JSC { … … 42 43 typedef CrossThreadRefCounted<SharableUChar> SharedUChar; 43 44 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 { 45 class UStringImpl : public StringImplBase { 109 46 friend struct CStringTranslator; 110 47 friend struct UCharBufferTranslator; … … 120 57 // static strings will be shared across threads & ref-counted in a non-threadsafe manner. 121 58 UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType) 122 : UStringImplBase(length, ConstructStaticString)59 : StringImplBase(length, ConstructStaticString) 123 60 , m_data(characters) 124 61 , m_buffer(0) … … 130 67 // Create a normal string with internal storage (BufferInternal) 131 68 UStringImpl(unsigned length) 132 : UStringImplBase(length, BufferInternal)69 : StringImplBase(length, BufferInternal) 133 70 , m_data(reinterpret_cast<UChar*>(this + 1)) 134 71 , m_buffer(0) … … 141 78 // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned) 142 79 UStringImpl(const UChar* characters, unsigned length) 143 : UStringImplBase(length, BufferOwned)80 : StringImplBase(length, BufferOwned) 144 81 , m_data(characters) 145 82 , m_buffer(0) … … 152 89 // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring) 153 90 UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base) 154 : UStringImplBase(length, BufferSubstring)91 : StringImplBase(length, BufferSubstring) 155 92 , m_data(characters) 156 93 , m_substringBuffer(base.releaseRef()) … … 164 101 // Used to construct new strings sharing an existing SharedUChar (BufferShared) 165 102 UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) 166 : UStringImplBase(length, BufferShared)103 : StringImplBase(length, BufferShared) 167 104 , m_data(characters) 168 105 , m_sharedBuffer(sharedBuffer.releaseRef()) -
trunk/JavaScriptCore/wtf/text/StringImpl.h
r57904 r57932 32 32 #include <wtf/StringHashFunctions.h> 33 33 #include <wtf/Vector.h> 34 #include <wtf/text/StringImplBase.h> 34 35 #include <wtf/unicode/Unicode.h> 35 36 … … 59 60 typedef bool (*CharacterMatchFunctionPtr)(UChar); 60 61 61 class StringImpl : public Noncopyable {62 class StringImpl : public StringImplBase { 62 63 friend struct CStringTranslator; 63 64 friend struct HashAndCharactersTranslator; 64 65 friend struct UCharBufferTranslator; 65 66 private: 66 enum BufferOwnership {67 BufferInternal,68 BufferOwned,69 BufferShared,70 };71 67 72 68 // Used to construct static strings, which have an special refCount that can never hit zero. 73 69 // This means that the static string will never be destroyed, which is important because 74 70 // static strings will be shared across threads & ref-counted in a non-threadsafe manner. 75 enum StaticStringConstructType { ConstructStaticString };76 71 StringImpl(const UChar* characters, unsigned length, StaticStringConstructType) 77 : m_data(characters) 72 : StringImplBase(length, ConstructStaticString) 73 , m_data(characters) 78 74 , m_sharedBuffer(0) 79 , m_length(length)80 , m_refCountAndFlags(s_refCountFlagStatic | BufferInternal)81 75 , m_hash(0) 82 76 { … … 89 83 // Create a normal string with internal storage (BufferInternal) 90 84 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)) 92 87 , m_sharedBuffer(0) 93 , m_length(length)94 , m_refCountAndFlags(s_refCountIncrement | BufferInternal)95 88 , m_hash(0) 96 89 { … … 101 94 // Create a StringImpl adopting ownership of the provided buffer (BufferOwned) 102 95 StringImpl(const UChar* characters, unsigned length) 103 : m_data(characters) 96 : StringImplBase(length, BufferOwned) 97 , m_data(characters) 104 98 , m_sharedBuffer(0) 105 , m_length(length)106 , m_refCountAndFlags(s_refCountIncrement | BufferOwned)107 99 , m_hash(0) 108 100 { … … 113 105 // Used to construct new strings sharing an existing SharedUChar (BufferShared) 114 106 StringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) 115 : m_data(characters) 107 : StringImplBase(length, BufferShared) 108 , m_data(characters) 116 109 , m_sharedBuffer(sharedBuffer.releaseRef()) 117 , m_length(length)118 , m_refCountAndFlags(s_refCountIncrement | BufferShared)119 110 , m_hash(0) 120 111 { … … 157 148 SharedUChar* sharedBuffer(); 158 149 const UChar* characters() const { return m_data; } 159 unsigned length() { return m_length; }160 150 161 151 bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; } … … 169 159 static unsigned computeHash(const char* data) { return WTF::stringHash(data); } 170 160 171 StringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; }172 161 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; } 173 162 ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; } … … 242 231 243 232 private: 244 using Noncopyable::operator new;245 void* operator new(size_t, void* inPlace) { ASSERT(inPlace); return inPlace; }246 247 233 static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length); 248 234 … … 250 236 bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; } 251 237 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 259 238 const UChar* m_data; 260 239 SharedUChar* m_sharedBuffer; 261 unsigned m_length;262 unsigned m_refCountAndFlags;263 240 mutable unsigned m_hash; 264 241 }; -
trunk/JavaScriptCore/wtf/text/StringImplBase.h
r57912 r57932 1 1 /* 2 * Copyright (C) 20 09Apple Inc. All rights reserved.2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #ifndef UStringImpl_h27 #define UStringImpl_h26 #ifndef StringImplBase_h 27 #define StringImplBase_h 28 28 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> 35 30 #include <wtf/unicode/Unicode.h> 36 31 37 namespace JSC{32 namespace WTF { 38 33 39 class IdentifierTable; 40 41 typedef OwnFastMallocPtr<const UChar> SharableUChar; 42 typedef CrossThreadRefCounted<SharableUChar> SharedUChar; 43 44 class UStringImplBase : public Noncopyable { 34 class StringImplBase : public Noncopyable { 45 35 public: 46 36 bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; } 47 37 unsigned length() const { return m_length; } 48 49 38 void ref() { m_refCountAndFlags += s_refCountIncrement; } 50 39 … … 58 47 59 48 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; } 61 50 62 51 // For SmallStringStorage, which allocates an array and uses an in-place new. 63 UStringImplBase() { }52 StringImplBase() { } 64 53 65 UStringImplBase(unsigned length, BufferOwnership ownership)54 StringImplBase(unsigned length, BufferOwnership ownership) 66 55 : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership) 67 56 , m_length(length) … … 71 60 72 61 enum StaticStringConstructType { ConstructStaticString }; 73 UStringImplBase(unsigned length, StaticStringConstructType)62 StringImplBase(unsigned length, StaticStringConstructType) 74 63 : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned) 75 64 , m_length(length) … … 78 67 } 79 68 80 // This constructor is not used when creating UStringImpl objects,69 // This constructor is not used when creating StringImpl objects, 81 70 // and sets the flags into a state marking the object as such. 82 71 enum NonStringImplConstructType { ConstructNonStringImpl }; 83 UStringImplBase(NonStringImplConstructType)72 StringImplBase(NonStringImplConstructType) 84 73 : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl) 85 74 , m_length(0) … … 88 77 } 89 78 90 // The bottom 5 bits hold flags, the top 27bits hold the ref count.91 // When dereferencing UStringImpls we check for the ref count AND the79 // 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 92 81 // 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; 96 87 static const unsigned s_refCountFlagShouldReportedCost = 0x8; 97 88 static const unsigned s_refCountFlagIsIdentifier = 0x4; … … 106 97 }; 107 98 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 117 100 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 } 101 using WTF::StringImplBase; 294 102 295 103 #endif
Note:
See TracChangeset
for help on using the changeset viewer.