Home | History | Annotate | Download | only in wtf
      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