initial import
[vuplus_webkit] / Source / JavaScriptCore / runtime / JSGlobalData.h
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, HeapSize = SmallHeap);
127         static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType, HeapSize = SmallHeap);
128         static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType, HeapSize = SmallHeap);
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         CallFrame* topCallFrame;
139
140         const HashTable* arrayConstructorTable;
141         const HashTable* arrayPrototypeTable;
142         const HashTable* booleanPrototypeTable;
143         const HashTable* dateTable;
144         const HashTable* dateConstructorTable;
145         const HashTable* errorPrototypeTable;
146         const HashTable* globalObjectTable;
147         const HashTable* jsonTable;
148         const HashTable* mathTable;
149         const HashTable* numberConstructorTable;
150         const HashTable* numberPrototypeTable;
151         const HashTable* objectConstructorTable;
152         const HashTable* objectPrototypeTable;
153         const HashTable* regExpTable;
154         const HashTable* regExpConstructorTable;
155         const HashTable* regExpPrototypeTable;
156         const HashTable* stringTable;
157         const HashTable* stringConstructorTable;
158         
159         Strong<Structure> structureStructure;
160         Strong<Structure> debuggerActivationStructure;
161         Strong<Structure> activationStructure;
162         Strong<Structure> interruptedExecutionErrorStructure;
163         Strong<Structure> terminatedExecutionErrorStructure;
164         Strong<Structure> staticScopeStructure;
165         Strong<Structure> strictEvalActivationStructure;
166         Strong<Structure> stringStructure;
167         Strong<Structure> notAnObjectStructure;
168         Strong<Structure> propertyNameIteratorStructure;
169         Strong<Structure> getterSetterStructure;
170         Strong<Structure> apiWrapperStructure;
171         Strong<Structure> scopeChainNodeStructure;
172         Strong<Structure> executableStructure;
173         Strong<Structure> nativeExecutableStructure;
174         Strong<Structure> evalExecutableStructure;
175         Strong<Structure> programExecutableStructure;
176         Strong<Structure> functionExecutableStructure;
177         Strong<Structure> regExpStructure;
178         Strong<Structure> structureChainStructure;
179
180         static void storeVPtrs();
181         static JS_EXPORTDATA void* jsFinalObjectVPtr;
182         static JS_EXPORTDATA void* jsArrayVPtr;
183         static JS_EXPORTDATA void* jsByteArrayVPtr;
184         static JS_EXPORTDATA void* jsStringVPtr;
185         static JS_EXPORTDATA void* jsFunctionVPtr;
186
187         IdentifierTable* identifierTable;
188         CommonIdentifiers* propertyNames;
189         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.
190         SmallStrings smallStrings;
191         NumericStrings numericStrings;
192         DateInstanceCache dateInstanceCache;
193         
194 #if ENABLE(ASSEMBLER)
195         ExecutableAllocator executableAllocator;
196 #endif
197
198 #if !ENABLE(JIT)
199         bool canUseJIT() { return false; } // interpreter only
200 #elif !ENABLE(INTERPRETER)
201         bool canUseJIT() { return true; } // jit only
202 #else
203         bool canUseJIT() { return m_canUseJIT; }
204 #endif
205
206         const StackBounds& stack()
207         {
208             return (globalDataType == Default)
209                 ? m_stack
210                 : wtfThreadData().stack();
211         }
212
213         Lexer* lexer;
214         Parser* parser;
215         Interpreter* interpreter;
216 #if ENABLE(JIT)
217         OwnPtr<JITThunks> jitStubs;
218         MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
219         {
220             return jitStubs->ctiStub(this, generator);
221         }
222         NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator);
223 #endif
224         NativeExecutable* getHostFunction(NativeFunction);
225
226         TimeoutChecker timeoutChecker;
227         Terminator terminator;
228         Heap heap;
229
230         JSValue exception;
231 #if ENABLE(JIT)
232         ReturnAddressPtr exceptionLocation;
233         JSValue hostCallReturnValue;
234 #ifndef NDEBUG
235         int64_t debugDataBuffer[64];
236 #endif
237 #if ENABLE(TIERED_COMPILATION)
238         Vector<void*> osrScratchBuffers;
239         size_t sizeOfLastOSRScratchBuffer;
240         
241         void* osrScratchBufferForSize(size_t size)
242         {
243             if (!size)
244                 return 0;
245             
246             if (size > sizeOfLastOSRScratchBuffer) {
247                 // Protect against a N^2 memory usage pathology by ensuring
248                 // that at worst, we get a geometric series, meaning that the
249                 // total memory usage is somewhere around
250                 // max(scratch buffer size) * 4.
251                 sizeOfLastOSRScratchBuffer = size * 2;
252                 
253                 osrScratchBuffers.append(fastMalloc(sizeOfLastOSRScratchBuffer));
254             }
255             
256             return osrScratchBuffers.last();
257         }
258 #endif
259 #endif
260
261         HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
262
263         JSGlobalObject* dynamicGlobalObject;
264
265         HashSet<JSObject*> stringRecursionCheckVisitedObjects;
266
267         double cachedUTCOffset;
268         DSTOffsetCache dstOffsetCache;
269         
270         UString cachedDateString;
271         double cachedDateStringValue;
272
273         int maxReentryDepth;
274
275         RegExpCache* m_regExpCache;
276         BumpPointerAllocator m_regExpAllocator;
277
278 #if ENABLE(REGEXP_TRACING)
279         typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
280         RTTraceList* m_rtTraceList;
281 #endif
282
283 #ifndef NDEBUG
284         ThreadIdentifier exclusiveThread;
285 #endif
286
287         CachedTranscendentalFunction<sin> cachedSin;
288
289         void resetDateCache();
290
291         void startSampling();
292         void stopSampling();
293         void dumpSampleData(ExecState* exec);
294         void recompileAllJSFunctions();
295         RegExpCache* regExpCache() { return m_regExpCache; }
296 #if ENABLE(REGEXP_TRACING)
297         void addRegExpToTrace(PassRefPtr<RegExp> regExp);
298 #endif
299         void dumpRegExpTrace();
300         HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
301         HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
302         void clearBuiltinStructures();
303
304         bool isCollectorBusy() { return heap.isBusy(); }
305         void releaseExecutableMemory();
306
307 #if ENABLE(GC_VALIDATION)
308         bool isInitializingObject() const; 
309         void setInitializingObject(bool);
310 #endif
311
312     private:
313         JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
314         static JSGlobalData*& sharedInstanceInternal();
315         void createNativeThunk();
316 #if ENABLE(JIT) && ENABLE(INTERPRETER)
317         bool m_canUseJIT;
318 #endif
319         StackBounds m_stack;
320 #if ENABLE(GC_VALIDATION)
321         bool m_isInitializingObject;
322 #endif
323     };
324
325     inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData)
326     {
327         return globalData.allocateGlobalHandle();
328     }
329
330 #if ENABLE(GC_VALIDATION)
331     inline bool JSGlobalData::isInitializingObject() const
332     {
333         return m_isInitializingObject;
334     }
335
336     inline void JSGlobalData::setInitializingObject(bool initializingObject)
337     {
338         m_isInitializingObject = initializingObject;
339     }
340 #endif
341
342 } // namespace JSC
343
344 #endif // JSGlobalData_h