• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
DSTOffsetCacheDSTOffsetCache81         DSTOffsetCache()
82         {
83             reset();
84         }
85 
resetDSTOffsetCache86         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 
isSharedInstance()121         bool isSharedInstance() { return globalDataType == APIShared; }
usingAPI()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.
makeUsableFromMultipleThreads()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)
canUseJIT()192         bool canUseJIT() { return false; } // interpreter only
193 #elif !ENABLE(INTERPRETER)
canUseJIT()194         bool canUseJIT() { return true; } // jit only
195 #else
canUseJIT()196         bool canUseJIT() { return m_canUseJIT; }
197 #endif
198 
stack()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;
getCTIStub(ThunkGenerator generator)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();
regExpCache()263         RegExpCache* regExpCache() { return m_regExpCache; }
264 #if ENABLE(REGEXP_TRACING)
265         void addRegExpToTrace(PassRefPtr<RegExp> regExp);
266 #endif
267         void dumpRegExpTrace();
allocateGlobalHandle()268         HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
allocateLocalHandle()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 
allocateGlobalHandle(JSGlobalData & globalData)282     inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData)
283     {
284         return globalData.allocateGlobalHandle();
285     }
286 
287 } // namespace JSC
288 
289 #endif // JSGlobalData_h
290