2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #ifndef JSGlobalData_h
30 #define JSGlobalData_h
32 #include "CachedTranscendentalFunction.h"
34 #include "DateInstanceCache.h"
35 #include "ExecutableAllocator.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>
55 struct OpaqueJSClassContextData;
60 class CommonIdentifiers;
62 class IdentifierTable;
67 class NativeExecutable;
73 #if ENABLE(REGEXP_TRACING)
80 struct DSTOffsetCache {
100 enum ThreadStackType {
101 ThreadStackTypeLarge,
105 class JSGlobalData : public RefCounted<JSGlobalData> {
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
115 enum GlobalDataType { Default, APIContextGroup, APIShared };
118 virtual ~ClientData() = 0;
121 bool isSharedInstance() { return globalDataType == APIShared; }
122 bool usingAPI() { return globalDataType != Default; }
123 static bool sharedInstanceExists();
124 static JSGlobalData& sharedInstance();
126 static PassRefPtr<JSGlobalData> create(ThreadStackType, HeapSize = SmallHeap);
127 static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType, HeapSize = SmallHeap);
128 static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType, HeapSize = SmallHeap);
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(); }
136 GlobalDataType globalDataType;
137 ClientData* clientData;
138 CallFrame* topCallFrame;
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;
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;
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;
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;
194 #if ENABLE(ASSEMBLER)
195 ExecutableAllocator executableAllocator;
199 bool canUseJIT() { return false; } // interpreter only
200 #elif !ENABLE(INTERPRETER)
201 bool canUseJIT() { return true; } // jit only
203 bool canUseJIT() { return m_canUseJIT; }
206 const StackBounds& stack()
208 return (globalDataType == Default)
210 : wtfThreadData().stack();
215 Interpreter* interpreter;
217 OwnPtr<JITThunks> jitStubs;
218 MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
220 return jitStubs->ctiStub(this, generator);
222 NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator);
224 NativeExecutable* getHostFunction(NativeFunction);
226 TimeoutChecker timeoutChecker;
227 Terminator terminator;
232 ReturnAddressPtr exceptionLocation;
233 JSValue hostCallReturnValue;
235 int64_t debugDataBuffer[64];
237 #if ENABLE(TIERED_COMPILATION)
238 Vector<void*> osrScratchBuffers;
239 size_t sizeOfLastOSRScratchBuffer;
241 void* osrScratchBufferForSize(size_t size)
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;
253 osrScratchBuffers.append(fastMalloc(sizeOfLastOSRScratchBuffer));
256 return osrScratchBuffers.last();
261 HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
263 JSGlobalObject* dynamicGlobalObject;
265 HashSet<JSObject*> stringRecursionCheckVisitedObjects;
267 double cachedUTCOffset;
268 DSTOffsetCache dstOffsetCache;
270 UString cachedDateString;
271 double cachedDateStringValue;
275 RegExpCache* m_regExpCache;
276 BumpPointerAllocator m_regExpAllocator;
278 #if ENABLE(REGEXP_TRACING)
279 typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
280 RTTraceList* m_rtTraceList;
284 ThreadIdentifier exclusiveThread;
287 CachedTranscendentalFunction<sin> cachedSin;
289 void resetDateCache();
291 void startSampling();
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);
299 void dumpRegExpTrace();
300 HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
301 HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
302 void clearBuiltinStructures();
304 bool isCollectorBusy() { return heap.isBusy(); }
305 void releaseExecutableMemory();
307 #if ENABLE(GC_VALIDATION)
308 bool isInitializingObject() const;
309 void setInitializingObject(bool);
313 JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
314 static JSGlobalData*& sharedInstanceInternal();
315 void createNativeThunk();
316 #if ENABLE(JIT) && ENABLE(INTERPRETER)
320 #if ENABLE(GC_VALIDATION)
321 bool m_isInitializingObject;
325 inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData)
327 return globalData.allocateGlobalHandle();
330 #if ENABLE(GC_VALIDATION)
331 inline bool JSGlobalData::isInitializingObject() const
333 return m_isInitializingObject;
336 inline void JSGlobalData::setInitializingObject(bool initializingObject)
338 m_isInitializingObject = initializingObject;
344 #endif // JSGlobalData_h