Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights | 3 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights |
| 4 * reserved. | 4 * reserved. |
| 5 * Copyright (C) 2009 Google Inc. All rights reserved. | 5 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 | 23 |
| 24 #ifndef StringImpl_h | 24 #ifndef StringImpl_h |
| 25 #define StringImpl_h | 25 #define StringImpl_h |
| 26 | 26 |
| 27 #include "wtf/ASCIICType.h" | 27 #include "wtf/ASCIICType.h" |
| 28 #include "wtf/Forward.h" | 28 #include "wtf/Forward.h" |
| 29 #include "wtf/HashMap.h" | 29 #include "wtf/HashMap.h" |
| 30 #include "wtf/StringHasher.h" | 30 #include "wtf/StringHasher.h" |
| 31 #include "wtf/Vector.h" | 31 #include "wtf/Vector.h" |
| 32 #include "wtf/WTFExport.h" | 32 #include "wtf/WTFExport.h" |
| 33 #include "wtf/text/ASCIIFastPath.h" | |
| 33 #include "wtf/text/Unicode.h" | 34 #include "wtf/text/Unicode.h" |
| 34 #include <limits.h> | 35 #include <limits.h> |
| 35 #include <string.h> | 36 #include <string.h> |
| 36 | 37 |
| 37 #if OS(MACOSX) | 38 #if OS(MACOSX) |
| 38 typedef const struct __CFString* CFStringRef; | 39 typedef const struct __CFString* CFStringRef; |
| 39 #endif | 40 #endif |
| 40 | 41 |
| 41 #ifdef __OBJC__ | 42 #ifdef __OBJC__ |
| 42 @class NSString; | 43 @class NSString; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 #define STRING_STATS_ADD_16BIT_STRING(length) ((void)0) | 113 #define STRING_STATS_ADD_16BIT_STRING(length) ((void)0) |
| 113 #define STRING_STATS_REMOVE_STRING(string) ((void)0) | 114 #define STRING_STATS_REMOVE_STRING(string) ((void)0) |
| 114 #endif | 115 #endif |
| 115 | 116 |
| 116 // You can find documentation about this class in this doc: | 117 // You can find documentation about this class in this doc: |
| 117 // https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl 14/edit?usp=sharing | 118 // https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl 14/edit?usp=sharing |
| 118 class WTF_EXPORT StringImpl { | 119 class WTF_EXPORT StringImpl { |
| 119 WTF_MAKE_NONCOPYABLE(StringImpl); | 120 WTF_MAKE_NONCOPYABLE(StringImpl); |
| 120 | 121 |
| 121 private: | 122 private: |
| 123 enum ContainsASCIIFlag { | |
| 124 DoesNotContainOnlyASCII = 0, | |
| 125 ContainsOnlyASCII = 1, | |
| 126 NotCalculated = 2, | |
| 127 }; | |
| 122 // StringImpls are allocated out of the WTF buffer partition. | 128 // StringImpls are allocated out of the WTF buffer partition. |
| 123 void* operator new(size_t); | 129 void* operator new(size_t); |
| 124 void* operator new(size_t, void* ptr) { return ptr; } | 130 void* operator new(size_t, void* ptr) { return ptr; } |
| 125 void operator delete(void*); | 131 void operator delete(void*); |
| 126 | 132 |
| 127 // Used to construct static strings, which have an special refCount that can | 133 // Used to construct static strings, which have an special refCount that can |
| 128 // never hit zero. This means that the static string will never be | 134 // never hit zero. This means that the static string will never be |
| 129 // destroyed, which is important because static strings will be shared | 135 // destroyed, which is important because static strings will be shared |
| 130 // across threads & ref-counted in a non-threadsafe manner. | 136 // across threads & ref-counted in a non-threadsafe manner. |
| 131 enum ConstructEmptyStringTag { ConstructEmptyString }; | 137 enum ConstructEmptyStringTag { ConstructEmptyString }; |
| 132 explicit StringImpl(ConstructEmptyStringTag) | 138 explicit StringImpl(ConstructEmptyStringTag) |
| 133 : m_refCount(1), | 139 : m_refCount(1), |
| 134 m_length(0), | 140 m_length(0), |
| 135 m_hash(0), | 141 m_hash(0), |
| 142 m_containsOnlyASCII(NotCalculated), | |
| 136 m_isAtomic(false), | 143 m_isAtomic(false), |
| 137 m_is8Bit(true), | 144 m_is8Bit(true), |
| 138 m_isStatic(true) { | 145 m_isStatic(true) { |
| 139 // Ensure that the hash is computed so that AtomicStringHash can call | 146 // Ensure that the hash is computed so that AtomicStringHash can call |
| 140 // existingHash() with impunity. The empty string is special because it | 147 // existingHash() with impunity. The empty string is special because it |
| 141 // is never entered into AtomicString's HashKey, but still needs to | 148 // is never entered into AtomicString's HashKey, but still needs to |
| 142 // compare correctly. | 149 // compare correctly. |
| 143 STRING_STATS_ADD_8BIT_STRING(m_length); | 150 STRING_STATS_ADD_8BIT_STRING(m_length); |
| 144 hash(); | 151 hash(); |
| 145 } | 152 } |
| 146 | 153 |
| 147 enum ConstructEmptyString16BitTag { ConstructEmptyString16Bit }; | 154 enum ConstructEmptyString16BitTag { ConstructEmptyString16Bit }; |
| 148 explicit StringImpl(ConstructEmptyString16BitTag) | 155 explicit StringImpl(ConstructEmptyString16BitTag) |
| 149 : m_refCount(1), | 156 : m_refCount(1), |
| 150 m_length(0), | 157 m_length(0), |
| 151 m_hash(0), | 158 m_hash(0), |
| 159 m_containsOnlyASCII(NotCalculated), | |
| 152 m_isAtomic(false), | 160 m_isAtomic(false), |
| 153 m_is8Bit(false), | 161 m_is8Bit(false), |
| 154 m_isStatic(true) { | 162 m_isStatic(true) { |
| 155 STRING_STATS_ADD_16BIT_STRING(m_length); | 163 STRING_STATS_ADD_16BIT_STRING(m_length); |
| 156 hash(); | 164 hash(); |
| 157 } | 165 } |
| 158 | 166 |
| 159 // FIXME: there has to be a less hacky way to do this. | 167 // FIXME: there has to be a less hacky way to do this. |
| 160 enum Force8Bit { Force8BitConstructor }; | 168 enum Force8Bit { Force8BitConstructor }; |
| 161 StringImpl(unsigned length, Force8Bit) | 169 StringImpl(unsigned length, Force8Bit) |
| 162 : m_refCount(1), | 170 : m_refCount(1), |
| 163 m_length(length), | 171 m_length(length), |
| 164 m_hash(0), | 172 m_hash(0), |
| 173 m_containsOnlyASCII(NotCalculated), | |
| 165 m_isAtomic(false), | 174 m_isAtomic(false), |
| 166 m_is8Bit(true), | 175 m_is8Bit(true), |
| 167 m_isStatic(false) { | 176 m_isStatic(false) { |
| 168 ASSERT(m_length); | 177 ASSERT(m_length); |
| 169 STRING_STATS_ADD_8BIT_STRING(m_length); | 178 STRING_STATS_ADD_8BIT_STRING(m_length); |
| 170 } | 179 } |
| 171 | 180 |
| 172 StringImpl(unsigned length) | 181 StringImpl(unsigned length) |
| 173 : m_refCount(1), | 182 : m_refCount(1), |
| 174 m_length(length), | 183 m_length(length), |
| 175 m_hash(0), | 184 m_hash(0), |
| 185 m_containsOnlyASCII(NotCalculated), | |
| 176 m_isAtomic(false), | 186 m_isAtomic(false), |
| 177 m_is8Bit(false), | 187 m_is8Bit(false), |
| 178 m_isStatic(false) { | 188 m_isStatic(false) { |
| 179 ASSERT(m_length); | 189 ASSERT(m_length); |
| 180 STRING_STATS_ADD_16BIT_STRING(m_length); | 190 STRING_STATS_ADD_16BIT_STRING(m_length); |
| 181 } | 191 } |
| 182 | 192 |
| 183 enum StaticStringTag { StaticString }; | 193 enum StaticStringTag { StaticString }; |
| 184 StringImpl(unsigned length, unsigned hash, StaticStringTag) | 194 StringImpl(unsigned length, unsigned hash, StaticStringTag) |
| 185 : m_refCount(1), | 195 : m_refCount(1), |
| 186 m_length(length), | 196 m_length(length), |
| 187 m_hash(hash), | 197 m_hash(hash), |
| 198 m_containsOnlyASCII(NotCalculated), | |
| 188 m_isAtomic(false), | 199 m_isAtomic(false), |
| 189 m_is8Bit(true), | 200 m_is8Bit(true), |
| 190 m_isStatic(true) {} | 201 m_isStatic(true) {} |
| 191 | 202 |
| 192 public: | 203 public: |
| 193 ~StringImpl(); | 204 ~StringImpl(); |
| 194 | 205 |
| 195 static StringImpl* createStatic(const char* string, | 206 static StringImpl* createStatic(const char* string, |
| 196 unsigned length, | 207 unsigned length, |
| 197 unsigned hash); | 208 unsigned hash); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 | 257 |
| 247 size_t charactersSizeInBytes() const { | 258 size_t charactersSizeInBytes() const { |
| 248 return length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); | 259 return length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); |
| 249 } | 260 } |
| 250 | 261 |
| 251 bool isAtomic() const { return m_isAtomic; } | 262 bool isAtomic() const { return m_isAtomic; } |
| 252 void setIsAtomic(bool isAtomic) { m_isAtomic = isAtomic; } | 263 void setIsAtomic(bool isAtomic) { m_isAtomic = isAtomic; } |
| 253 | 264 |
| 254 bool isStatic() const { return m_isStatic; } | 265 bool isStatic() const { return m_isStatic; } |
| 255 | 266 |
| 267 bool containsOnlyASCII() const; | |
| 268 | |
| 256 bool isSafeToSendToAnotherThread() const; | 269 bool isSafeToSendToAnotherThread() const; |
| 257 | 270 |
| 258 // The high bits of 'hash' are always empty, but we prefer to store our | 271 // The high bits of 'hash' are always empty, but we prefer to store our |
| 259 // flags in the low bits because it makes them slightly more efficient to | 272 // flags in the low bits because it makes them slightly more efficient to |
| 260 // access. So, we shift left and right when setting and getting our hash | 273 // access. So, we shift left and right when setting and getting our hash |
| 261 // code. | 274 // code. |
| 262 void setHash(unsigned hash) const { | 275 void setHash(unsigned hash) const { |
| 263 DCHECK(!hasHash()); | 276 DCHECK(!hasHash()); |
| 264 // Multiple clients assume that StringHasher is the canonical string | 277 // Multiple clients assume that StringHasher is the canonical string |
| 265 // hash function. | 278 // hash function. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 ASSERT(hasHash()); | 504 ASSERT(hasHash()); |
| 492 ASSERT(existingHash() == | 505 ASSERT(existingHash() == |
| 493 StringHasher::computeHashAndMaskTop8Bits(characters8(), length())); | 506 StringHasher::computeHashAndMaskTop8Bits(characters8(), length())); |
| 494 } | 507 } |
| 495 #endif | 508 #endif |
| 496 | 509 |
| 497 private: | 510 private: |
| 498 unsigned m_refCount; | 511 unsigned m_refCount; |
| 499 const unsigned m_length; | 512 const unsigned m_length; |
| 500 mutable unsigned m_hash : 24; | 513 mutable unsigned m_hash : 24; |
| 514 // Tristate enum set lazily on calls to containsOnlyASCII. | |
| 515 mutable unsigned m_containsOnlyASCII : 2; | |
| 501 unsigned m_isAtomic : 1; | 516 unsigned m_isAtomic : 1; |
| 502 const unsigned m_is8Bit : 1; | 517 const unsigned m_is8Bit : 1; |
| 503 const unsigned m_isStatic : 1; | 518 const unsigned m_isStatic : 1; |
| 504 }; | 519 }; |
| 505 | 520 |
| 506 template <> | 521 template <> |
| 507 ALWAYS_INLINE const LChar* StringImpl::getCharacters<LChar>() const { | 522 ALWAYS_INLINE const LChar* StringImpl::getCharacters<LChar>() const { |
| 508 return characters8(); | 523 return characters8(); |
| 509 } | 524 } |
| 510 | 525 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 524 return equal(a, reinterpret_cast<const LChar*>(b), length); | 539 return equal(a, reinterpret_cast<const LChar*>(b), length); |
| 525 } | 540 } |
| 526 inline bool equal(const LChar* a, StringImpl* b) { | 541 inline bool equal(const LChar* a, StringImpl* b) { |
| 527 return equal(b, a); | 542 return equal(b, a); |
| 528 } | 543 } |
| 529 inline bool equal(const char* a, StringImpl* b) { | 544 inline bool equal(const char* a, StringImpl* b) { |
| 530 return equal(b, reinterpret_cast<const LChar*>(a)); | 545 return equal(b, reinterpret_cast<const LChar*>(a)); |
| 531 } | 546 } |
| 532 WTF_EXPORT bool equalNonNull(const StringImpl* a, const StringImpl* b); | 547 WTF_EXPORT bool equalNonNull(const StringImpl* a, const StringImpl* b); |
| 533 | 548 |
| 549 inline bool StringImpl::containsOnlyASCII() const { | |
| 550 if (m_containsOnlyASCII == NotCalculated) { | |
| 551 m_containsOnlyASCII = | |
| 552 !length() || | |
| 553 (is8Bit() ? charactersAreAllASCII(characters8(), length()) | |
| 554 : charactersAreAllASCII(characters16(), length())); | |
|
kinuko
2016/12/26 07:32:19
I'd defer the judgement to esprehn (so you might w
| |
| 555 } | |
| 556 return m_containsOnlyASCII; | |
| 557 } | |
| 558 | |
| 534 template <typename CharType> | 559 template <typename CharType> |
| 535 ALWAYS_INLINE bool equal(const CharType* a, | 560 ALWAYS_INLINE bool equal(const CharType* a, |
| 536 const CharType* b, | 561 const CharType* b, |
| 537 unsigned length) { | 562 unsigned length) { |
| 538 return !memcmp(a, b, length * sizeof(CharType)); | 563 return !memcmp(a, b, length * sizeof(CharType)); |
| 539 } | 564 } |
| 540 | 565 |
| 541 ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length) { | 566 ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length) { |
| 542 for (unsigned i = 0; i < length; ++i) { | 567 for (unsigned i = 0; i < length; ++i) { |
| 543 if (a[i] != b[i]) | 568 if (a[i] != b[i]) |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 using WTF::TextCaseASCIIInsensitive; | 867 using WTF::TextCaseASCIIInsensitive; |
| 843 using WTF::TextCaseUnicodeInsensitive; | 868 using WTF::TextCaseUnicodeInsensitive; |
| 844 using WTF::TextCaseSensitive; | 869 using WTF::TextCaseSensitive; |
| 845 using WTF::TextCaseSensitivity; | 870 using WTF::TextCaseSensitivity; |
| 846 using WTF::equal; | 871 using WTF::equal; |
| 847 using WTF::equalNonNull; | 872 using WTF::equalNonNull; |
| 848 using WTF::lengthOfNullTerminatedString; | 873 using WTF::lengthOfNullTerminatedString; |
| 849 using WTF::reverseFind; | 874 using WTF::reverseFind; |
| 850 | 875 |
| 851 #endif | 876 #endif |
| OLD | NEW |