Changeset 58712 in webkit
- Timestamp:
- May 3, 2010, 4:03:37 PM (15 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 deleted
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r58709 r58712 1 2010-05-03 Gavin Barraclough <[email protected]> 2 3 Reviewed by NOBODY (reverting previous commit). 4 5 Rolling out r58114 - this introduced memory leaks of 6 AtomicStrings then workers terminated. 7 8 * GNUmakefile.am: 9 * JavaScriptCore.gypi: 10 * JavaScriptCore.vcproj/WTF/WTF.vcproj: 11 * JavaScriptCore.xcodeproj/project.pbxproj: 12 * jit/ThunkGenerators.cpp: 13 (JSC::ThunkHelpers::stringImplDataOffset): 14 * runtime/Identifier.cpp: 15 (JSC::IdentifierTable::~IdentifierTable): 16 (JSC::IdentifierTable::add): 17 (JSC::IdentifierCStringTranslator::hash): 18 (JSC::IdentifierCStringTranslator::equal): 19 (JSC::IdentifierCStringTranslator::translate): 20 (JSC::Identifier::add): 21 (JSC::IdentifierUCharBufferTranslator::hash): 22 (JSC::IdentifierUCharBufferTranslator::equal): 23 (JSC::IdentifierUCharBufferTranslator::translate): 24 (JSC::Identifier::addSlowCase): 25 * runtime/Identifier.h: 26 * runtime/JSGlobalData.cpp: 27 (JSC::JSGlobalData::JSGlobalData): 28 (JSC::JSGlobalData::~JSGlobalData): 29 * runtime/JSGlobalData.h: 30 * wtf/WTFThreadData.cpp: 31 (WTF::WTFThreadData::WTFThreadData): 32 (WTF::WTFThreadData::~WTFThreadData): 33 * wtf/WTFThreadData.h: 34 (JSC::IdentifierTable::remove): 35 (JSC::IdentifierTable::literalTable): 36 (WTF::WTFThreadData::atomicStringTable): 37 * wtf/text/AtomicString.cpp: 38 (WebCore::AtomicStringTable::create): 39 (WebCore::AtomicStringTable::table): 40 (WebCore::AtomicStringTable::destroy): 41 (WebCore::stringTable): 42 (WebCore::CStringTranslator::hash): 43 (WebCore::CStringTranslator::equal): 44 (WebCore::CStringTranslator::translate): 45 (WebCore::operator==): 46 (WebCore::AtomicString::add): 47 (WebCore::equal): 48 (WebCore::UCharBufferTranslator::hash): 49 (WebCore::UCharBufferTranslator::equal): 50 (WebCore::UCharBufferTranslator::translate): 51 (WebCore::HashAndCharactersTranslator::hash): 52 (WebCore::HashAndCharactersTranslator::equal): 53 (WebCore::HashAndCharactersTranslator::translate): 54 (WebCore::AtomicString::find): 55 (WebCore::AtomicString::remove): 56 * wtf/text/AtomicStringTable.h: Removed. 57 * wtf/text/StringImpl.cpp: 58 (WebCore::StringImpl::~StringImpl): 59 * wtf/text/StringImpl.h: 60 (WebCore::StringImpl::inTable): 61 (WebCore::StringImpl::setInTable): 62 (WebCore::equal): 63 * wtf/text/StringImplBase.h: 64 (WTF::StringImplBase::StringImplBase): 65 1 66 2010-05-03 Kevin Watters <[email protected]> 2 67 -
trunk/JavaScriptCore/GNUmakefile.am
r58537 r58712 311 311 JavaScriptCore/wtf/text/AtomicString.h \ 312 312 JavaScriptCore/wtf/text/AtomicStringImpl.h \ 313 JavaScriptCore/wtf/text/AtomicStringTable.h \314 313 JavaScriptCore/wtf/text/CString.cpp \ 315 314 JavaScriptCore/wtf/text/CString.h \ -
trunk/JavaScriptCore/JavaScriptCore.gypi
r58537 r58712 428 428 'wtf/text/AtomicString.h', 429 429 'wtf/text/AtomicStringImpl.h', 430 'wtf/text/AtomicStringTable.h',431 430 'wtf/text/CString.cpp', 432 431 'wtf/text/CString.h', -
trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
r58206 r58712 569 569 > 570 570 </File> 571 <File572 RelativePath="..\..\wtf\text\AtomicStringTable.h"573 >574 </File>575 571 <File 576 572 RelativePath="..\..\wtf\text\CString.cpp" -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r58537 r58712 220 220 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 221 221 86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE2117E578100DF5A90 /* StringImplBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 222 86B99DA711800F8500DF5A90 /* AtomicStringTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99DA611800F8500DF5A90 /* AtomicStringTable.h */; settings = {ATTRIBUTES = (Private, ); }; };223 222 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; }; 224 223 86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; }; … … 773 772 86B99AE1117E578100DF5A90 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuffer.h; path = text/StringBuffer.h; sourceTree = "<group>"; }; 774 773 86B99AE2117E578100DF5A90 /* StringImplBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringImplBase.h; path = text/StringImplBase.h; sourceTree = "<group>"; }; 775 86B99DA611800F8500DF5A90 /* AtomicStringTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringTable.h; path = text/AtomicStringTable.h; sourceTree = "<group>"; };776 774 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; }; 777 775 86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; }; … … 1709 1707 868BFA01117CEFD100B908B1 /* AtomicString.h */, 1710 1708 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */, 1711 86B99DA611800F8500DF5A90 /* AtomicStringTable.h */,1712 1709 86565740115BE3DA00291F40 /* CString.cpp */, 1713 1710 86565741115BE3DA00291F40 /* CString.h */, … … 2123 2120 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */, 2124 2121 86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */, 2125 86B99DA711800F8500DF5A90 /* AtomicStringTable.h in Headers */,2126 2122 511FC4CB117EE2A800425272 /* MD5.h in Headers */, 2127 2123 BC5F7BBE11823B590052C02C /* Atomics.h in Headers */, -
trunk/JavaScriptCore/jit/ThunkGenerators.cpp
r58475 r58712 26 26 #include "config.h" 27 27 #include "ThunkGenerators.h" 28 #include <wtf/text/StringImpl.h> 28 29 29 30 #include "SpecializedThunkJIT.h" … … 34 35 35 36 struct ThunkHelpers { 36 static unsigned stringImplDataOffset() { return StringImpl::dataOffset(); }37 static unsigned stringImplDataOffset() { return WebCore::StringImpl::dataOffset(); } 37 38 static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); } 38 39 static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); } -
trunk/JavaScriptCore/runtime/Identifier.cpp
r58114 r58712 30 30 #include <wtf/HashSet.h> 31 31 #include <wtf/WTFThreadData.h> 32 #include <wtf/text/AtomicStringTable.h>33 32 #include <wtf/text/StringHash.h> 34 33 … … 37 36 namespace JSC { 38 37 39 class LiteralTable : public HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > {}; 40 41 LiteralTable* createLiteralTable() 42 { 43 return new LiteralTable; 44 } 45 46 void deleteLiteralTable(LiteralTable* table) 47 { 48 delete table; 38 IdentifierTable::~IdentifierTable() 39 { 40 HashSet<StringImpl*>::iterator end = m_table.end(); 41 for (HashSet<StringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter) 42 (*iter)->setIsIdentifier(false); 43 } 44 std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value) 45 { 46 std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value); 47 (*result.first)->setIsIdentifier(true); 48 return result; 49 } 50 template<typename U, typename V> 51 std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(U value) 52 { 53 std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add<U, V>(value); 54 (*result.first)->setIsIdentifier(true); 55 return result; 49 56 } 50 57 … … 80 87 } 81 88 89 struct IdentifierCStringTranslator { 90 static unsigned hash(const char* c) 91 { 92 return UString::Rep::computeHash(c); 93 } 94 95 static bool equal(UString::Rep* r, const char* s) 96 { 97 return Identifier::equal(r, s); 98 } 99 100 static void translate(UString::Rep*& location, const char* c, unsigned hash) 101 { 102 size_t length = strlen(c); 103 UChar* d; 104 UString::Rep* r = UString::Rep::createUninitialized(length, d).releaseRef(); 105 for (size_t i = 0; i != length; i++) 106 d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend 107 r->setHash(hash); 108 location = r; 109 } 110 }; 111 82 112 PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c) 83 113 { … … 89 119 return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0]))); 90 120 91 LiteralTable* literalTable = globalData->literalTable; 92 pair<LiteralTable::iterator, bool> result = literalTable->add(c, 0); 93 if (!result.second) // pre-existing entry 94 return result.first->second; 95 96 RefPtr<StringImpl> addedString = globalData->identifierTable->add(c); 97 result.first->second = addedString.get(); 121 IdentifierTable& identifierTable = *globalData->identifierTable; 122 LiteralIdentifierTable& literalIdentifierTable = identifierTable.literalTable(); 123 124 const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c); 125 if (iter != literalIdentifierTable.end()) 126 return iter->second; 127 128 pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, IdentifierCStringTranslator>(c); 129 130 // If the string is newly-translated, then we need to adopt it. 131 // The boolean in the pair tells us if that is so. 132 RefPtr<UString::Rep> addedString = addResult.second ? adoptRef(*addResult.first) : *addResult.first; 133 134 literalIdentifierTable.add(c, addedString.get()); 98 135 99 136 return addedString.release(); … … 104 141 return add(&exec->globalData(), c); 105 142 } 143 144 struct UCharBuffer { 145 const UChar* s; 146 unsigned int length; 147 }; 148 149 struct IdentifierUCharBufferTranslator { 150 static unsigned hash(const UCharBuffer& buf) 151 { 152 return UString::Rep::computeHash(buf.s, buf.length); 153 } 154 155 static bool equal(UString::Rep* str, const UCharBuffer& buf) 156 { 157 return Identifier::equal(str, buf.s, buf.length); 158 } 159 160 static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash) 161 { 162 UChar* d; 163 UString::Rep* r = UString::Rep::createUninitialized(buf.length, d).releaseRef(); 164 for (unsigned i = 0; i != buf.length; i++) 165 d[i] = buf.s[i]; 166 r->setHash(hash); 167 location = r; 168 } 169 }; 106 170 107 171 PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar* s, int length) … … 114 178 if (!length) 115 179 return UString::Rep::empty(); 116 117 return globalData->identifierTable->add(s, length); 180 UCharBuffer buf = {s, length}; 181 pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf); 182 183 // If the string is newly-translated, then we need to adopt it. 184 // The boolean in the pair tells us if that is so. 185 return addResult.second ? adoptRef(*addResult.first) : *addResult.first; 118 186 } 119 187 … … 138 206 } 139 207 140 return globalData->identifierTable->add(r);208 return *globalData->identifierTable->add(r).first; 141 209 } 142 210 -
trunk/JavaScriptCore/runtime/Identifier.h
r58114 r58712 138 138 IdentifierTable* createIdentifierTable(); 139 139 void deleteIdentifierTable(IdentifierTable*); 140 LiteralTable* createLiteralTable();141 void deleteLiteralTable(LiteralTable*);142 140 143 141 } // namespace JSC -
trunk/JavaScriptCore/runtime/JSGlobalData.cpp
r58133 r58712 130 130 #endif 131 131 , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable()) 132 , literalTable(createLiteralTable())133 132 , propertyNames(new CommonIdentifiers(this)) 134 133 , emptyList(new MarkedArgumentBuffer) … … 196 195 if (globalDataType != Default) 197 196 deleteIdentifierTable(identifierTable); 198 deleteLiteralTable(literalTable);199 197 200 198 delete clientData; -
trunk/JavaScriptCore/runtime/JSGlobalData.h
r58286 r58712 57 57 class JSObject; 58 58 class Lexer; 59 class LiteralTable;60 59 class Parser; 61 60 class Stringifier; … … 156 155 157 156 IdentifierTable* identifierTable; 158 LiteralTable* literalTable;159 157 CommonIdentifiers* propertyNames; 160 158 const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark. -
trunk/JavaScriptCore/wtf/WTFThreadData.cpp
r58133 r58712 27 27 #include "config.h" 28 28 #include "WTFThreadData.h" 29 #include <wtf/text/AtomicStringTable.h>30 29 31 30 namespace WTF { … … 38 37 39 38 WTFThreadData::WTFThreadData() 40 : m_atomicStringTable(new WebCore::AtomicStringTable()) 39 : m_atomicStringTable(0) 40 , m_atomicStringTableDestructor(0) 41 41 #if USE(JSC) 42 42 , m_defaultIdentifierTable(new JSC::IdentifierTable()) … … 48 48 WTFThreadData::~WTFThreadData() 49 49 { 50 delete m_atomicStringTable; 50 if (m_atomicStringTableDestructor) 51 m_atomicStringTableDestructor(m_atomicStringTable); 51 52 #if USE(JSC) 52 53 delete m_defaultIdentifierTable; -
trunk/JavaScriptCore/wtf/WTFThreadData.h
r58114 r58712 28 28 #define WTFThreadData_h 29 29 30 #include <wtf/HashMap.h> 31 #include <wtf/HashSet.h> 30 32 #include <wtf/Noncopyable.h> 33 #include <wtf/text/StringHash.h> 31 34 32 35 // This was ENABLE(WORKERS) in WebCore, but this is not defined when compiling JSC. … … 44 47 45 48 // FIXME: This is a temporary layering violation while we move more string code to WTF. 46 namespace JSC {47 class IdentifierTable;48 }49 50 // FIXME: This is a temporary layering violation while we move more string code to WTF.51 49 namespace WebCore { 52 50 class AtomicStringTable; 51 class StringImpl; 53 52 } 53 using WebCore::StringImpl; 54 55 typedef void (*AtomicStringTableDestructor)(WebCore::AtomicStringTable*); 56 57 #if USE(JSC) 58 // FIXME: This is a temporary layering violation while we move more string code to WTF. 59 namespace JSC { 60 61 typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable; 62 63 class IdentifierTable : public FastAllocBase { 64 public: 65 ~IdentifierTable(); 66 67 std::pair<HashSet<StringImpl*>::iterator, bool> add(StringImpl* value); 68 template<typename U, typename V> 69 std::pair<HashSet<StringImpl*>::iterator, bool> add(U value); 70 71 void remove(StringImpl* r) { m_table.remove(r); } 72 73 LiteralIdentifierTable& literalTable() { return m_literalTable; } 74 75 private: 76 HashSet<StringImpl*> m_table; 77 LiteralIdentifierTable m_literalTable; 78 }; 79 80 } 81 #endif 54 82 55 83 namespace WTF { … … 60 88 ~WTFThreadData(); 61 89 62 WebCore::AtomicStringTable &atomicStringTable()90 WebCore::AtomicStringTable* atomicStringTable() 63 91 { 64 return *m_atomicStringTable;92 return m_atomicStringTable; 65 93 } 66 94 … … 92 120 private: 93 121 WebCore::AtomicStringTable* m_atomicStringTable; 122 AtomicStringTableDestructor m_atomicStringTableDestructor; 94 123 95 124 #if USE(JSC) … … 104 133 #endif 105 134 friend WTFThreadData& wtfThreadData(); 135 friend class WebCore::AtomicStringTable; 106 136 }; 107 137 -
trunk/JavaScriptCore/wtf/text/AtomicString.cpp
r58179 r58712 32 32 #include <wtf/Threading.h> 33 33 #include <wtf/WTFThreadData.h> 34 #include <wtf/text/AtomicStringTable.h>35 34 36 35 namespace WebCore { 37 36 38 static inline AtomicStringTable& table() 39 { 40 return wtfThreadData().atomicStringTable(); 41 } 37 class AtomicStringTable { 38 public: 39 static AtomicStringTable* create() 40 { 41 AtomicStringTable* table = new AtomicStringTable; 42 43 WTFThreadData& data = wtfThreadData(); 44 data.m_atomicStringTable = table; 45 data.m_atomicStringTableDestructor = AtomicStringTable::destroy; 46 47 return table; 48 } 49 50 HashSet<StringImpl*>& table() 51 { 52 return m_table; 53 } 54 55 private: 56 static void destroy(AtomicStringTable* table) 57 { 58 delete table; 59 } 60 61 HashSet<StringImpl*> m_table; 62 }; 63 64 static inline HashSet<StringImpl*>& stringTable() 65 { 66 // Once possible we should make this non-lazy (constructed in WTFThreadData's constructor). 67 AtomicStringTable* table = wtfThreadData().atomicStringTable(); 68 if (UNLIKELY(!table)) 69 table = AtomicStringTable::create(); 70 return table->table(); 71 } 72 73 struct CStringTranslator { 74 static unsigned hash(const char* c) 75 { 76 return StringImpl::computeHash(c); 77 } 78 79 static bool equal(StringImpl* r, const char* s) 80 { 81 int length = r->length(); 82 const UChar* d = r->characters(); 83 for (int i = 0; i != length; ++i) { 84 unsigned char c = s[i]; 85 if (d[i] != c) 86 return false; 87 } 88 return s[length] == 0; 89 } 90 91 static void translate(StringImpl*& location, const char* const& c, unsigned hash) 92 { 93 location = StringImpl::create(c).releaseRef(); 94 location->setHash(hash); 95 location->setInTable(); 96 } 97 }; 42 98 43 99 bool operator==(const AtomicString& a, const char* b) … … 48 104 if ((!impl || !impl->characters()) || !b) 49 105 return false; 50 return ::equal(impl, b);106 return CStringTranslator::equal(impl, b); 51 107 } 52 108 … … 56 112 return 0; 57 113 if (!*c) 58 return StringImpl::empty(); 59 return table().add(c); 60 } 114 return StringImpl::empty(); 115 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<const char*, CStringTranslator>(c); 116 if (!addResult.second) 117 return *addResult.first; 118 return adoptRef(*addResult.first); 119 } 120 121 struct UCharBuffer { 122 const UChar* s; 123 unsigned length; 124 }; 125 126 static inline bool equal(StringImpl* string, const UChar* characters, unsigned length) 127 { 128 if (string->length() != length) 129 return false; 130 131 // FIXME: perhaps we should have a more abstract macro that indicates when 132 // going 4 bytes at a time is unsafe 133 #if CPU(ARM) || CPU(SH4) 134 const UChar* stringCharacters = string->characters(); 135 for (unsigned i = 0; i != length; ++i) { 136 if (*stringCharacters++ != *characters++) 137 return false; 138 } 139 return true; 140 #else 141 /* Do it 4-bytes-at-a-time on architectures where it's safe */ 142 143 const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string->characters()); 144 const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(characters); 145 146 unsigned halfLength = length >> 1; 147 for (unsigned i = 0; i != halfLength; ++i) { 148 if (*stringCharacters++ != *bufferCharacters++) 149 return false; 150 } 151 152 if (length & 1 && *reinterpret_cast<const uint16_t*>(stringCharacters) != *reinterpret_cast<const uint16_t*>(bufferCharacters)) 153 return false; 154 155 return true; 156 #endif 157 } 158 159 struct UCharBufferTranslator { 160 static unsigned hash(const UCharBuffer& buf) 161 { 162 return StringImpl::computeHash(buf.s, buf.length); 163 } 164 165 static bool equal(StringImpl* const& str, const UCharBuffer& buf) 166 { 167 return WebCore::equal(str, buf.s, buf.length); 168 } 169 170 static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) 171 { 172 location = StringImpl::create(buf.s, buf.length).releaseRef(); 173 location->setHash(hash); 174 location->setInTable(); 175 } 176 }; 177 178 struct HashAndCharacters { 179 unsigned hash; 180 const UChar* characters; 181 unsigned length; 182 }; 183 184 struct HashAndCharactersTranslator { 185 static unsigned hash(const HashAndCharacters& buffer) 186 { 187 ASSERT(buffer.hash == StringImpl::computeHash(buffer.characters, buffer.length)); 188 return buffer.hash; 189 } 190 191 static bool equal(StringImpl* const& string, const HashAndCharacters& buffer) 192 { 193 return WebCore::equal(string, buffer.characters, buffer.length); 194 } 195 196 static void translate(StringImpl*& location, const HashAndCharacters& buffer, unsigned hash) 197 { 198 location = StringImpl::create(buffer.characters, buffer.length).releaseRef(); 199 location->setHash(hash); 200 location->setInTable(); 201 } 202 }; 61 203 62 204 PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length) … … 68 210 return StringImpl::empty(); 69 211 70 return table().add(s, length); 212 UCharBuffer buf = { s, length }; 213 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf); 214 215 // If the string is newly-translated, then we need to adopt it. 216 // The boolean in the pair tells us if that is so. 217 return addResult.second ? adoptRef(*addResult.first) : *addResult.first; 71 218 } 72 219 … … 78 225 if (length == 0) 79 226 return StringImpl::empty(); 80 81 return table().add(s, length, existingHash); 227 228 HashAndCharacters buffer = { existingHash, s, length }; 229 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndCharacters, HashAndCharactersTranslator>(buffer); 230 if (!addResult.second) 231 return *addResult.first; 232 return adoptRef(*addResult.first); 82 233 } 83 234 … … 87 238 return 0; 88 239 89 unsignedlength = 0;240 int length = 0; 90 241 while (s[length] != UChar(0)) 91 242 length++; … … 94 245 return StringImpl::empty(); 95 246 96 return table().add(s, length); 247 UCharBuffer buf = {s, length}; 248 pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf); 249 250 // If the string is newly-translated, then we need to adopt it. 251 // The boolean in the pair tells us if that is so. 252 return addResult.second ? adoptRef(*addResult.first) : *addResult.first; 97 253 } 98 254 99 255 PassRefPtr<StringImpl> AtomicString::add(StringImpl* r) 100 256 { 101 if (!r || r->i sAtomic())257 if (!r || r->inTable()) 102 258 return r; 103 259 104 // The singleton empty string is atomic.105 ASSERT(r->length());260 if (r->length() == 0) 261 return StringImpl::empty(); 106 262 107 return table().add(r); 263 StringImpl* result = *stringTable().add(r).first; 264 if (result == r) 265 r->setInTable(); 266 return result; 108 267 } 109 268 … … 115 274 if (length == 0) 116 275 return static_cast<AtomicStringImpl*>(StringImpl::empty()); 117 118 return static_cast<AtomicStringImpl*>(table().find(s, length, existingHash)); 276 277 HashAndCharacters buffer = { existingHash, s, length }; 278 HashSet<StringImpl*>::iterator iterator = stringTable().find<HashAndCharacters, HashAndCharactersTranslator>(buffer); 279 if (iterator == stringTable().end()) 280 return 0; 281 return static_cast<AtomicStringImpl*>(*iterator); 119 282 } 120 283 121 284 void AtomicString::remove(StringImpl* r) 122 285 { 123 table().remove(r);286 stringTable().remove(r); 124 287 } 125 288 -
trunk/JavaScriptCore/wtf/text/StringImpl.cpp
r58114 r58712 31 31 #include <wtf/StdLibExtras.h> 32 32 #include <wtf/WTFThreadData.h> 33 #include <wtf/text/AtomicStringTable.h>34 33 35 34 using namespace WTF; … … 44 43 ASSERT(!isStatic()); 45 44 46 if (i sAtomic())45 if (inTable()) 47 46 AtomicString::remove(this); 48 47 #if USE(JSC) -
trunk/JavaScriptCore/wtf/text/StringImpl.h
r58392 r58712 44 44 // FIXME: This is a temporary layering violation while we move string code to WTF. 45 45 // Landing the file moves in one patch, will follow on with patches to change the namespaces. 46 namespace WTF { 47 48 struct CStringTranslator; 49 struct UCharBufferTranslator; 50 struct HashAndCharactersTranslator; 46 namespace JSC { 47 48 struct IdentifierCStringTranslator; 49 struct IdentifierUCharBufferTranslator; 51 50 52 51 } … … 58 57 class StringBuffer; 59 58 59 struct CStringTranslator; 60 struct HashAndCharactersTranslator; 60 61 struct StringHash; 62 struct UCharBufferTranslator; 61 63 62 64 enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive }; … … 67 69 68 70 class StringImpl : public StringImplBase { 69 friend struct WTF::CStringTranslator; 70 friend struct WTF::UCharBufferTranslator; 71 friend struct WTF::HashAndCharactersTranslator; 71 friend struct JSC::IdentifierCStringTranslator; 72 friend struct JSC::IdentifierUCharBufferTranslator; 73 friend struct CStringTranslator; 74 friend struct HashAndCharactersTranslator; 75 friend struct UCharBufferTranslator; 72 76 friend class AtomicStringImpl; 73 77 private: … … 220 224 bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; } 221 225 222 bool isAtomic() const { return m_refCountAndFlags & s_refCountFlagIsAtomic; } 223 void setIsAtomic(bool inTable) 224 { 225 ASSERT(!isStatic()); 226 if (inTable) 227 m_refCountAndFlags |= s_refCountFlagIsAtomic; 228 else 229 m_refCountAndFlags &= s_refCountFlagIsAtomic; 230 } 226 bool inTable() const { return m_refCountAndFlags & s_refCountFlagInTable; } 227 void setInTable() { m_refCountAndFlags |= s_refCountFlagInTable; } 231 228 232 229 unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; } … … 336 333 bool equal(const StringImpl*, const char*); 337 334 inline bool equal(const char* a, StringImpl* b) { return equal(b, a); } 338 inline bool equal(StringImpl* string, const UChar* characters, unsigned length)339 {340 if (string->length() != length)341 return false;342 343 // FIXME: perhaps we should have a more abstract macro that indicates when344 // going 4 bytes at a time is unsafe345 #if CPU(ARM) || CPU(SH4)346 const UChar* stringCharacters = string->characters();347 for (unsigned i = 0; i != length; ++i) {348 if (*stringCharacters++ != *characters++)349 return false;350 }351 return true;352 #else353 /* Do it 4-bytes-at-a-time on architectures where it's safe */354 355 const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string->characters());356 const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(characters);357 358 unsigned halfLength = length >> 1;359 for (unsigned i = 0; i != halfLength; ++i) {360 if (*stringCharacters++ != *bufferCharacters++)361 return false;362 }363 364 if (length & 1 && *reinterpret_cast<const uint16_t*>(stringCharacters) != *reinterpret_cast<const uint16_t*>(bufferCharacters))365 return false;366 367 return true;368 #endif369 }370 335 371 336 bool equalIgnoringCase(StringImpl*, StringImpl*); … … 410 375 411 376 using WebCore::equal; 412 using WebCore::StringImpl;413 377 414 378 namespace WTF { -
trunk/JavaScriptCore/wtf/text/StringImplBase.h
r58114 r58712 61 61 enum StaticStringConstructType { ConstructStaticString }; 62 62 StringImplBase(unsigned length, StaticStringConstructType) 63 : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIs Atomic | s_refCountFlagIsIdentifier | BufferOwned)63 : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned) 64 64 , m_length(length) 65 65 { … … 84 84 static const unsigned s_refCountFlagStatic = 0x40; 85 85 static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x20; 86 static const unsigned s_refCountFlagI sAtomic= 0x10;86 static const unsigned s_refCountFlagInTable = 0x10; 87 87 static const unsigned s_refCountFlagShouldReportedCost = 0x8; 88 88 static const unsigned s_refCountFlagIsIdentifier = 0x4;
Note:
See TracChangeset
for help on using the changeset viewer.