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
54struct OpaqueJSClass;
55struct OpaqueJSClassContextData;
56
57namespace 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