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. 51 namespace JSC { 52 53 typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable; 54 55 class IdentifierTable { 56 WTF_MAKE_FAST_ALLOCATED; 57 public: 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 75 private: 76 HashSet<StringImpl*> m_table; 77 LiteralIdentifierTable m_literalTable; 78 }; 79 80 } 81 #endif 82 83 namespace WTF { 84 85 class AtomicStringTable; 86 87 typedef void (*AtomicStringTableDestructor)(AtomicStringTable*); 88 89 class WTFThreadData { 90 WTF_MAKE_NONCOPYABLE(WTFThreadData); 91 public: 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 124 private: 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 143 inline 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 167 using WTF::WTFThreadData; 168 using WTF::wtfThreadData; 169 170 #endif // WTFThreadData_h 171