Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2008, 2009 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  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #ifndef JSGlobalData_h
     30 #define JSGlobalData_h
     31 
     32 #include "CachedTranscendentalFunction.h"
     33 #include "Heap.h"
     34 #include "DateInstanceCache.h"
     35 #include "ExecutableAllocator.h"
     36 #include "Strong.h"
     37 #include "JITStubs.h"
     38 #include "JSValue.h"
     39 #include "NumericStrings.h"
     40 #include "SmallStrings.h"
     41 #include "Terminator.h"
     42 #include "TimeoutChecker.h"
     43 #include "WeakRandom.h"
     44 #include <wtf/BumpPointerAllocator.h>
     45 #include <wtf/Forward.h>
     46 #include <wtf/HashMap.h>
     47 #include <wtf/RefCounted.h>
     48 #include <wtf/ThreadSpecific.h>
     49 #include <wtf/WTFThreadData.h>
     50 #if ENABLE(REGEXP_TRACING)
     51 #include <wtf/ListHashSet.h>
     52 #endif
     53 
     54 struct OpaqueJSClass;
     55 struct OpaqueJSClassContextData;
     56 
     57 namespace JSC {
     58 
     59     class CodeBlock;
     60     class CommonIdentifiers;
     61     class HandleStack;
     62     class IdentifierTable;
     63     class Interpreter;
     64     class JSGlobalObject;
     65     class JSObject;
     66     class Lexer;
     67     class NativeExecutable;
     68     class Parser;
     69     class RegExpCache;
     70     class Stringifier;
     71     class Structure;
     72     class UString;
     73 #if ENABLE(REGEXP_TRACING)
     74     class RegExp;
     75 #endif
     76 
     77     struct HashTable;
     78     struct Instruction;
     79 
     80     struct DSTOffsetCache {
     81         DSTOffsetCache()
     82         {
     83             reset();
     84         }
     85 
     86         void reset()
     87         {
     88             offset = 0.0;
     89             start = 0.0;
     90             end = -1.0;
     91             increment = 0.0;
     92         }
     93 
     94         double offset;
     95         double start;
     96         double end;
     97         double increment;
     98     };
     99 
    100     enum ThreadStackType {
    101         ThreadStackTypeLarge,
    102         ThreadStackTypeSmall
    103     };
    104 
    105     class JSGlobalData : public RefCounted<JSGlobalData> {
    106     public:
    107         // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
    108         // either create() or createLeaked() should only be called once
    109         // on a thread, this is the 'default' JSGlobalData (it uses the
    110         // thread's default string uniquing table from wtfThreadData).
    111         // API contexts created using the new context group aware interface
    112         // create APIContextGroup objects which require less locking of JSC
    113         // than the old singleton APIShared JSGlobalData created for use by
    114         // the original API.
    115         enum GlobalDataType { Default, APIContextGroup, APIShared };
    116 
    117         struct ClientData {
    118             virtual ~ClientData() = 0;
    119         };
    120 
    121         bool isSharedInstance() { return globalDataType == APIShared; }
    122         bool usingAPI() { return globalDataType != Default; }
    123         static bool sharedInstanceExists();
    124         static JSGlobalData& sharedInstance();
    125 
    126         static PassRefPtr<JSGlobalData> create(ThreadStackType);
    127         static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType);
    128         static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType);
    129         ~JSGlobalData();
    130 
    131 #if ENABLE(JSC_MULTIPLE_THREADS)
    132         // Will start tracking threads that use the heap, which is resource-heavy.
    133         void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
    134 #endif
    135 
    136         GlobalDataType globalDataType;
    137         ClientData* clientData;
    138 
    139         const HashTable* arrayTable;
    140         const HashTable* dateTable;
    141         const HashTable* jsonTable;
    142         const HashTable* mathTable;
    143         const HashTable* numberTable;
    144         const HashTable* objectConstructorTable;
    145         const HashTable* regExpTable;
    146         const HashTable* regExpConstructorTable;
    147         const HashTable* stringTable;
    148 
    149         Strong<Structure> structureStructure;
    150         Strong<Structure> activationStructure;
    151         Strong<Structure> interruptedExecutionErrorStructure;
    152         Strong<Structure> terminatedExecutionErrorStructure;
    153         Strong<Structure> staticScopeStructure;
    154         Strong<Structure> strictEvalActivationStructure;
    155         Strong<Structure> stringStructure;
    156         Strong<Structure> notAnObjectStructure;
    157         Strong<Structure> propertyNameIteratorStructure;
    158         Strong<Structure> getterSetterStructure;
    159         Strong<Structure> apiWrapperStructure;
    160         Strong<Structure> scopeChainNodeStructure;
    161         Strong<Structure> executableStructure;
    162         Strong<Structure> nativeExecutableStructure;
    163         Strong<Structure> evalExecutableStructure;
    164         Strong<Structure> programExecutableStructure;
    165         Strong<Structure> functionExecutableStructure;
    166         Strong<Structure> dummyMarkableCellStructure;
    167         Strong<Structure> structureChainStructure;
    168 
    169 #if ENABLE(JSC_ZOMBIES)
    170         Strong<Structure> zombieStructure;
    171 #endif
    172 
    173         static void storeVPtrs();
    174         static JS_EXPORTDATA void* jsArrayVPtr;
    175         static JS_EXPORTDATA void* jsByteArrayVPtr;
    176         static JS_EXPORTDATA void* jsStringVPtr;
    177         static JS_EXPORTDATA void* jsFunctionVPtr;
    178 
    179         IdentifierTable* identifierTable;
    180         CommonIdentifiers* propertyNames;
    181         const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
    182         SmallStrings smallStrings;
    183         NumericStrings numericStrings;
    184         DateInstanceCache dateInstanceCache;
    185 
    186 #if ENABLE(ASSEMBLER)
    187         ExecutableAllocator executableAllocator;
    188         ExecutableAllocator regexAllocator;
    189 #endif
    190 
    191 #if !ENABLE(JIT)
    192         bool canUseJIT() { return false; } // interpreter only
    193 #elif !ENABLE(INTERPRETER)
    194         bool canUseJIT() { return true; } // jit only
    195 #else
    196         bool canUseJIT() { return m_canUseJIT; }
    197 #endif
    198 
    199         const StackBounds& stack()
    200         {
    201             return (globalDataType == Default)
    202                 ? m_stack
    203                 : wtfThreadData().stack();
    204         }
    205 
    206         Lexer* lexer;
    207         Parser* parser;
    208         Interpreter* interpreter;
    209 #if ENABLE(JIT)
    210         OwnPtr<JITThunks> jitStubs;
    211         MacroAssemblerCodePtr getCTIStub(ThunkGenerator generator)
    212         {
    213             return jitStubs->ctiStub(this, generator);
    214         }
    215         NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator);
    216 #endif
    217         NativeExecutable* getHostFunction(NativeFunction);
    218 
    219         TimeoutChecker timeoutChecker;
    220         Terminator terminator;
    221         Heap heap;
    222 
    223         JSValue exception;
    224 #if ENABLE(JIT)
    225         ReturnAddressPtr exceptionLocation;
    226 #endif
    227 
    228         HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
    229 
    230         unsigned globalObjectCount;
    231         JSGlobalObject* dynamicGlobalObject;
    232 
    233         HashSet<JSObject*> stringRecursionCheckVisitedObjects;
    234 
    235         double cachedUTCOffset;
    236         DSTOffsetCache dstOffsetCache;
    237 
    238         UString cachedDateString;
    239         double cachedDateStringValue;
    240 
    241         int maxReentryDepth;
    242 
    243         RegExpCache* m_regExpCache;
    244         BumpPointerAllocator m_regExpAllocator;
    245 
    246 #if ENABLE(REGEXP_TRACING)
    247         typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
    248         RTTraceList* m_rtTraceList;
    249 #endif
    250 
    251 #ifndef NDEBUG
    252         ThreadIdentifier exclusiveThread;
    253 #endif
    254 
    255         CachedTranscendentalFunction<sin> cachedSin;
    256 
    257         void resetDateCache();
    258 
    259         void startSampling();
    260         void stopSampling();
    261         void dumpSampleData(ExecState* exec);
    262         void recompileAllJSFunctions();
    263         RegExpCache* regExpCache() { return m_regExpCache; }
    264 #if ENABLE(REGEXP_TRACING)
    265         void addRegExpToTrace(PassRefPtr<RegExp> regExp);
    266 #endif
    267         void dumpRegExpTrace();
    268         HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
    269         HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
    270         void clearBuiltinStructures();
    271 
    272     private:
    273         JSGlobalData(GlobalDataType, ThreadStackType);
    274         static JSGlobalData*& sharedInstanceInternal();
    275         void createNativeThunk();
    276 #if ENABLE(JIT) && ENABLE(INTERPRETER)
    277         bool m_canUseJIT;
    278 #endif
    279         StackBounds m_stack;
    280     };
    281 
    282     inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData)
    283     {
    284         return globalData.allocateGlobalHandle();
    285     }
    286 
    287 } // namespace JSC
    288 
    289 #endif // JSGlobalData_h
    290