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 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 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/StackStats.h> 35#include <wtf/text/StringHash.h> 36 37#if OS(DARWIN) 38#if defined(__has_include) && __has_include(<System/pthread_machdep.h>) 39#include <System/pthread_machdep.h> 40#endif 41#endif 42 43#if defined(__PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1) 44#define WTF_USE_PTHREAD_GETSPECIFIC_DIRECT 1 45#endif 46 47#if !USE(PTHREAD_GETSPECIFIC_DIRECT) 48#include <wtf/ThreadSpecific.h> 49#include <wtf/Threading.h> 50#endif 51 52namespace WTF { 53 54class AtomicStringTable; 55 56typedef void (*AtomicStringTableDestructor)(AtomicStringTable*); 57 58class WTFThreadData { 59 WTF_MAKE_NONCOPYABLE(WTFThreadData); 60public: 61 WTF_EXPORT_PRIVATE WTFThreadData(); 62 WTF_EXPORT_PRIVATE ~WTFThreadData(); 63 64 AtomicStringTable* atomicStringTable() 65 { 66 return m_currentAtomicStringTable; 67 } 68 69 AtomicStringTable* setCurrentAtomicStringTable(AtomicStringTable* atomicStringTable) 70 { 71 AtomicStringTable* oldAtomicStringTable = m_currentAtomicStringTable; 72 m_currentAtomicStringTable = atomicStringTable; 73 return oldAtomicStringTable; 74 } 75 76 void resetCurrentAtomicStringTable() 77 { 78 m_currentAtomicStringTable = m_defaultAtomicStringTable; 79 } 80 81 const StackBounds& stack() 82 { 83 // We need to always get a fresh StackBounds from the OS due to how fibers work. 84 // See https://bugs.webkit.org/show_bug.cgi?id=102411 85#if OS(WINDOWS) 86 m_stackBounds = StackBounds::currentThreadStackBounds(); 87#endif 88 return m_stackBounds; 89 } 90 91#if ENABLE(STACK_STATS) 92 StackStats::PerThreadStats& stackStats() 93 { 94 return m_stackStats; 95 } 96#endif 97 98 void* savedStackPointerAtVMEntry() 99 { 100 return m_savedStackPointerAtVMEntry; 101 } 102 103 void setSavedStackPointerAtVMEntry(void* stackPointerAtVMEntry) 104 { 105 m_savedStackPointerAtVMEntry = stackPointerAtVMEntry; 106 } 107 108 void* savedLastStackTop() 109 { 110 return m_savedLastStackTop; 111 } 112 113 void setSavedLastStackTop(void* lastStackTop) 114 { 115 m_savedLastStackTop = lastStackTop; 116 } 117 118 void* m_apiData; 119 120private: 121 AtomicStringTable* m_currentAtomicStringTable; 122 AtomicStringTable* m_defaultAtomicStringTable; 123 AtomicStringTableDestructor m_atomicStringTableDestructor; 124 125 StackBounds m_stackBounds; 126#if ENABLE(STACK_STATS) 127 StackStats::PerThreadStats m_stackStats; 128#endif 129 void* m_savedStackPointerAtVMEntry; 130 void* m_savedLastStackTop; 131 132#if USE(PTHREAD_GETSPECIFIC_DIRECT) 133 static const pthread_key_t directKey = __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1; 134 WTF_EXPORT_PRIVATE static WTFThreadData& createAndRegisterForGetspecificDirect(); 135#else 136 static WTF_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData; 137#endif 138 139 friend WTFThreadData& wtfThreadData(); 140 friend class AtomicStringTable; 141}; 142 143inline WTFThreadData& wtfThreadData() 144{ 145 // WRT WebCore: 146 // WTFThreadData is used on main thread before it could possibly be used 147 // on secondary ones, so there is no need for synchronization here. 148 // WRT JavaScriptCore: 149 // wtfThreadData() is initially called from initializeThreading(), ensuring 150 // this is initially called in a pthread_once locked context. 151#if !USE(PTHREAD_GETSPECIFIC_DIRECT) 152 if (!WTFThreadData::staticData) 153 WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>; 154 return **WTFThreadData::staticData; 155#else 156 if (WTFThreadData* data = static_cast<WTFThreadData*>(_pthread_getspecific_direct(WTFThreadData::directKey))) 157 return *data; 158 return WTFThreadData::createAndRegisterForGetspecificDirect(); 159#endif 160} 161 162} // namespace WTF 163 164using WTF::WTFThreadData; 165using WTF::wtfThreadData; 166using WTF::AtomicStringTable; 167 168#endif // WTFThreadData_h 169