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