1/* 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27#ifndef WTFThreadData_h 28#define WTFThreadData_h 29 30#include <wtf/HashMap.h> 31#include <wtf/HashSet.h> 32#include <wtf/Noncopyable.h> 33#include <wtf/StackBounds.h> 34#include <wtf/text/StringHash.h> 35 36// This was ENABLE(WORKERS) in WebCore, but this is not defined when compiling JSC. 37// However this check was not correct anyway, re this comment: 38// // FIXME: Workers are not necessarily the only feature that make per-thread global data necessary. 39// // We need to check for e.g. database objects manipulating strings on secondary threads. 40// Always enabling this is safe, and should be a better option until we can come up 41// with a better define. 42#define WTFTHREADDATA_MULTITHREADED 1 43 44#if WTFTHREADDATA_MULTITHREADED 45#include <wtf/ThreadSpecific.h> 46#include <wtf/Threading.h> 47#endif 48 49#if USE(JSC) 50// FIXME: This is a temporary layering violation while we move more string code to WTF. 51namespace JSC { 52 53typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable; 54 55class IdentifierTable { 56 WTF_MAKE_FAST_ALLOCATED; 57public: 58 ~IdentifierTable(); 59 60 std::pair<HashSet<StringImpl*>::iterator, bool> add(StringImpl* value); 61 template<typename U, typename V> 62 std::pair<HashSet<StringImpl*>::iterator, bool> add(U value); 63 64 bool remove(StringImpl* r) 65 { 66 HashSet<StringImpl*>::iterator iter = m_table.find(r); 67 if (iter == m_table.end()) 68 return false; 69 m_table.remove(iter); 70 return true; 71 } 72 73 LiteralIdentifierTable& literalTable() { return m_literalTable; } 74 75private: 76 HashSet<StringImpl*> m_table; 77 LiteralIdentifierTable m_literalTable; 78}; 79 80} 81#endif 82 83namespace WTF { 84 85class AtomicStringTable; 86 87typedef void (*AtomicStringTableDestructor)(AtomicStringTable*); 88 89class WTFThreadData { 90 WTF_MAKE_NONCOPYABLE(WTFThreadData); 91public: 92 WTFThreadData(); 93 ~WTFThreadData(); 94 95 AtomicStringTable* atomicStringTable() 96 { 97 return m_atomicStringTable; 98 } 99 100#if USE(JSC) 101 JSC::IdentifierTable* currentIdentifierTable() 102 { 103 return m_currentIdentifierTable; 104 } 105 106 JSC::IdentifierTable* setCurrentIdentifierTable(JSC::IdentifierTable* identifierTable) 107 { 108 JSC::IdentifierTable* oldIdentifierTable = m_currentIdentifierTable; 109 m_currentIdentifierTable = identifierTable; 110 return oldIdentifierTable; 111 } 112 113 void resetCurrentIdentifierTable() 114 { 115 m_currentIdentifierTable = m_defaultIdentifierTable; 116 } 117 118 const StackBounds& stack() const 119 { 120 return m_stackBounds; 121 } 122#endif 123 124private: 125 AtomicStringTable* m_atomicStringTable; 126 AtomicStringTableDestructor m_atomicStringTableDestructor; 127 128#if USE(JSC) 129 JSC::IdentifierTable* m_defaultIdentifierTable; 130 JSC::IdentifierTable* m_currentIdentifierTable; 131 StackBounds m_stackBounds; 132#endif 133 134#if WTFTHREADDATA_MULTITHREADED 135 static JS_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData; 136#else 137 static JS_EXPORTDATA WTFThreadData* staticData; 138#endif 139 friend WTFThreadData& wtfThreadData(); 140 friend class AtomicStringTable; 141}; 142 143inline WTFThreadData& wtfThreadData() 144{ 145#if WTFTHREADDATA_MULTITHREADED 146 // WRT WebCore: 147 // WTFThreadData is used on main thread before it could possibly be used 148 // on secondary ones, so there is no need for synchronization here. 149 // WRT JavaScriptCore: 150 // wtfThreadData() is initially called from initializeThreading(), ensuring 151 // this is initially called in a pthread_once locked context. 152 if (!WTFThreadData::staticData) 153 WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>; 154 return **WTFThreadData::staticData; 155#else 156 if (!WTFThreadData::staticData) { 157 WTFThreadData::staticData = static_cast<WTFThreadData*>(fastMalloc(sizeof(WTFThreadData))); 158 // WTFThreadData constructor indirectly uses staticData, so we need to set up the memory before invoking it. 159 new (WTFThreadData::staticData) WTFThreadData; 160 } 161 return *WTFThreadData::staticData; 162#endif 163} 164 165} // namespace WTF 166 167using WTF::WTFThreadData; 168using WTF::wtfThreadData; 169 170#endif // WTFThreadData_h 171