Changeset 182915 in webkit
- Timestamp:
- Apr 16, 2015 3:46:35 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 17 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r182913 r182915 1 2015-04-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Implement Symbol.for and Symbol.keyFor 4 https://bugs.webkit.org/show_bug.cgi?id=143404 5 6 Reviewed by Geoffrey Garen. 7 8 Add tests to check Symbol's identity over different realms. 9 10 * js/dom/cross-frame-symbols-expected.txt: Added. 11 * js/dom/cross-frame-symbols.html: Added. 12 * js/dom/script-tests/cross-frame-symbols.js: Added. 13 1 14 2015-04-16 Beth Dakin <bdakin@apple.com> 2 15 -
trunk/Source/JavaScriptCore/CMakeLists.txt
r182911 r182915 565 565 runtime/StructureRareData.cpp 566 566 runtime/Symbol.cpp 567 runtime/SymbolConstructor.cpp 567 568 runtime/SymbolObject.cpp 568 569 runtime/SymbolPrototype.cpp 569 runtime/SymbolConstructor.cpp570 570 runtime/SymbolTable.cpp 571 571 runtime/TestRunnerUtils.cpp … … 611 611 runtime/StringConstructor.cpp 612 612 runtime/StringIteratorPrototype.cpp 613 runtime/SymbolConstructor.cpp 613 614 runtime/SymbolPrototype.cpp 614 615 ) -
trunk/Source/JavaScriptCore/ChangeLog
r182911 r182915 1 2015-04-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Implement Symbol.for and Symbol.keyFor 4 https://bugs.webkit.org/show_bug.cgi?id=143404 5 6 Reviewed by Geoffrey Garen. 7 8 This patch implements Symbol.for and Symbol.keyFor. 9 SymbolRegistry maintains registered StringImpl* symbols. 10 And to make this mapping enabled over realms, 11 VM owns this mapping (not JSGlobalObject). 12 13 While there's Default AtomicStringTable per thread, 14 SymbolRegistry should not exist over VMs. 15 So everytime VM is created, SymbolRegistry is also created. 16 17 In SymbolRegistry implementation, we don't leverage WeakGCMap (or weak reference design). 18 Theres are several reasons. 19 1. StringImpl* which represents identity of Symbols is not GC-managed object. 20 So we cannot use WeakGCMap directly. 21 While Symbol* is GC-managed object, holding weak reference to Symbol* doesn't maintain JS symbols (exposed primitive values to users) liveness, 22 because distinct Symbol* can exist. 23 Distinct Symbol* means the Symbol* object that pointer value (Symbol*) is different from weakly referenced Symbol* but held StringImpl* is the same. 24 25 2. We don't use WTF::WeakPtr. If we add WeakPtrFactory into StringImpl's member, we can track StringImpl*'s liveness by WeakPtr. 26 However there's problem about when we prune staled entries in SymbolRegistry. 27 Since the memory allocated for the Symbol is typically occupied by allocated symbolized StringImpl*'s content, 28 and it is not in GC-heap. 29 While heavily registering Symbols and storing StringImpl* into SymbolRegistry, Heap's EdenSpace is not so occupied. 30 So GC typically attempt to perform EdenCollection, and it doesn't call WeakGCMap's pruleStaleEntries callback. 31 As a result, before pruning staled entries in SymbolRegistry, fast malloc-ed memory fills up the system memory. 32 33 So instead of using Weak reference, we take relatively easy design. 34 When we register symbolized StringImpl* into SymbolRegistry, symbolized StringImpl* is aware of that. 35 And when destructing it, it removes its reference from SymbolRegistry as if atomic StringImpl do so with AtomicStringTable. 36 37 * CMakeLists.txt: 38 * DerivedSources.make: 39 * runtime/SymbolConstructor.cpp: 40 (JSC::SymbolConstructor::getOwnPropertySlot): 41 (JSC::symbolConstructorFor): 42 (JSC::symbolConstructorKeyFor): 43 * runtime/SymbolConstructor.h: 44 * runtime/VM.cpp: 45 * runtime/VM.h: 46 (JSC::VM::symbolRegistry): 47 * tests/stress/symbol-registry.js: Added. 48 (test): 49 1 50 2015-04-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 51 -
trunk/Source/JavaScriptCore/DerivedSources.make
r182193 r182915 59 59 StringConstructor.lut.h \ 60 60 StringIteratorPrototype.lut.h \ 61 SymbolConstructor.lut.h \ 61 62 SymbolPrototype.lut.h \ 62 63 udis86_itab.h \ -
trunk/Source/JavaScriptCore/runtime/SymbolConstructor.cpp
r182205 r182915 31 31 #include "JSCInlines.h" 32 32 #include "JSGlobalObject.h" 33 #include "Symbol.h" 33 34 #include "SymbolPrototype.h" 35 #include <wtf/text/SymbolRegistry.h> 36 37 namespace JSC { 38 39 static EncodedJSValue JSC_HOST_CALL symbolConstructorFor(ExecState*); 40 static EncodedJSValue JSC_HOST_CALL symbolConstructorKeyFor(ExecState*); 41 42 } 43 44 #include "SymbolConstructor.lut.h" 34 45 35 46 namespace JSC { … … 38 49 39 50 const ClassInfo SymbolConstructor::s_info = { "Function", &Base::s_info, 0, CREATE_METHOD_TABLE(SymbolConstructor) }; 51 52 /* Source for SymbolConstructor.lut.h 53 @begin symbolConstructorTable 54 for symbolConstructorFor DontEnum|Function 1 55 keyFor symbolConstructorKeyFor DontEnum|Function 1 56 @end 57 */ 40 58 41 59 SymbolConstructor::SymbolConstructor(VM& vm, Structure* structure) … … 55 73 JSC_COMMON_PRIVATE_IDENTIFIERS_EACH_WELL_KNOWN_SYMBOL(INITIALIZE_WELL_KNOWN_SYMBOLS) 56 74 } 75 76 bool SymbolConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot &slot) 77 { 78 return getStaticFunctionSlot<Base>(exec, symbolConstructorTable, jsCast<SymbolConstructor*>(object), propertyName, slot); 79 } 80 81 // ------------------------------ Functions --------------------------- 57 82 58 83 static EncodedJSValue JSC_HOST_CALL callSymbol(ExecState* exec) … … 75 100 } 76 101 102 EncodedJSValue JSC_HOST_CALL symbolConstructorFor(ExecState* exec) 103 { 104 JSString* stringKey = exec->argument(0).toString(exec); 105 if (exec->hadException()) 106 return JSValue::encode(jsUndefined()); 107 String string = stringKey->value(exec); 108 if (exec->hadException()) 109 return JSValue::encode(jsUndefined()); 110 111 Ref<StringImpl> uid = exec->vm().symbolRegistry().symbolForKey(string); 112 return JSValue::encode(Symbol::create(exec->vm(), static_cast<AtomicStringImpl*>(&uid.get()))); 113 } 114 115 EncodedJSValue JSC_HOST_CALL symbolConstructorKeyFor(ExecState* exec) 116 { 117 JSValue symbolValue = exec->argument(0); 118 if (!symbolValue.isSymbol()) 119 return JSValue::encode(throwTypeError(exec)); 120 121 AtomicStringImpl* uid = asSymbol(symbolValue)->privateName().uid(); 122 ASSERT(uid->isSymbol()); 123 if (!uid->symbolRegistry()) 124 return JSValue::encode(jsUndefined()); 125 126 ASSERT(uid->symbolRegistry() == &exec->vm().symbolRegistry()); 127 return JSValue::encode(jsString(exec, exec->vm().symbolRegistry().keyForSymbol(uid))); 128 } 129 77 130 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/SymbolConstructor.h
r179429 r182915 56 56 void finishCreation(VM&, SymbolPrototype*); 57 57 58 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags; 59 58 60 private: 59 61 SymbolConstructor(VM&, Structure*); 60 62 static ConstructType getConstructData(JSCell*, ConstructData&); 61 63 static CallType getCallData(JSCell*, CallData&); 64 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 62 65 }; 63 66 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r182899 r182915 88 88 #include "WeakGCMapInlines.h" 89 89 #include "WeakMapData.h" 90 #include <wtf/CurrentTime.h> 90 91 #include <wtf/ProcessID.h> 91 92 #include <wtf/RetainPtr.h> … … 94 95 #include <wtf/WTFThreadData.h> 95 96 #include <wtf/text/AtomicStringTable.h> 96 #include <wtf/ CurrentTime.h>97 #include <wtf/text/SymbolRegistry.h> 97 98 98 99 #if ENABLE(DFG_JIT) -
trunk/Source/JavaScriptCore/runtime/VM.h
r182899 r182915 65 65 #include <wtf/ThreadSpecific.h> 66 66 #include <wtf/WTFThreadData.h> 67 #include <wtf/text/SymbolRegistry.h> 67 68 #include <wtf/text/WTFString.h> 68 69 #if ENABLE(REGEXP_TRACING) … … 281 282 282 283 AtomicStringTable* m_atomicStringTable; 284 WTF::SymbolRegistry m_symbolRegistry; 283 285 CommonIdentifiers* propertyNames; 284 286 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. … … 291 293 292 294 AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; } 295 WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; } 293 296 294 297 void setInDefineOwnProperty(bool inDefineOwnProperty) -
trunk/Source/WTF/ChangeLog
r182895 r182915 1 2015-04-16 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Implement Symbol.for and Symbol.keyFor 4 https://bugs.webkit.org/show_bug.cgi?id=143404 5 6 Reviewed by Geoffrey Garen. 7 8 When we register symbolized StringImpl* into SymbolRegistry, symbolized StringImpl* is aware of that. 9 And when destructing it, it removes its reference from SymbolRegistry as if atomic StringImpl do so with AtomicStringTable. 10 While AtomicStringTable (in WebCore case) exists in thread local storage, 11 SymbolRegistry exists per VM and StringImpl* has a reference to the registered SymbolRegistry. 12 13 Since StringImpl has isSymbol etc. members, it's class is aware of Symbol use cases. 14 So introduce SymbolRegistry in WTF layers as if AtomicStringTable. 15 16 * WTF.vcxproj/WTF.vcxproj: 17 * WTF.vcxproj/WTF.vcxproj.filters: 18 * WTF.xcodeproj/project.pbxproj: 19 * wtf/CMakeLists.txt: 20 * wtf/text/AtomicString.cpp: 21 (WTF::AtomicString::addSlowCase): 22 (WTF::AtomicString::findSlowCase): 23 (WTF::AtomicString::findInternal): 24 (WTF::AtomicString::find): Deleted. 25 * wtf/text/AtomicString.h: 26 (WTF::AtomicString::find): 27 * wtf/text/StringImpl.cpp: 28 (WTF::StringImpl::~StringImpl): 29 (WTF::StringImpl::createSymbol): 30 (WTF::StringImpl::createSymbolEmpty): 31 * wtf/text/StringImpl.h: 32 (WTF::StringImpl::StringImpl): 33 (WTF::StringImpl::extractFoldedStringInSymbol): 34 (WTF::StringImpl::symbolRegistry): 35 (WTF::StringImpl::createSymbolEmpty): Deleted. 36 * wtf/text/SymbolRegistry.cpp: Copied from Source/JavaScriptCore/runtime/SymbolConstructor.h. 37 (WTF::SymbolRegistry::~SymbolRegistry): 38 (WTF::SymbolRegistry::symbolForKey): 39 (WTF::SymbolRegistry::keyForSymbol): 40 (WTF::SymbolRegistry::remove): 41 * wtf/text/SymbolRegistry.h: Added. 42 (WTF::SymbolRegistryKey::hash): 43 (WTF::SymbolRegistryKey::impl): 44 (WTF::SymbolRegistryKey::isHashTableDeletedValue): 45 (WTF::SymbolRegistryKey::hashTableDeletedValue): 46 (WTF::DefaultHash<SymbolRegistryKey>::Hash::hash): 47 (WTF::DefaultHash<SymbolRegistryKey>::Hash::equal): 48 (WTF::HashTraits<SymbolRegistryKey>::isEmptyValue): 49 (WTF::SymbolRegistryKey::SymbolRegistryKey): 50 1 51 2015-04-16 Antti Koivisto <antti@apple.com> 2 52 -
trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj
r181758 r182915 135 135 <ClCompile Include="..\wtf\text\StringStatics.cpp" /> 136 136 <ClCompile Include="..\wtf\text\StringView.cpp" /> 137 <ClCompile Include="..\wtf\text\SymbolRegistry.cpp" /> 137 138 <ClCompile Include="..\wtf\text\WTFString.cpp" /> 138 139 <ClCompile Include="..\wtf\text\cf\AtomicStringCF.cpp" /> … … 296 297 <ClInclude Include="..\wtf\text\StringOperators.h" /> 297 298 <ClInclude Include="..\wtf\text\StringView.h" /> 299 <ClInclude Include="..\wtf\text\SymbolRegistry.h" /> 298 300 <ClInclude Include="..\wtf\text\WTFString.h" /> 299 301 <ClInclude Include="..\wtf\Threading.h" /> -
trunk/Source/WTF/WTF.vcxproj/WTF.vcxproj.filters
r181758 r182915 79 79 <Filter>text</Filter> 80 80 </ClCompile> 81 <ClCompile Include="..\wtf\text\SymbolRegistry.cpp"> 82 <Filter>text</Filter> 83 </ClCompile> 81 84 <ClCompile Include="..\wtf\text\WTFString.cpp"> 82 85 <Filter>text</Filter> … … 342 345 <ClInclude Include="..\wtf\text\StringView.h"> 343 346 <Filter>wtf</Filter> 347 </ClInclude> 348 <ClInclude Include="..\wtf\text\SymbolRegistry.h"> 349 <Filter>text</Filter> 344 350 </ClInclude> 345 351 <ClInclude Include="..\wtf\text\WTFString.h"> -
trunk/Source/WTF/WTF.xcodeproj/project.pbxproj
r181758 r182915 75 75 2CDED0F418115C85004DBA70 /* RunLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CDED0F218115C85004DBA70 /* RunLoop.h */; }; 76 76 430B47891AAAAC1A001223DA /* StringCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 430B47871AAAAC1A001223DA /* StringCommon.h */; }; 77 70A993FE1AD7151300FA615B /* SymbolRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 70A993FC1AD7151300FA615B /* SymbolRegistry.cpp */; }; 78 70A993FF1AD7151300FA615B /* SymbolRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 70A993FD1AD7151300FA615B /* SymbolRegistry.h */; }; 77 79 7CBBA07419BB7FDC00BBF025 /* OSObjectPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CBBA07319BB7FDC00BBF025 /* OSObjectPtr.h */; }; 78 80 7CDD7FF8186D291E007433CD /* IteratorAdaptors.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CDD7FF7186D291E007433CD /* IteratorAdaptors.h */; }; … … 363 365 5D247B7314689C4700E78B76 /* WTF.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = WTF.xcconfig; sourceTree = "<group>"; }; 364 366 6541CAF41630DB26006D0DEC /* CopyWTFHeaders.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CopyWTFHeaders.xcconfig; sourceTree = "<group>"; }; 367 70A993FC1AD7151300FA615B /* SymbolRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolRegistry.cpp; sourceTree = "<group>"; }; 368 70A993FD1AD7151300FA615B /* SymbolRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolRegistry.h; sourceTree = "<group>"; }; 365 369 7CBBA07319BB7FDC00BBF025 /* OSObjectPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSObjectPtr.h; sourceTree = "<group>"; }; 366 370 7CDD7FF7186D291E007433CD /* IteratorAdaptors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IteratorAdaptors.h; sourceTree = "<group>"; }; … … 955 959 A8A4732A151A825B004123FF /* StringOperators.h */, 956 960 A8A4732B151A825B004123FF /* StringStatics.cpp */, 961 70A993FC1AD7151300FA615B /* SymbolRegistry.cpp */, 962 70A993FD1AD7151300FA615B /* SymbolRegistry.h */, 957 963 A8A4732C151A825B004123FF /* TextPosition.h */, 958 964 A8A4732D151A825B004123FF /* WTFString.cpp */, … … 1128 1134 CE46516E19DB1FB4003ECA05 /* NSMapTableSPI.h in Headers */, 1129 1135 0F0D85B417234CC100338210 /* NoLock.h in Headers */, 1136 70A993FF1AD7151300FA615B /* SymbolRegistry.h in Headers */, 1130 1137 A8A473EF151A825B004123FF /* Noncopyable.h in Headers */, 1131 1138 A8A473F5151A825B004123FF /* NumberOfCores.h in Headers */, … … 1379 1386 A5BA15F51824348000A82E69 /* StringImplMac.mm in Sources */, 1380 1387 A5BA15F3182433A900A82E69 /* StringMac.mm in Sources */, 1388 70A993FE1AD7151300FA615B /* SymbolRegistry.cpp in Sources */, 1381 1389 0FDDBFA71666DFA300C55FEF /* StringPrintStream.cpp in Sources */, 1382 1390 A8A47443151A825B004123FF /* StringStatics.cpp in Sources */, -
trunk/Source/WTF/wtf/CMakeLists.txt
r182243 r182915 133 133 text/StringImpl.h 134 134 text/StringView.h 135 text/SymbolRegistry.h 135 136 text/WTFString.h 136 137 … … 200 201 text/StringStatics.cpp 201 202 text/StringView.cpp 203 text/SymbolRegistry.cpp 202 204 text/WTFString.cpp 203 205 -
trunk/Source/WTF/wtf/text/AtomicString.cpp
r182205 r182915 404 404 return *StringImpl::empty(); 405 405 406 if (string.isSymbol()) 407 return add(string.extractFoldedStringInSymbol()); 406 if (string.isSymbol()) { 407 if (string.is8Bit()) 408 return *add(string.characters8(), string.length()); 409 return *add(string.characters16(), string.length()); 410 } 408 411 409 412 ASSERT_WITH_MESSAGE(!string.isAtomic(), "AtomicString should not hit the slow case if the string is already atomic."); … … 425 428 return *StringImpl::empty(); 426 429 427 if (string.isSymbol()) 428 return add(stringTable, string.extractFoldedStringInSymbol()); 430 if (string.isSymbol()) { 431 if (string.is8Bit()) 432 return *add(string.characters8(), string.length()); 433 return *add(string.characters16(), string.length()); 434 } 429 435 430 436 ASSERT_WITH_MESSAGE(!string.isAtomic(), "AtomicString should not hit the slow case if the string is already atomic."); … … 513 519 return static_cast<AtomicStringImpl*>(StringImpl::empty()); 514 520 515 if (string.isSymbol()) 516 return find(&string.extractFoldedStringInSymbol()); 521 if (string.isSymbol()) { 522 if (string.is8Bit()) 523 return findInternal(string.characters8(), string.length()); 524 return findInternal(string.characters16(), string.length()); 525 } 517 526 518 527 AtomicStringTableLocker locker; … … 554 563 } 555 564 556 AtomicStringImpl* AtomicString::find (LChar* characters, unsigned length)565 AtomicStringImpl* AtomicString::findInternal(const LChar* characters, unsigned length) 557 566 { 558 567 AtomicStringTableLocker locker; … … 566 575 } 567 576 568 AtomicStringImpl* AtomicString::find (UChar* characters, unsigned length)577 AtomicStringImpl* AtomicString::findInternal(const UChar* characters, unsigned length) 569 578 { 570 579 AtomicStringTableLocker locker; -
trunk/Source/WTF/wtf/text/AtomicString.h
r182205 r182915 87 87 bool isHashTableDeletedValue() const { return m_string.isHashTableDeletedValue(); } 88 88 89 WTF_EXPORT_STRING_API static AtomicStringImpl* find(LChar*, unsigned length); 90 WTF_EXPORT_STRING_API static AtomicStringImpl* find(UChar*, unsigned length); 89 static AtomicStringImpl* find(LChar* characters, unsigned length) 90 { 91 return findInternal(characters, length); 92 } 93 static AtomicStringImpl* find(UChar* characters, unsigned length) 94 { 95 return findInternal(characters, length); 96 } 91 97 static AtomicStringImpl* find(StringImpl* string) 92 98 { … … 250 256 WTF_EXPORT_STRING_API static AtomicStringImpl* findSlowCase(StringImpl&); 251 257 WTF_EXPORT_STRING_API static AtomicString fromUTF8Internal(const char*, const char*); 258 259 WTF_EXPORT_STRING_API static AtomicStringImpl* findInternal(const LChar*, unsigned length); 260 WTF_EXPORT_STRING_API static AtomicStringImpl* findInternal(const UChar*, unsigned length); 252 261 }; 253 262 -
trunk/Source/WTF/wtf/text/StringImpl.cpp
r182205 r182915 34 34 #include <wtf/text/CString.h> 35 35 #include <wtf/text/StringView.h> 36 #include <wtf/text/SymbolRegistry.h> 36 37 #include <wtf/unicode/CharacterNames.h> 37 38 #include <wtf/unicode/UTF8.h> … … 113 114 AtomicString::remove(this); 114 115 116 if (isSymbol() && symbolRegistry()) 117 symbolRegistry()->remove(this); 118 115 119 BufferOwnership ownership = bufferOwnership(); 116 120 … … 289 293 Ref<StringImpl> StringImpl::createSymbol(PassRefPtr<StringImpl> rep) 290 294 { 291 unsigned length = rep->length(); 292 if (!length) 293 return createSymbolEmpty(); 294 Ref<StringImpl> string = createSubstringSharingImpl(rep, 0, length); 295 ASSERT(!string->isAtomic()); 296 string->m_hashAndFlags = hashAndFlagsForSymbol(string->m_hashAndFlags); 297 return string; 295 StringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->substringBuffer() : rep.get(); 296 297 // We allocate a buffer that contains 298 // 1. the StringImpl struct 299 // 2. the pointer to the owner string 300 // 3. the pointer to the symbol registry 301 StringImpl* stringImpl = static_cast<StringImpl*>(fastMalloc(allocationSize<StringImpl*>(2))); 302 if (rep->is8Bit()) 303 return adoptRef(*new (NotNull, stringImpl) StringImpl(CreateSymbol, rep->m_data8, rep->length(), ownerRep)); 304 return adoptRef(*new (NotNull, stringImpl) StringImpl(CreateSymbol, rep->m_data16, rep->length(), ownerRep)); 305 } 306 307 Ref<StringImpl> StringImpl::createSymbolEmpty() 308 { 309 return createSymbol(empty()); 298 310 } 299 311 -
trunk/Source/WTF/wtf/text/StringImpl.h
r182222 r182915 58 58 struct UCharBufferTranslator; 59 59 template<typename> class RetainPtr; 60 class SymbolRegistry; 60 61 61 62 enum TextCaseSensitivity { … … 293 294 } 294 295 295 enum CreateSymbolEmptyTag { CreateSymbolEmpty }; 296 StringImpl(CreateSymbolEmptyTag) 296 enum CreateSymbolTag { CreateSymbol }; 297 // Used to create new symbol strings that holds existing 8-bit [[Description]] string as a substring buffer (BufferSubstring). 298 StringImpl(CreateSymbolTag, const LChar* characters, unsigned length, PassRefPtr<StringImpl> base) 297 299 : m_refCount(s_refCountIncrement) 298 , m_length(0) 299 // We expect m_length to be initialized to 0 as we use it 300 // to represent a null terminated buffer. 301 , m_data8(reinterpret_cast<const LChar*>(&m_length)) 302 , m_hashAndFlags(hashAndFlagsForSymbol(s_hashFlag8BitBuffer | BufferInternal)) 303 { 300 , m_length(length) 301 , m_data8(characters) 302 , m_hashAndFlags(hashAndFlagsForSymbol(s_hashFlag8BitBuffer | StringSymbol | BufferSubstring)) 303 { 304 ASSERT(is8Bit()); 304 305 ASSERT(m_data8); 305 306 STRING_STATS_ADD_8BIT_STRING(m_length); 306 ASSERT(base->bufferOwnership() != BufferSubstring); 307 308 substringBuffer() = base.leakRef(); 309 symbolRegistry() = nullptr; 310 311 STRING_STATS_ADD_8BIT_STRING2(m_length, true); 312 } 313 314 // Used to create new symbol strings that holds existing 16-bit [[Description]] string as a substring buffer (BufferSubstring). 315 StringImpl(CreateSymbolTag, const UChar* characters, unsigned length, PassRefPtr<StringImpl> base) 316 : m_refCount(s_refCountIncrement) 317 , m_length(length) 318 , m_data16(characters) 319 , m_hashAndFlags(hashAndFlagsForSymbol(StringSymbol | BufferSubstring)) 320 { 321 ASSERT(!is8Bit()); 322 ASSERT(m_data16); 323 ASSERT(base->bufferOwnership() != BufferSubstring); 324 325 substringBuffer() = base.leakRef(); 326 symbolRegistry() = nullptr; 327 328 STRING_STATS_ADD_16BIT_STRING2(m_length, true); 307 329 } 308 330 … … 398 420 } 399 421 400 ALWAYS_INLINE static Ref<StringImpl> createSymbolEmpty() 401 { 402 return adoptRef(*new StringImpl(CreateSymbolEmpty)); 403 } 404 422 WTF_EXPORT_STRING_API static Ref<StringImpl> createSymbolEmpty(); 405 423 WTF_EXPORT_STRING_API static Ref<StringImpl> createSymbol(PassRefPtr<StringImpl> rep); 406 424 … … 742 760 WTF_EXPORT_STRING_API static const UChar latin1CaseFoldTable[256]; 743 761 744 StringImpl& extractFoldedStringInSymbol() 745 { 746 ASSERT(length()); 762 Ref<StringImpl> extractFoldedStringInSymbol() 763 { 747 764 ASSERT(isSymbol()); 748 765 ASSERT(bufferOwnership() == BufferSubstring); 749 766 ASSERT(substringBuffer()); 750 767 ASSERT(!substringBuffer()->isSymbol()); 751 return *substringBuffer(); 768 return createSubstringSharingImpl(this, 0, length()); 769 } 770 771 SymbolRegistry* const& symbolRegistry() const 772 { 773 ASSERT(isSymbol()); 774 return *(tailPointer<SymbolRegistry*>() + 1); 775 } 776 777 SymbolRegistry*& symbolRegistry() 778 { 779 ASSERT(isSymbol()); 780 return *(tailPointer<SymbolRegistry*>() + 1); 752 781 } 753 782 -
trunk/Source/WTF/wtf/text/SymbolRegistry.cpp
r182914 r182915 1 1 /* 2 * Copyright (C) 2012 Apple Inc. All rights reserved.3 2 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>. 4 3 * … … 25 24 */ 26 25 27 #i fndef SymbolConstructor_h28 # define SymbolConstructor_h26 #include "config.h" 27 #include "SymbolRegistry.h" 29 28 30 #include "InternalFunction.h" 31 #include "Symbol.h" 29 namespace WTF { 32 30 33 namespace JSC { 31 SymbolRegistry::~SymbolRegistry() 32 { 33 for (auto& key : m_table) 34 key.impl()->symbolRegistry() = nullptr; 35 } 34 36 35 class SymbolPrototype; 37 Ref<StringImpl> SymbolRegistry::symbolForKey(const String& rep) 38 { 39 auto addResult = m_table.add(SymbolRegistryKey(rep.impl())); 40 if (!addResult.isNewEntry) 41 return *addResult.iterator->impl(); 36 42 37 class SymbolConstructor : public InternalFunction { 38 public: 39 typedef InternalFunction Base; 43 Ref<StringImpl> symbol = StringImpl::createSymbol(rep.impl()); 44 symbol->symbolRegistry() = this; 45 *addResult.iterator = SymbolRegistryKey(&symbol.get()); 46 return symbol; 47 } 40 48 41 static SymbolConstructor* create(VM& vm, Structure* structure, SymbolPrototype* prototype)42 43 SymbolConstructor* constructor = new (NotNull, allocateCell<SymbolConstructor>(vm.heap)) SymbolConstructor(vm, structure);44 constructor->finishCreation(vm, prototype);45 return constructor;46 49 String SymbolRegistry::keyForSymbol(StringImpl* uid) 50 { 51 ASSERT(uid->isSymbol()); 52 ASSERT(uid->symbolRegistry() == this); 53 return uid->extractFoldedStringInSymbol(); 54 } 47 55 48 DECLARE_INFO; 56 void SymbolRegistry::remove(StringImpl* uid) 57 { 58 ASSERT(uid->isSymbol()); 59 ASSERT(uid->symbolRegistry() == this); 60 auto iterator = m_table.find(SymbolRegistryKey(uid)); 61 ASSERT_WITH_MESSAGE(iterator != m_table.end(), "The string being removed is registered in the string table of an other thread!"); 62 m_table.remove(iterator); 63 } 49 64 50 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 51 { 52 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 53 } 54 55 protected: 56 void finishCreation(VM&, SymbolPrototype*); 57 58 private: 59 SymbolConstructor(VM&, Structure*); 60 static ConstructType getConstructData(JSCell*, ConstructData&); 61 static CallType getCallData(JSCell*, CallData&); 62 }; 63 64 } // namespace JSC 65 66 #endif // SymbolConstructor_h 65 }
Note: See TracChangeset
for help on using the changeset viewer.