Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1193)

Side by Side Diff: third_party/WebKit/Source/wtf/text/StringImpl.h

Issue 2585063002: Cache contains only ascii in StringImpl (Closed)
Patch Set: DCHECK + static_Cast Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 127
127 // Used to construct static strings, which have an special refCount that can 128 // 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 129 // never hit zero. This means that the static string will never be
129 // destroyed, which is important because static strings will be shared 130 // destroyed, which is important because static strings will be shared
130 // across threads & ref-counted in a non-threadsafe manner. 131 // across threads & ref-counted in a non-threadsafe manner.
131 enum ConstructEmptyStringTag { ConstructEmptyString }; 132 enum ConstructEmptyStringTag { ConstructEmptyString };
132 explicit StringImpl(ConstructEmptyStringTag) 133 explicit StringImpl(ConstructEmptyStringTag)
133 : m_refCount(1), 134 : m_refCount(1),
134 m_length(0), 135 m_length(0),
135 m_hash(0), 136 m_hash(0),
137 m_containsOnlyASCII(true),
138 m_needsASCIICheck(false),
136 m_isAtomic(false), 139 m_isAtomic(false),
137 m_is8Bit(true), 140 m_is8Bit(true),
138 m_isStatic(true) { 141 m_isStatic(true) {
139 // Ensure that the hash is computed so that AtomicStringHash can call 142 // Ensure that the hash is computed so that AtomicStringHash can call
140 // existingHash() with impunity. The empty string is special because it 143 // existingHash() with impunity. The empty string is special because it
141 // is never entered into AtomicString's HashKey, but still needs to 144 // is never entered into AtomicString's HashKey, but still needs to
142 // compare correctly. 145 // compare correctly.
143 STRING_STATS_ADD_8BIT_STRING(m_length); 146 STRING_STATS_ADD_8BIT_STRING(m_length);
144 hash(); 147 hash();
145 } 148 }
146 149
147 enum ConstructEmptyString16BitTag { ConstructEmptyString16Bit }; 150 enum ConstructEmptyString16BitTag { ConstructEmptyString16Bit };
148 explicit StringImpl(ConstructEmptyString16BitTag) 151 explicit StringImpl(ConstructEmptyString16BitTag)
149 : m_refCount(1), 152 : m_refCount(1),
150 m_length(0), 153 m_length(0),
151 m_hash(0), 154 m_hash(0),
155 m_containsOnlyASCII(true),
156 m_needsASCIICheck(false),
152 m_isAtomic(false), 157 m_isAtomic(false),
153 m_is8Bit(false), 158 m_is8Bit(false),
154 m_isStatic(true) { 159 m_isStatic(true) {
155 STRING_STATS_ADD_16BIT_STRING(m_length); 160 STRING_STATS_ADD_16BIT_STRING(m_length);
156 hash(); 161 hash();
157 } 162 }
158 163
159 // FIXME: there has to be a less hacky way to do this. 164 // FIXME: there has to be a less hacky way to do this.
160 enum Force8Bit { Force8BitConstructor }; 165 enum Force8Bit { Force8BitConstructor };
161 StringImpl(unsigned length, Force8Bit) 166 StringImpl(unsigned length, Force8Bit)
162 : m_refCount(1), 167 : m_refCount(1),
163 m_length(length), 168 m_length(length),
164 m_hash(0), 169 m_hash(0),
170 m_containsOnlyASCII(!length),
171 m_needsASCIICheck(static_cast<bool>(length)),
165 m_isAtomic(false), 172 m_isAtomic(false),
166 m_is8Bit(true), 173 m_is8Bit(true),
167 m_isStatic(false) { 174 m_isStatic(false) {
168 DCHECK(m_length); 175 DCHECK(m_length);
169 STRING_STATS_ADD_8BIT_STRING(m_length); 176 STRING_STATS_ADD_8BIT_STRING(m_length);
170 } 177 }
171 178
172 StringImpl(unsigned length) 179 StringImpl(unsigned length)
173 : m_refCount(1), 180 : m_refCount(1),
174 m_length(length), 181 m_length(length),
175 m_hash(0), 182 m_hash(0),
183 m_containsOnlyASCII(!length),
184 m_needsASCIICheck(static_cast<bool>(length)),
176 m_isAtomic(false), 185 m_isAtomic(false),
177 m_is8Bit(false), 186 m_is8Bit(false),
178 m_isStatic(false) { 187 m_isStatic(false) {
179 DCHECK(m_length); 188 DCHECK(m_length);
180 STRING_STATS_ADD_16BIT_STRING(m_length); 189 STRING_STATS_ADD_16BIT_STRING(m_length);
181 } 190 }
182 191
183 enum StaticStringTag { StaticString }; 192 enum StaticStringTag { StaticString };
184 StringImpl(unsigned length, unsigned hash, StaticStringTag) 193 StringImpl(unsigned length, unsigned hash, StaticStringTag)
185 : m_refCount(1), 194 : m_refCount(1),
186 m_length(length), 195 m_length(length),
187 m_hash(hash), 196 m_hash(hash),
197 m_containsOnlyASCII(!length),
198 m_needsASCIICheck(static_cast<bool>(length)),
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
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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 unsigned replacementLength); 481 unsigned replacementLength);
469 482
470 template <class UCharPredicate> 483 template <class UCharPredicate>
471 PassRefPtr<StringImpl> stripMatchedCharacters(UCharPredicate); 484 PassRefPtr<StringImpl> stripMatchedCharacters(UCharPredicate);
472 template <typename CharType, class UCharPredicate> 485 template <typename CharType, class UCharPredicate>
473 PassRefPtr<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate, 486 PassRefPtr<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate,
474 StripBehavior); 487 StripBehavior);
475 NEVER_INLINE unsigned hashSlowCase() const; 488 NEVER_INLINE unsigned hashSlowCase() const;
476 489
477 void destroyIfNotStatic(); 490 void destroyIfNotStatic();
491 void updateContainsOnlyASCII() const;
478 492
479 #ifdef STRING_STATS 493 #ifdef STRING_STATS
480 static StringStats m_stringStats; 494 static StringStats m_stringStats;
481 #endif 495 #endif
482 496
483 static unsigned m_highestStaticStringLength; 497 static unsigned m_highestStaticStringLength;
484 498
485 #if DCHECK_IS_ON() 499 #if DCHECK_IS_ON()
486 void assertHashIsCorrect() { 500 void assertHashIsCorrect() {
487 DCHECK(hasHash()); 501 DCHECK(hasHash());
488 DCHECK_EQ(existingHash(), StringHasher::computeHashAndMaskTop8Bits( 502 DCHECK_EQ(existingHash(), StringHasher::computeHashAndMaskTop8Bits(
489 characters8(), length())); 503 characters8(), length()));
490 } 504 }
491 #endif 505 #endif
492 506
493 private: 507 private:
494 unsigned m_refCount; 508 unsigned m_refCount;
495 const unsigned m_length; 509 const unsigned m_length;
496 mutable unsigned m_hash : 24; 510 mutable unsigned m_hash : 24;
511 mutable unsigned m_containsOnlyASCII : 1;
512 mutable unsigned m_needsASCIICheck : 1;
497 unsigned m_isAtomic : 1; 513 unsigned m_isAtomic : 1;
498 const unsigned m_is8Bit : 1; 514 const unsigned m_is8Bit : 1;
499 const unsigned m_isStatic : 1; 515 const unsigned m_isStatic : 1;
500 }; 516 };
501 517
502 template <> 518 template <>
503 ALWAYS_INLINE const LChar* StringImpl::getCharacters<LChar>() const { 519 ALWAYS_INLINE const LChar* StringImpl::getCharacters<LChar>() const {
504 return characters8(); 520 return characters8();
505 } 521 }
506 522
(...skipping 13 matching lines...) Expand all
520 return equal(a, reinterpret_cast<const LChar*>(b), length); 536 return equal(a, reinterpret_cast<const LChar*>(b), length);
521 } 537 }
522 inline bool equal(const LChar* a, StringImpl* b) { 538 inline bool equal(const LChar* a, StringImpl* b) {
523 return equal(b, a); 539 return equal(b, a);
524 } 540 }
525 inline bool equal(const char* a, StringImpl* b) { 541 inline bool equal(const char* a, StringImpl* b) {
526 return equal(b, reinterpret_cast<const LChar*>(a)); 542 return equal(b, reinterpret_cast<const LChar*>(a));
527 } 543 }
528 WTF_EXPORT bool equalNonNull(const StringImpl* a, const StringImpl* b); 544 WTF_EXPORT bool equalNonNull(const StringImpl* a, const StringImpl* b);
529 545
546 ALWAYS_INLINE bool StringImpl::containsOnlyASCII() const {
547 if (m_needsASCIICheck)
548 updateContainsOnlyASCII();
549 return m_containsOnlyASCII;
550 }
551
530 template <typename CharType> 552 template <typename CharType>
531 ALWAYS_INLINE bool equal(const CharType* a, 553 ALWAYS_INLINE bool equal(const CharType* a,
532 const CharType* b, 554 const CharType* b,
533 unsigned length) { 555 unsigned length) {
534 return !memcmp(a, b, length * sizeof(CharType)); 556 return !memcmp(a, b, length * sizeof(CharType));
535 } 557 }
536 558
537 ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length) { 559 ALWAYS_INLINE bool equal(const LChar* a, const UChar* b, unsigned length) {
538 for (unsigned i = 0; i < length; ++i) { 560 for (unsigned i = 0; i < length; ++i) {
539 if (a[i] != b[i]) 561 if (a[i] != b[i])
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 using WTF::TextCaseASCIIInsensitive; 860 using WTF::TextCaseASCIIInsensitive;
839 using WTF::TextCaseUnicodeInsensitive; 861 using WTF::TextCaseUnicodeInsensitive;
840 using WTF::TextCaseSensitive; 862 using WTF::TextCaseSensitive;
841 using WTF::TextCaseSensitivity; 863 using WTF::TextCaseSensitivity;
842 using WTF::equal; 864 using WTF::equal;
843 using WTF::equalNonNull; 865 using WTF::equalNonNull;
844 using WTF::lengthOfNullTerminatedString; 866 using WTF::lengthOfNullTerminatedString;
845 using WTF::reverseFind; 867 using WTF::reverseFind;
846 868
847 #endif 869 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/text/ASCIIFastPath.h ('k') | third_party/WebKit/Source/wtf/text/StringImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698