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"
33 #include "DFGIntrinsic.h"
34 #include "DateInstanceCache.h"
35 #include "ExecutableAllocator.h"
40 #include "NumericStrings.h"
41 #include "SmallStrings.h"
42 #include "Terminator.h"
43 #include "TimeoutChecker.h"
44 #include "WeakRandom.h"
45 #include <wtf/BumpPointerAllocator.h>
46 #include <wtf/Forward.h>
47 #include <wtf/HashMap.h>
48 #include <wtf/RefCounted.h>
49 #include <wtf/ThreadSpecific.h>
50 #include <wtf/WTFThreadData.h>
51 #if ENABLE(REGEXP_TRACING)
52 #include <wtf/ListHashSet.h>
56 struct OpaqueJSClassContextData;
61 class CommonIdentifiers;
63 class IdentifierTable;
68 class NativeExecutable;
74 #if ENABLE(REGEXP_TRACING)
81 struct DSTOffsetCache {
101 enum ThreadStackType {
102 ThreadStackTypeLarge,
106 struct TypedArrayDescriptor {
107 TypedArrayDescriptor()
113 TypedArrayDescriptor(void* vptr, size_t storageOffset, size_t lengthOffset)
115 , m_storageOffset(storageOffset)
116 , m_lengthOffset(lengthOffset)
120 size_t m_storageOffset;
121 size_t m_lengthOffset;
124 class JSGlobalData : public RefCounted<JSGlobalData> {
126 // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
127 // either create() or createLeaked() should only be called once
128 // on a thread, this is the 'default' JSGlobalData (it uses the
129 // thread's default string uniquing table from wtfThreadData).
130 // API contexts created using the new context group aware interface
131 // create APIContextGroup objects which require less locking of JSC
132 // than the old singleton APIShared JSGlobalData created for use by
134 enum GlobalDataType { Default, APIContextGroup, APIShared };
137 virtual ~ClientData() = 0;
140 bool isSharedInstance() { return globalDataType == APIShared; }
141 bool usingAPI() { return globalDataType != Default; }
142 static bool sharedInstanceExists();
143 static JSGlobalData& sharedInstance();
145 static PassRefPtr<JSGlobalData> create(ThreadStackType, HeapSize = SmallHeap);
146 static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType, HeapSize = SmallHeap);
147 static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType, HeapSize = SmallHeap);
150 void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
152 GlobalDataType globalDataType;
153 ClientData* clientData;
154 CallFrame* topCallFrame;
156 const HashTable* arrayConstructorTable;
157 const HashTable* arrayPrototypeTable;
158 const HashTable* booleanPrototypeTable;
159 const HashTable* dateTable;
160 const HashTable* dateConstructorTable;
161 const HashTable* errorPrototypeTable;
162 const HashTable* globalObjectTable;
163 const HashTable* jsonTable;
164 const HashTable* mathTable;
165 const HashTable* numberConstructorTable;
166 const HashTable* numberPrototypeTable;
167 const HashTable* objectConstructorTable;
168 const HashTable* objectPrototypeTable;
169 const HashTable* regExpTable;
170 const HashTable* regExpConstructorTable;
171 const HashTable* regExpPrototypeTable;
172 const HashTable* stringTable;
173 const HashTable* stringConstructorTable;
175 Strong<Structure> structureStructure;
176 Strong<Structure> debuggerActivationStructure;
177 Strong<Structure> activationStructure;
178 Strong<Structure> interruptedExecutionErrorStructure;
179 Strong<Structure> terminatedExecutionErrorStructure;
180 Strong<Structure> staticScopeStructure;
181 Strong<Structure> strictEvalActivationStructure;
182 Strong<Structure> stringStructure;
183 Strong<Structure> notAnObjectStructure;
184 Strong<Structure> propertyNameIteratorStructure;
185 Strong<Structure> getterSetterStructure;
186 Strong<Structure> apiWrapperStructure;
187 Strong<Structure> scopeChainNodeStructure;
188 Strong<Structure> executableStructure;
189 Strong<Structure> nativeExecutableStructure;
190 Strong<Structure> evalExecutableStructure;
191 Strong<Structure> programExecutableStructure;
192 Strong<Structure> functionExecutableStructure;
193 Strong<Structure> regExpStructure;
194 Strong<Structure> structureChainStructure;
196 static void storeVPtrs();
197 static JS_EXPORTDATA void* jsFinalObjectVPtr;
198 static JS_EXPORTDATA void* jsArrayVPtr;
199 static JS_EXPORTDATA void* jsByteArrayVPtr;
200 static JS_EXPORTDATA void* jsStringVPtr;
201 static JS_EXPORTDATA void* jsFunctionVPtr;
203 IdentifierTable* identifierTable;
204 CommonIdentifiers* propertyNames;
205 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.
206 SmallStrings smallStrings;
207 NumericStrings numericStrings;
208 DateInstanceCache dateInstanceCache;
209 Vector<CodeBlock*> codeBlocksBeingCompiled;
210 void startedCompiling(CodeBlock* codeBlock)
212 codeBlocksBeingCompiled.append(codeBlock);
215 void finishedCompiling(CodeBlock* codeBlock)
217 ASSERT_UNUSED(codeBlock, codeBlock == codeBlocksBeingCompiled.last());
218 codeBlocksBeingCompiled.removeLast();
221 #if ENABLE(ASSEMBLER)
222 ExecutableAllocator executableAllocator;
226 bool canUseJIT() { return false; } // interpreter only
227 #elif !ENABLE(INTERPRETER)
228 bool canUseJIT() { return true; } // jit only
230 bool canUseJIT() { return m_canUseJIT; }
233 const StackBounds& stack()
235 return (globalDataType == Default)
237 : wtfThreadData().stack();
240 OwnPtr<ParserArena> parserArena;
241 OwnPtr<Keywords> keywords;
242 Interpreter* interpreter;
244 OwnPtr<JITThunks> jitStubs;
245 MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
247 return jitStubs->ctiStub(this, generator);
249 NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator, DFG::Intrinsic);
251 NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
253 TimeoutChecker timeoutChecker;
254 Terminator terminator;
259 ReturnAddressPtr exceptionLocation;
260 JSValue hostCallReturnValue;
262 uint32_t osrExitIndex;
263 void* osrExitJumpDestination;
264 Vector<void*> scratchBuffers;
265 size_t sizeOfLastScratchBuffer;
267 void* scratchBufferForSize(size_t size)
272 if (size > sizeOfLastScratchBuffer) {
273 // Protect against a N^2 memory usage pathology by ensuring
274 // that at worst, we get a geometric series, meaning that the
275 // total memory usage is somewhere around
276 // max(scratch buffer size) * 4.
277 sizeOfLastScratchBuffer = size * 2;
279 scratchBuffers.append(fastMalloc(sizeOfLastScratchBuffer));
282 return scratchBuffers.last();
287 HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
289 JSGlobalObject* dynamicGlobalObject;
291 HashSet<JSObject*> stringRecursionCheckVisitedObjects;
293 double cachedUTCOffset;
294 DSTOffsetCache dstOffsetCache;
296 UString cachedDateString;
297 double cachedDateStringValue;
301 RegExpCache* m_regExpCache;
302 BumpPointerAllocator m_regExpAllocator;
304 #if ENABLE(REGEXP_TRACING)
305 typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
306 RTTraceList* m_rtTraceList;
310 ThreadIdentifier exclusiveThread;
313 CachedTranscendentalFunction<sin> cachedSin;
315 void resetDateCache();
317 void startSampling();
319 void dumpSampleData(ExecState* exec);
320 void recompileAllJSFunctions();
321 RegExpCache* regExpCache() { return m_regExpCache; }
322 #if ENABLE(REGEXP_TRACING)
323 void addRegExpToTrace(PassRefPtr<RegExp> regExp);
325 void dumpRegExpTrace();
326 #if ENABLE(TIZEN_JS_EXT_API)
327 int getExecutionState() { return m_executionState; }
328 void setExecutionState(bool b)
332 else if (m_executionState > 0)
336 void clearBuiltinStructures();
338 bool isCollectorBusy() { return heap.isBusy(); }
339 void releaseExecutableMemory();
341 #if ENABLE(GC_VALIDATION)
342 bool isInitializingObject() const;
343 void setInitializingObject(bool);
346 #if CPU(X86) && ENABLE(JIT)
347 unsigned m_timeoutCount;
350 #define registerTypedArrayFunction(type, capitalizedType) \
351 void registerTypedArrayDescriptor(const capitalizedType##Array*, const TypedArrayDescriptor& descriptor) \
353 ASSERT(!m_##type##ArrayDescriptor.m_vptr || m_##type##ArrayDescriptor.m_vptr == descriptor.m_vptr); \
354 m_##type##ArrayDescriptor = descriptor; \
356 registerTypedArrayFunction(int8, Int8);
357 registerTypedArrayFunction(int16, Int16);
358 registerTypedArrayFunction(int32, Int32);
359 registerTypedArrayFunction(uint8, Uint8);
360 registerTypedArrayFunction(uint16, Uint16);
361 registerTypedArrayFunction(uint32, Uint32);
362 registerTypedArrayFunction(float32, Float32);
363 registerTypedArrayFunction(float64, Float64);
364 #undef registerTypedArrayFunction
367 JSGlobalData(GlobalDataType, ThreadStackType, HeapSize);
368 static JSGlobalData*& sharedInstanceInternal();
369 void createNativeThunk();
370 #if ENABLE(JIT) && ENABLE(INTERPRETER)
374 #if ENABLE(GC_VALIDATION)
375 bool m_isInitializingObject;
377 #if ENABLE(TIZEN_JS_EXT_API)
378 /* This is added to inform about the script execution status */
379 int m_executionState;
381 TypedArrayDescriptor m_int8ArrayDescriptor;
382 TypedArrayDescriptor m_int16ArrayDescriptor;
383 TypedArrayDescriptor m_int32ArrayDescriptor;
384 TypedArrayDescriptor m_uint8ArrayDescriptor;
385 TypedArrayDescriptor m_uint16ArrayDescriptor;
386 TypedArrayDescriptor m_uint32ArrayDescriptor;
387 TypedArrayDescriptor m_float32ArrayDescriptor;
388 TypedArrayDescriptor m_float64ArrayDescriptor;
391 #if ENABLE(GC_VALIDATION)
392 inline bool JSGlobalData::isInitializingObject() const
394 return m_isInitializingObject;
397 inline void JSGlobalData::setInitializingObject(bool initializingObject)
399 m_isInitializingObject = initializingObject;
405 #endif // JSGlobalData_h