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