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

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

Issue 2585063002: Cache contains only ascii in StringImpl (Closed)
Patch Set: cache contains only ascci Created 4 years 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
« no previous file with comments | « no previous file | third_party/WebKit/Source/wtf/text/WTFString.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/wtf/text/WTFString.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698