Changeset 154780 in webkit
- Timestamp:
- Aug 28, 2013 3:29:13 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r154779 r154780 1 2013-08-27 Benjamin Poulain <bpoulain@apple.com> 2 3 Simplify and clean SpaceSplitString 4 https://bugs.webkit.org/show_bug.cgi?id=120385 5 6 Reviewed by Ryosuke Niwa. 7 8 Clean up of SpaceSplitString following the cleaning of the DOMTokenList hierarchy. 9 This brings the following: 10 - Fix the coding style of the header. 11 - Remove the concepts of empty and null. The list can now be empty or have something. 12 There is no null state. 13 - Put the tokens directly following SpaceSplitStringData instead of using a Vector in between. 14 15 * WebCore.exp.in: 16 * dom/ElementData.h: 17 (WebCore::ElementData::hasClass): 18 * dom/SpaceSplitString.cpp: 19 (WebCore::tokenizeSpaceSplitString): 20 (WebCore::SpaceSplitStringData::containsAll): 21 (WebCore::SpaceSplitString::set): 22 (WebCore::SpaceSplitString::spaceSplitStringContainsValue): 23 (WebCore::TokenCounterProcessor::TokenCounterProcessor): 24 (WebCore::TokenCounterProcessor::processToken): 25 (WebCore::TokenCounterProcessor::tokenCount): 26 (WebCore::TokenInitializerProcessor::TokenInitializerProcessor): 27 (WebCore::TokenInitializerProcessor::processToken): 28 (WebCore::TokenInitializerProcessor::nextMemoryBucket): 29 (WebCore::SpaceSplitStringData::create): 30 (WebCore::SpaceSplitStringData::destroy): 31 * dom/SpaceSplitString.h: 32 (WebCore::SpaceSplitStringData::contains): 33 (WebCore::SpaceSplitStringData::size): 34 (WebCore::SpaceSplitStringData::operator[]): 35 (WebCore::SpaceSplitStringData::ref): 36 (WebCore::SpaceSplitStringData::deref): 37 (WebCore::SpaceSplitStringData::SpaceSplitStringData): 38 (WebCore::SpaceSplitStringData::~SpaceSplitStringData): 39 (WebCore::SpaceSplitStringData::tokenArrayStart): 40 (WebCore::SpaceSplitString::SpaceSplitString): 41 (WebCore::SpaceSplitString::operator!=): 42 (WebCore::SpaceSplitString::clear): 43 (WebCore::SpaceSplitString::contains): 44 (WebCore::SpaceSplitString::containsAll): 45 (WebCore::SpaceSplitString::size): 46 (WebCore::SpaceSplitString::isEmpty): 47 (WebCore::SpaceSplitString::operator[]): 48 (WebCore::SpaceSplitString::spaceSplitStringContainsValue): 49 * html/ClassList.cpp: 50 (WebCore::ClassList::classNames): 51 * page/EventHandler.cpp: 52 (WebCore::findDropZone): 53 54 <<<<<<< .mine 55 2013-08-28 Benjamin Poulain <benjamin@webkit.org> 56 57 Simplify and clean SpaceSplitString 58 https://bugs.webkit.org/show_bug.cgi?id=120385 59 60 Reviewed by Ryosuke Niwa. 61 62 Clean up of SpaceSplitString following the cleaning of the DOMTokenList hierarchy. 63 - Remove the concepts of empty and null. The list can now be empty or have something. 64 There is no null state. 65 - Put the tokens directly following SpaceSplitStringData instead of using a Vector in between. 66 67 * WebCore.exp.in: 68 * dom/ElementData.h: 69 (WebCore::ElementData::hasClass): 70 * dom/SpaceSplitString.cpp: 71 (WebCore::tokenizeSpaceSplitString): 72 (WebCore::SpaceSplitStringData::containsAll): 73 (WebCore::SpaceSplitString::set): 74 (WebCore::SpaceSplitString::spaceSplitStringContainsValue): 75 (WebCore::TokenCounter::TokenCounter): 76 (WebCore::TokenCounter::processToken): 77 (WebCore::TokenCounter::tokenCount): 78 (WebCore::TokenAtomicStringInitializer::TokenAtomicStringInitializer): 79 (WebCore::TokenAtomicStringInitializer::processToken): 80 (WebCore::TokenAtomicStringInitializer::nextMemoryBucket): 81 (WebCore::SpaceSplitStringData::create): 82 (WebCore::SpaceSplitStringData::destroy): 83 * dom/SpaceSplitString.h: 84 (WebCore::SpaceSplitStringData::contains): 85 (WebCore::SpaceSplitStringData::size): 86 (WebCore::SpaceSplitStringData::operator[]): 87 (WebCore::SpaceSplitStringData::ref): 88 (WebCore::SpaceSplitStringData::deref): 89 (WebCore::SpaceSplitStringData::SpaceSplitStringData): 90 (WebCore::SpaceSplitStringData::~SpaceSplitStringData): 91 (WebCore::SpaceSplitStringData::tokenArrayStart): 92 (WebCore::SpaceSplitString::containsAll): 93 (WebCore::SpaceSplitString::isEmpty): 94 (WebCore::SpaceSplitString::operator[]): 95 * html/ClassList.cpp: 96 (WebCore::ClassList::classNames): 97 * page/EventHandler.cpp: 98 (WebCore::findDropZone): 99 100 ======= 1 101 2013-08-28 Rob Buis <rwlbuis@webkit.org> 2 102 … … 81 181 (WebCore::AXSearchFieldCancelButtonText): 82 182 183 >>>>>>> .r154779 83 184 2013-08-28 Eric Carlson <eric.carlson@apple.com> 84 185 -
trunk/Source/WebCore/WebCore.exp.in
r154761 r154780 690 690 __ZN7WebCore20ResourceResponseBaseC2Ev 691 691 __ZN7WebCore20ResourceResponseBaseC2ERKNS_4KURLERKN3WTF6StringExS7_S7_ 692 __ZN7WebCore20SpaceSplitStringDataD1Ev693 692 __ZN7WebCore20UserGestureIndicator7s_stateE 694 693 __ZN7WebCore20UserGestureIndicatorC1ENS_26ProcessingUserGestureStateE -
trunk/Source/WebCore/dom/ElementData.h
r154249 r154780 67 67 68 68 bool hasID() const { return !m_idForStyleResolution.isNull(); } 69 bool hasClass() const { return !m_classNames.is Null(); }69 bool hasClass() const { return !m_classNames.isEmpty(); } 70 70 bool hasName() const { return m_hasNameAttribute; } 71 71 -
trunk/Source/WebCore/dom/SpaceSplitString.cpp
r153685 r154780 28 28 #include <wtf/text/StringBuilder.h> 29 29 30 using namespace WTF;31 32 30 namespace WebCore { 31 32 COMPILE_ASSERT(!(sizeof(SpaceSplitStringData) % sizeof(uintptr_t)), SpaceSplitStringDataTailIsAlignedToWordSize); 33 33 34 34 template <typename CharacterType> … … 74 74 } 75 75 76 class AppendTokenToVectorTokenProcessor { 77 public: 78 AppendTokenToVectorTokenProcessor(Vector<AtomicString, 4>& vector) : m_vector(vector) { } 79 80 template <typename CharacterType> 81 bool processToken(const CharacterType* characters, unsigned length) 82 { 83 m_vector.append(AtomicString(characters, length)); 84 return true; 85 } 86 private: 87 Vector<AtomicString, 4>& m_vector; 88 }; 89 90 void SpaceSplitStringData::createVector(const String& string) 91 { 92 unsigned length = string.length(); 93 94 AppendTokenToVectorTokenProcessor tokenProcessor(m_vector); 95 if (string.is8Bit()) { 96 tokenizeSpaceSplitString(tokenProcessor, string.characters8(), length); 97 return; 98 } 99 100 tokenizeSpaceSplitString(tokenProcessor, string.characters16(), length); 76 template<typename TokenProcessor> 77 static inline void tokenizeSpaceSplitString(TokenProcessor& tokenProcessor, const String& string) 78 { 79 ASSERT(!string.isNull()); 80 81 const StringImpl* stringImpl = string.impl(); 82 if (stringImpl->is8Bit()) 83 tokenizeSpaceSplitString(tokenProcessor, stringImpl->characters8(), stringImpl->length()); 84 else 85 tokenizeSpaceSplitString(tokenProcessor, stringImpl->characters16(), stringImpl->length()); 101 86 } 102 87 … … 106 91 return true; 107 92 108 size_t thisSize = m_vector.size(); 109 size_t otherSize = other.m_vector.size(); 110 for (size_t i = 0; i < otherSize; ++i) { 111 const AtomicString& name = other.m_vector[i]; 112 size_t j; 113 for (j = 0; j < thisSize; ++j) { 114 if (m_vector[j] == name) 115 break; 116 } 117 if (j == thisSize) 93 unsigned otherSize = other.m_size; 94 unsigned i = 0; 95 do { 96 if (!contains(other[i])) 118 97 return false; 119 } 98 ++i; 99 } while (i < otherSize); 120 100 return true; 121 101 } 122 102 123 void SpaceSplitStringData::add(const AtomicString& string) 124 { 125 ASSERT(hasOneRef()); 126 ASSERT(!contains(string)); 127 m_vector.append(string); 128 } 129 130 void SpaceSplitStringData::remove(unsigned index) 131 { 132 ASSERT(hasOneRef()); 133 m_vector.remove(index); 134 } 135 136 void SpaceSplitString::add(const AtomicString& string) 137 { 138 // FIXME: add() does not allow duplicates but createVector() does. 139 if (contains(string)) 140 return; 141 ensureUnique(); 142 if (m_data) 143 m_data->add(string); 144 } 145 146 bool SpaceSplitString::remove(const AtomicString& string) 147 { 148 if (!m_data) 149 return false; 150 unsigned i = 0; 151 bool changed = false; 152 while (i < m_data->size()) { 153 if ((*m_data)[i] == string) { 154 if (!changed) 155 ensureUnique(); 156 m_data->remove(i); 157 changed = true; 158 continue; 159 } 160 ++i; 161 } 162 return changed; 163 } 164 165 typedef HashMap<AtomicString, SpaceSplitStringData*> SpaceSplitStringDataMap; 103 struct SpaceSplitStringDataMapKeyTrait : public HashTraits<AtomicString> 104 { 105 // The number 200 for typicalNumberOfSpaceSplitString was based on the typical number of unique class names 106 // on typical websites on August 2013. 107 static const unsigned typicalNumberOfSpaceSplitString = 200; 108 static const int minimumTableSize = WTF::HashTableCapacityForSize<typicalNumberOfSpaceSplitString>::value; 109 }; 110 111 typedef HashMap<AtomicString, SpaceSplitStringData*, DefaultHash<AtomicString>::Hash, SpaceSplitStringDataMapKeyTrait> SpaceSplitStringDataMap; 166 112 167 113 static SpaceSplitStringDataMap& sharedDataMap() … … 178 124 } 179 125 180 String string(inputString.string());126 AtomicString string(inputString); 181 127 if (shouldFoldCase && hasNonASCIIOrUpper(string)) 182 string = string. foldCase();128 string = string.string().foldCase(); 183 129 184 130 m_data = SpaceSplitStringData::create(string); … … 222 168 223 169 TokenIsEqualToCStringTokenProcessor tokenProcessor(value, valueLength); 224 unsigned length = string.length(); 225 if (string.is8Bit()) 226 tokenizeSpaceSplitString(tokenProcessor, string.characters8(), length); 227 else 228 tokenizeSpaceSplitString(tokenProcessor, string.characters16(), length); 170 tokenizeSpaceSplitString(tokenProcessor, string); 229 171 return tokenProcessor.referenceStringWasFound(); 230 172 } 231 173 232 SpaceSplitStringData::~SpaceSplitStringData() 233 { 234 if (!m_keyString.isNull()) 235 sharedDataMap().remove(m_keyString); 236 } 237 238 PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& string) 239 { 240 SpaceSplitStringData*& data = sharedDataMap().add(string, 0).iterator->value; 241 if (!data) { 242 data = new SpaceSplitStringData(string); 243 return adoptRef(data); 244 } 245 return data; 246 } 247 248 PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::createUnique(const SpaceSplitStringData& other) 249 { 250 return adoptRef(new SpaceSplitStringData(other)); 251 } 252 253 SpaceSplitStringData::SpaceSplitStringData(const AtomicString& string) 254 : m_keyString(string) 255 { 256 ASSERT(!string.isNull()); 257 createVector(string); 258 } 259 260 SpaceSplitStringData::SpaceSplitStringData(const SpaceSplitStringData& other) 261 : RefCounted<SpaceSplitStringData>() 262 , m_vector(other.m_vector) 263 { 264 // Note that we don't copy m_keyString to indicate to the destructor that there's nothing 265 // to be removed from the sharedDataMap(). 174 class TokenCounter { 175 WTF_MAKE_NONCOPYABLE(TokenCounter); 176 public: 177 TokenCounter() : m_tokenCount(0) { } 178 179 template <typename CharacterType> 180 bool processToken(const CharacterType*, unsigned) 181 { 182 ++m_tokenCount; 183 return true; 184 } 185 186 unsigned tokenCount() const { return m_tokenCount; } 187 188 private: 189 unsigned m_tokenCount; 190 }; 191 192 class TokenAtomicStringInitializer { 193 WTF_MAKE_NONCOPYABLE(TokenAtomicStringInitializer); 194 public: 195 TokenAtomicStringInitializer(AtomicString* memory) : m_memoryBucket(memory) { } 196 197 template <typename CharacterType> 198 bool processToken(const CharacterType* characters, unsigned length) 199 { 200 new (NotNull, m_memoryBucket) AtomicString(characters, length); 201 ++m_memoryBucket; 202 return true; 203 } 204 205 const AtomicString* nextMemoryBucket() const { return m_memoryBucket; } 206 private: 207 AtomicString* m_memoryBucket; 208 }; 209 210 PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& keyString, unsigned tokenCount) 211 { 212 ASSERT(tokenCount); 213 214 RELEASE_ASSERT(tokenCount < (std::numeric_limits<unsigned>::max() - sizeof(SpaceSplitStringData)) / sizeof(AtomicString)); 215 unsigned sizeToAllocate = sizeof(SpaceSplitStringData) + tokenCount * sizeof(AtomicString); 216 SpaceSplitStringData* spaceSplitStringData = static_cast<SpaceSplitStringData*>(fastMalloc(sizeToAllocate)); 217 218 new (NotNull, spaceSplitStringData) SpaceSplitStringData(keyString, tokenCount); 219 AtomicString* tokenArrayStart = spaceSplitStringData->tokenArrayStart(); 220 TokenAtomicStringInitializer tokenInitializer(tokenArrayStart); 221 tokenizeSpaceSplitString(tokenInitializer, keyString); 222 ASSERT(tokenInitializer.nextMemoryBucket() - tokenArrayStart == tokenCount); 223 ASSERT(reinterpret_cast<const char*>(tokenInitializer.nextMemoryBucket()) == reinterpret_cast<const char*>(spaceSplitStringData) + sizeToAllocate); 224 225 return adoptRef(spaceSplitStringData); 226 } 227 228 PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& keyString) 229 { 230 ASSERT(isMainThread()); 231 ASSERT(!keyString.isNull()); 232 233 SpaceSplitStringDataMap& spaceSplitStringDataCache = sharedDataMap(); 234 SpaceSplitStringDataMap::iterator iterator = spaceSplitStringDataCache.find(keyString); 235 if (iterator != spaceSplitStringDataCache.end()) 236 return iterator->value; 237 238 // Nothing in the cache? Let's create a new SpaceSplitStringData if the input has something useful. 239 // 1) We find the number of strings in the input to know how much size we need to allocate. 240 TokenCounter tokenCounter; 241 tokenizeSpaceSplitString(tokenCounter, keyString); 242 unsigned tokenCount = tokenCounter.tokenCount(); 243 244 if (!tokenCount) 245 return nullptr; 246 247 RefPtr<SpaceSplitStringData> spaceSplitStringData = create(keyString, tokenCount); 248 spaceSplitStringDataCache.add(keyString, spaceSplitStringData.get()); 249 return spaceSplitStringData.release(); 250 } 251 252 253 void SpaceSplitStringData::destroy(SpaceSplitStringData* spaceSplitString) 254 { 255 ASSERT(isMainThread()); 256 257 if (!spaceSplitString->m_keyString.isNull()) 258 sharedDataMap().remove(spaceSplitString->m_keyString); 259 260 unsigned i = 0; 261 unsigned size = spaceSplitString->size(); 262 const AtomicString* data = spaceSplitString->tokenArrayStart(); 263 do { 264 data[i].~AtomicString(); 265 ++i; 266 } while (i < size); 267 268 spaceSplitString->~SpaceSplitStringData(); 269 270 fastFree(spaceSplitString); 266 271 } 267 272 -
trunk/Source/WebCore/dom/SpaceSplitString.h
r154719 r154780 1 1 /* 2 * Copyright (C) 2007, 2008, 2010, 2011, 2012 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 22 22 #define SpaceSplitString_h 23 23 24 #include <wtf/RefCounted.h> 25 #include <wtf/Vector.h> 24 #include <wtf/Assertions.h> 25 #include <wtf/MainThread.h> 26 #include <wtf/Noncopyable.h> 26 27 #include <wtf/text/AtomicString.h> 27 28 28 29 namespace WebCore { 29 30 30 class SpaceSplitStringData : public RefCounted<SpaceSplitStringData> { 31 class SpaceSplitStringData { 32 WTF_MAKE_NONCOPYABLE(SpaceSplitStringData); 33 WTF_MAKE_FAST_ALLOCATED; 31 34 public: 32 35 static PassRefPtr<SpaceSplitStringData> create(const AtomicString&); 33 static PassRefPtr<SpaceSplitStringData> createUnique(const SpaceSplitStringData&);34 35 ~SpaceSplitStringData();36 36 37 37 bool contains(const AtomicString& string) 38 38 { 39 size_t size = m_vector.size(); 40 for (size_t i = 0; i < size; ++i) { 41 if (m_vector[i] == string) 39 const AtomicString* data = tokenArrayStart(); 40 unsigned i = 0; 41 do { 42 if (data[i] == string) 42 43 return true; 43 } 44 ++i; 45 } while (i < m_size); 44 46 return false; 45 47 } … … 47 49 bool containsAll(SpaceSplitStringData&); 48 50 49 void add(const AtomicString&); 50 void remove(unsigned index); 51 unsigned size() const { return m_size; } 52 const AtomicString& operator[](size_t i) 53 { 54 RELEASE_ASSERT(i < m_size); 55 return tokenArrayStart()[i]; 56 } 51 57 52 bool isUnique() const { return m_keyString.isNull(); } 53 size_t size() const { return m_vector.size(); } 54 const AtomicString& operator[](size_t i) { ASSERT_WITH_SECURITY_IMPLICATION(i < size()); return m_vector[i]; } 58 inline void ref() 59 { 60 ASSERT(isMainThread()); 61 ASSERT(m_refCount); 62 ++m_refCount; 63 } 64 65 inline void deref() 66 { 67 ASSERT(isMainThread()); 68 ASSERT(m_refCount); 69 unsigned tempRefCount = m_refCount - 1; 70 if (!tempRefCount) { 71 SpaceSplitStringData::destroy(this); 72 return; 73 } 74 m_refCount = tempRefCount; 75 } 55 76 56 77 private: 57 explicit SpaceSplitStringData(const AtomicString&); 58 explicit SpaceSplitStringData(const SpaceSplitStringData&); 78 static PassRefPtr<SpaceSplitStringData> create(const AtomicString&, unsigned tokenCount); 79 SpaceSplitStringData(const AtomicString& string, unsigned size) 80 : m_keyString(string) 81 , m_refCount(1) 82 , m_size(size) 83 { 84 ASSERT(!string.isEmpty()); 85 ASSERT_WITH_MESSAGE(m_size, "SpaceSplitStringData should never be empty by definition. There is no difference between empty and null."); 86 } 59 87 60 void createVector(const String&); 61 template <typename CharacterType> 62 inline void createVector(const CharacterType*, unsigned); 88 inline ~SpaceSplitStringData() { } 89 static void destroy(SpaceSplitStringData*); 90 91 AtomicString* tokenArrayStart() { return reinterpret_cast<AtomicString*>(this + 1); } 63 92 64 93 AtomicString m_keyString; 65 Vector<AtomicString, 4> m_vector; 94 unsigned m_refCount; 95 unsigned m_size; 66 96 }; 67 97 … … 78 108 bool contains(const AtomicString& string) const { return m_data && m_data->contains(string); } 79 109 bool containsAll(const SpaceSplitString& names) const { return !names.m_data || (m_data && m_data->containsAll(*names.m_data)); } 80 void add(const AtomicString&);81 bool remove(const AtomicString&);82 110 83 111 size_t size() const { return m_data ? m_data->size() : 0; } 84 bool isNull() const { return !m_data; } 85 const AtomicString& operator[](size_t i) const { ASSERT_WITH_SECURITY_IMPLICATION(i < size()); return (*m_data)[i]; } 112 bool isEmpty() const { return !m_data; } 113 const AtomicString& operator[](size_t i) const 114 { 115 ASSERT_WITH_SECURITY_IMPLICATION(m_data); 116 return (*m_data)[i]; 117 } 86 118 87 119 static bool spaceSplitStringContainsValue(const String& spaceSplitString, const char* value, unsigned length, bool shouldFoldCase); … … 93 125 94 126 private: 95 void ensureUnique()96 {97 if (m_data && !m_data->isUnique())98 m_data = SpaceSplitStringData::createUnique(*m_data);99 }100 127 101 128 RefPtr<SpaceSplitStringData> m_data; -
trunk/Source/WebCore/html/ClassList.cpp
r154707 r154780 84 84 ASSERT(m_element->hasClass()); 85 85 if (m_element->document()->inQuirksMode()) { 86 if ( !m_classNamesForQuirksMode.size())86 if (m_classNamesForQuirksMode.isEmpty()) 87 87 m_classNamesForQuirksMode.set(value(), false); 88 88 return m_classNamesForQuirksMode; -
trunk/Source/WebCore/page/EventHandler.cpp
r154678 r154780 2075 2075 2076 2076 SpaceSplitString keywords(dropZoneStr, false); 2077 if (keywords.is Null())2077 if (keywords.isEmpty()) 2078 2078 continue; 2079 2079
Note: See TracChangeset
for help on using the changeset viewer.