Changeset 57912 in webkit for trunk/JavaScriptCore/runtime/UStringImpl.h
- Timestamp:
- Apr 20, 2010, 1:33:56 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/UStringImpl.h
r57851 r57912 42 42 typedef CrossThreadRefCounted<SharableUChar> SharedUChar; 43 43 44 class UString OrRopeImpl: public Noncopyable {44 class UStringImplBase : public Noncopyable { 45 45 public: 46 bool is Rope() { return (m_refCountAndFlags & s_refCountIsRope) == s_refCountIsRope; }46 bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; } 47 47 unsigned length() const { return m_length; } 48 48 49 49 void ref() { m_refCountAndFlags += s_refCountIncrement; } 50 inline void deref();51 50 52 51 protected: … … 62 61 63 62 // For SmallStringStorage, which allocates an array and uses an in-place new. 64 UString OrRopeImpl() { }65 66 UString OrRopeImpl(unsigned length, BufferOwnership ownership)63 UStringImplBase() { } 64 65 UStringImplBase(unsigned length, BufferOwnership ownership) 67 66 : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership) 68 67 , m_length(length) 69 68 { 70 ASSERT( !isRope());69 ASSERT(isStringImpl()); 71 70 } 72 71 73 72 enum StaticStringConstructType { ConstructStaticString }; 74 UString OrRopeImpl(unsigned length, StaticStringConstructType)73 UStringImplBase(unsigned length, StaticStringConstructType) 75 74 : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned) 76 75 , m_length(length) 77 76 { 78 ASSERT(!isRope()); 79 } 80 81 enum RopeConstructType { ConstructRope }; 82 UStringOrRopeImpl(RopeConstructType) 83 : m_refCountAndFlags(s_refCountIncrement | s_refCountIsRope) 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) 84 85 , m_length(0) 85 86 { 86 ASSERT( isRope());87 ASSERT(!isStringImpl()); 87 88 } 88 89 … … 96 97 static const unsigned s_refCountFlagIsIdentifier = 0x4; 97 98 static const unsigned s_refCountMaskBufferOwnership = 0x3; 98 // Use an otherwise invalid permutation of flags (static & shouldReportedCost -99 // s tatic strings do not set shouldReportedCost in the constructor, and this bit100 // is only ever cleared, not set) to identify objects that are ropes.101 static const unsigned s_refCountI sRope= s_refCountFlagStatic | s_refCountFlagShouldReportedCost;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; 102 103 103 104 unsigned m_refCountAndFlags; … … 105 106 }; 106 107 107 class UStringImpl : public UString OrRopeImpl{108 class UStringImpl : public UStringImplBase { 108 109 friend struct CStringTranslator; 109 110 friend struct UCharBufferTranslator; 110 111 friend class JIT; 111 112 friend class SmallStringsStorage; 112 friend class UStringOrRopeImpl;113 113 friend void initializeUString(); 114 114 private: … … 120 120 // static strings will be shared across threads & ref-counted in a non-threadsafe manner. 121 121 UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType) 122 : UString OrRopeImpl(length, ConstructStaticString)122 : UStringImplBase(length, ConstructStaticString) 123 123 , m_data(characters) 124 124 , m_buffer(0) … … 130 130 // Create a normal string with internal storage (BufferInternal) 131 131 UStringImpl(unsigned length) 132 : UString OrRopeImpl(length, BufferInternal)132 : UStringImplBase(length, BufferInternal) 133 133 , m_data(reinterpret_cast<UChar*>(this + 1)) 134 134 , m_buffer(0) … … 141 141 // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned) 142 142 UStringImpl(const UChar* characters, unsigned length) 143 : UString OrRopeImpl(length, BufferOwned)143 : UStringImplBase(length, BufferOwned) 144 144 , m_data(characters) 145 145 , m_buffer(0) … … 152 152 // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring) 153 153 UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base) 154 : UString OrRopeImpl(length, BufferSubstring)154 : UStringImplBase(length, BufferSubstring) 155 155 , m_data(characters) 156 156 , m_substringBuffer(base.releaseRef()) … … 164 164 // Used to construct new strings sharing an existing SharedUChar (BufferShared) 165 165 UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) 166 : UString OrRopeImpl(length, BufferShared)166 : UStringImplBase(length, BufferShared) 167 167 , m_data(characters) 168 168 , m_sharedBuffer(sharedBuffer.releaseRef()) … … 289 289 }; 290 290 291 class URopeImpl : public UStringOrRopeImpl { 292 friend class UStringOrRopeImpl; 293 public: 294 // A URopeImpl is composed from a set of smaller strings called Fibers. 295 // Each Fiber in a rope is either UStringImpl or another URopeImpl. 296 typedef UStringOrRopeImpl* Fiber; 297 298 // Creates a URopeImpl comprising of 'fiberCount' Fibers. 299 // The URopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the URopeImpl. 300 static PassRefPtr<URopeImpl> tryCreateUninitialized(unsigned fiberCount) 301 { 302 void* allocation; 303 if (tryFastMalloc(sizeof(URopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation)) 304 return adoptRef(new (allocation) URopeImpl(fiberCount)); 305 return 0; 306 } 307 308 void initializeFiber(unsigned &index, Fiber fiber) 309 { 310 m_fibers[index++] = fiber; 311 fiber->ref(); 312 m_length += fiber->length(); 313 } 314 315 unsigned fiberCount() { return m_fiberCount; } 316 Fiber& fibers(unsigned index) { return m_fibers[index]; } 317 318 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) destructNonRecursive(); } 319 320 private: 321 URopeImpl(unsigned fiberCount) : UStringOrRopeImpl(ConstructRope), m_fiberCount(fiberCount) {} 322 323 void destructNonRecursive(); 324 void derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue); 325 326 bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; } 327 328 unsigned m_fiberCount; 329 Fiber m_fibers[1]; 330 }; 331 332 inline void UStringOrRopeImpl::deref() 333 { 334 if (isRope()) 335 static_cast<URopeImpl*>(this)->deref(); 336 else 337 static_cast<UStringImpl*>(this)->deref(); 291 bool equal(const UStringImpl*, const UStringImpl*); 292 338 293 } 339 294 340 bool equal(const UStringImpl*, const UStringImpl*);341 342 }343 344 295 #endif
Note:
See TracChangeset
for help on using the changeset viewer.