Changeset 54743 in webkit for trunk/JavaScriptCore/runtime/UStringImpl.h
- Timestamp:
- Feb 12, 2010, 3:57:35 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/UStringImpl.h
r54563 r54743 41 41 typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar; 42 42 43 class UntypedPtrAndBitfield {44 public:45 UntypedPtrAndBitfield() {}46 47 UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue)48 : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue)49 #ifndef NDEBUG50 , m_leaksPtr(ptrValue)51 #endif52 {53 ASSERT(ptrValue == asPtr<void*>());54 ASSERT((*this & ~s_alignmentMask) == bitValue);55 }56 57 template<typename T>58 T asPtr() const { return reinterpret_cast<T>(m_value & s_alignmentMask); }59 60 UntypedPtrAndBitfield& operator&=(uintptr_t bits)61 {62 m_value &= bits | s_alignmentMask;63 return *this;64 }65 66 UntypedPtrAndBitfield& operator|=(uintptr_t bits)67 {68 m_value |= bits & ~s_alignmentMask;69 return *this;70 }71 72 uintptr_t operator&(uintptr_t mask) const73 {74 return m_value & mask & ~s_alignmentMask;75 }76 77 private:78 static const uintptr_t s_alignmentMask = ~static_cast<uintptr_t>(0x7);79 uintptr_t m_value;80 #ifndef NDEBUG81 void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced.82 #endif83 };84 85 43 class UStringImpl : Noncopyable { 86 44 public: … … 148 106 // For substrings, return the cost of the base string. 149 107 if (bufferOwnership() == BufferSubstring) 150 return m_ dataBuffer.asPtr<UStringImpl*>()->cost();151 152 if (m_ dataBuffer & s_reportedCostBit)108 return m_bufferSubstring->cost(); 109 110 if (m_refCountAndFlags & s_refCountFlagHasReportedCost) 153 111 return 0; 154 m_ dataBuffer |= s_reportedCostBit;112 m_refCountAndFlags |= s_refCountFlagHasReportedCost; 155 113 return m_length; 156 114 } … … 158 116 unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers 159 117 void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers 160 bool isIdentifier() const { return m_isIdentifier; } 161 void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; } 162 163 UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; } 164 ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; } 118 bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; } 119 void setIsIdentifier(bool isIdentifier) 120 { 121 if (isIdentifier) 122 m_refCountAndFlags |= s_refCountFlagIsIdentifier; 123 else 124 m_refCountAndFlags &= ~s_refCountFlagIsIdentifier; 125 } 126 127 UStringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; } 128 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) delete this; } 165 129 166 130 static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) … … 201 165 UStringImpl(UChar* data, int length, BufferOwnership ownership) 202 166 : m_data(data) 203 , m_length(length) 204 , m_refCount(s_refCountIncrement) 205 , m_hash(0) 206 , m_isIdentifier(false) 207 , m_dataBuffer(0, ownership) 167 , m_buffer(0) 168 , m_length(length) 169 , m_refCountAndFlags(s_refCountIncrement | ownership) 170 , m_hash(0) 208 171 { 209 172 ASSERT((ownership == BufferInternal) || (ownership == BufferOwned)); … … 217 180 UStringImpl(UChar* data, int length, StaticStringConstructType) 218 181 : m_data(data) 219 , m_length(length) 220 , m_refCount(s_staticRefCountInitialValue) 221 , m_hash(0) 222 , m_isIdentifier(false) 223 , m_dataBuffer(0, BufferOwned) 182 , m_buffer(0) 183 , m_length(length) 184 , m_refCountAndFlags(s_refCountFlagStatic | BufferOwned) 185 , m_hash(0) 224 186 { 225 187 checkConsistency(); … … 229 191 UStringImpl(UChar* data, int length, PassRefPtr<UStringImpl> base) 230 192 : m_data(data) 231 , m_length(length) 232 , m_refCount(s_refCountIncrement) 233 , m_hash(0) 234 , m_isIdentifier(false) 235 , m_dataBuffer(base.releaseRef(), BufferSubstring) 193 , m_bufferSubstring(base.releaseRef()) 194 , m_length(length) 195 , m_refCountAndFlags(s_refCountIncrement | BufferSubstring) 196 , m_hash(0) 236 197 { 237 198 // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes 238 199 // that all pointers will be at least 8-byte aligned, we cannot guarantee that of 239 200 // UStringImpls that are not heap allocated. 240 ASSERT(m_ dataBuffer.asPtr<UStringImpl*>()->size());241 ASSERT(!m_ dataBuffer.asPtr<UStringImpl*>()->isStatic());201 ASSERT(m_bufferSubstring->size()); 202 ASSERT(!m_bufferSubstring->isStatic()); 242 203 checkConsistency(); 243 204 } … … 246 207 UStringImpl(UChar* data, int length, PassRefPtr<SharedUChar> sharedBuffer) 247 208 : m_data(data) 248 , m_length(length) 249 , m_refCount(s_refCountIncrement) 250 , m_hash(0) 251 , m_isIdentifier(false) 252 , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared) 209 , m_bufferShared(sharedBuffer.releaseRef()) 210 , m_length(length) 211 , m_refCountAndFlags(s_refCountIncrement | BufferShared) 212 , m_hash(0) 253 213 { 254 214 checkConsistency(); … … 263 223 static const int s_minLengthToShare = 10; 264 224 static const unsigned s_copyCharsInlineCutOff = 20; 265 static const uintptr_t s_bufferOwnershipMask = 3;266 static const uintptr_t s_reportedCostBit = 4;267 225 // We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2. 268 226 // We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero. 269 static const int s_refCountIncrement = 2; 270 static const int s_staticRefCountInitialValue = 1; 271 272 UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; } 273 const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; } 227 static const unsigned s_refCountMask = 0xFFFFFFF0; 228 static const int s_refCountIncrement = 0x20; 229 static const int s_refCountFlagStatic = 0x10; 230 static const unsigned s_refCountFlagHasReportedCost = 0x8; 231 static const unsigned s_refCountFlagIsIdentifier = 0x4; 232 static const unsigned s_refCountMaskBufferOwnership = 0x3; 233 234 UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring : this; } 235 const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring : this; } 274 236 SharedUChar* baseSharedBuffer(); 275 unsigned bufferOwnership() const { return m_ dataBuffer & s_bufferOwnershipMask; }276 bool isStatic() const { return m_refCount & 1; }237 unsigned bufferOwnership() const { return m_refCountAndFlags & s_refCountMaskBufferOwnership; } 238 bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; } 277 239 278 240 // unshared data 279 241 UChar* m_data; 242 union { 243 void* m_buffer; 244 UStringImpl* m_bufferSubstring; 245 SharedUChar* m_bufferShared; 246 }; 280 247 int m_length; 281 unsigned m_refCount; 282 mutable unsigned m_hash : 31; 283 mutable unsigned m_isIdentifier : 1; 284 UntypedPtrAndBitfield m_dataBuffer; 248 unsigned m_refCountAndFlags; 249 mutable unsigned m_hash; 285 250 286 251 JS_EXPORTDATA static UStringImpl* s_empty;
Note:
See TracChangeset
for help on using the changeset viewer.