422 void AtomicString::remove(StringImpl* r)
423 {
424 HashSet<StringImpl*>::iterator iterator;
425 if (r->is8Bit())
426 iterator = findString<LChar>(r);
427 else
428 iterator = findString<UChar>(r);
429 RELEASE_ASSERT(iterator != stringTable().end());
430 stringTable().remove(iterator);
431 }
398 static inline HashSet<StringImpl*>::iterator findString(const StringImpl* stringImpl)
399 {
400 HashAndCharacters<CharacterType> buffer =
{ stringImpl->existingHash(),
stringImpl->getCharacters<CharacterType>(),
stringImpl->length() };
401 return stringTable().find<HashAndCharactersTranslator<CharacterType> >(buffer);
402 }
63 static inline HashSet<StringImpl*>& stringTable()
64 {
65
66 WTFThreadData& data = wtfThreadData();
67 AtomicStringTable* table = data.atomicStringTable();
68 if (UNLIKELY(!table))
69 table = AtomicStringTable::create(data);
70 return table->table();
71 }
71 inline WTFThreadData& wtfThreadData()
72 {
73
74
75
76
77
78
79 if (!WTFThreadData::staticData)
80 WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>;
81 return **WTFThreadData::staticData;
82 }
251 template<typename T>
252 inline ThreadSpecific<T>::operator T*()
253 {
254 T* ptr = static_cast<T*>(get());
255 if (!ptr) {
256
in case any function it calls
257
258 ptr = static_cast<T*>(fastZeroedMalloc(sizeof(T)));
259 set(ptr);
260 new (NotNull, ptr) T;
261 }
262 return ptr;
263 }
142 template<typename T>
143 inline T* ThreadSpecific<T>::get()
144 {
145 Data* data = static_cast<Data*>(pthread_getspecific(m_key));
146 return data ? data->value : 0;
147 }
233 void* pthread_getspecific(pthread_key_t key) {
234 if (!IsValidUserKey(key)) {
235 return NULL;
236 }
237
238
239
240
241
242 return (void *)(((unsigned *)__get_tls())[key]);
243 }