#ifndef JSGlobalData_h
#define JSGlobalData_h
-#include "Collector.h"
+#include "CachedTranscendentalFunction.h"
+#include "Heap.h"
#include "DateInstanceCache.h"
#include "ExecutableAllocator.h"
+#include "Strong.h"
#include "JITStubs.h"
#include "JSValue.h"
-#include "MarkStack.h"
#include "NumericStrings.h"
#include "SmallStrings.h"
+#include "Terminator.h"
#include "TimeoutChecker.h"
#include "WeakRandom.h"
+#include <wtf/BumpPointerAllocator.h>
#include <wtf/Forward.h>
#include <wtf/HashMap.h>
#include <wtf/RefCounted.h>
+#include <wtf/ThreadSpecific.h>
+#include <wtf/WTFThreadData.h>
+#if ENABLE(REGEXP_TRACING)
+#include <wtf/ListHashSet.h>
+#endif
struct OpaqueJSClass;
struct OpaqueJSClassContextData;
class CodeBlock;
class CommonIdentifiers;
+ class HandleStack;
class IdentifierTable;
class Interpreter;
class JSGlobalObject;
class JSObject;
class Lexer;
+ class NativeExecutable;
class Parser;
+ class RegExpCache;
class Stringifier;
class Structure;
class UString;
+#if ENABLE(REGEXP_TRACING)
+ class RegExp;
+#endif
struct HashTable;
- struct Instruction;
+ struct Instruction;
struct DSTOffsetCache {
DSTOffsetCache()
double increment;
};
+ enum ThreadStackType {
+ ThreadStackTypeLarge,
+ ThreadStackTypeSmall
+ };
+
class JSGlobalData : public RefCounted<JSGlobalData> {
public:
+ // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
+ // either create() or createLeaked() should only be called once
+ // on a thread, this is the 'default' JSGlobalData (it uses the
+ // thread's default string uniquing table from wtfThreadData).
+ // API contexts created using the new context group aware interface
+ // create APIContextGroup objects which require less locking of JSC
+ // than the old singleton APIShared JSGlobalData created for use by
+ // the original API.
+ enum GlobalDataType { Default, APIContextGroup, APIShared };
+
struct ClientData {
virtual ~ClientData() = 0;
};
+ bool isSharedInstance() { return globalDataType == APIShared; }
+ bool usingAPI() { return globalDataType != Default; }
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
- static PassRefPtr<JSGlobalData> create();
- static PassRefPtr<JSGlobalData> createLeaked();
- static PassRefPtr<JSGlobalData> createNonDefault();
+ static PassRefPtr<JSGlobalData> create(ThreadStackType);
+ static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType);
+ static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType);
~JSGlobalData();
#if ENABLE(JSC_MULTIPLE_THREADS)
// Will start tracking threads that use the heap, which is resource-heavy.
- void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
+ void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
#endif
- bool isSharedInstance;
+ GlobalDataType globalDataType;
ClientData* clientData;
- const HashTable* arrayTable;
+ const HashTable* arrayConstructorTable;
+ const HashTable* arrayPrototypeTable;
+ const HashTable* booleanPrototypeTable;
const HashTable* dateTable;
+ const HashTable* dateConstructorTable;
+ const HashTable* errorPrototypeTable;
+ const HashTable* globalObjectTable;
const HashTable* jsonTable;
const HashTable* mathTable;
- const HashTable* numberTable;
+ const HashTable* numberConstructorTable;
+ const HashTable* numberPrototypeTable;
+ const HashTable* objectConstructorTable;
+ const HashTable* objectPrototypeTable;
const HashTable* regExpTable;
const HashTable* regExpConstructorTable;
+ const HashTable* regExpPrototypeTable;
const HashTable* stringTable;
+ const HashTable* stringConstructorTable;
- RefPtr<Structure> activationStructure;
- RefPtr<Structure> interruptedExecutionErrorStructure;
- RefPtr<Structure> staticScopeStructure;
- RefPtr<Structure> stringStructure;
- RefPtr<Structure> notAnObjectErrorStubStructure;
- RefPtr<Structure> notAnObjectStructure;
- RefPtr<Structure> propertyNameIteratorStructure;
- RefPtr<Structure> getterSetterStructure;
- RefPtr<Structure> apiWrapperStructure;
- RefPtr<Structure> dummyMarkableCellStructure;
-
-#if USE(JSVALUE32)
- RefPtr<Structure> numberStructure;
+ Strong<Structure> structureStructure;
+ Strong<Structure> debuggerActivationStructure;
+ Strong<Structure> activationStructure;
+ Strong<Structure> interruptedExecutionErrorStructure;
+ Strong<Structure> terminatedExecutionErrorStructure;
+ Strong<Structure> staticScopeStructure;
+ Strong<Structure> strictEvalActivationStructure;
+ Strong<Structure> stringStructure;
+ Strong<Structure> notAnObjectStructure;
+ Strong<Structure> propertyNameIteratorStructure;
+ Strong<Structure> getterSetterStructure;
+ Strong<Structure> apiWrapperStructure;
+ Strong<Structure> scopeChainNodeStructure;
+ Strong<Structure> executableStructure;
+ Strong<Structure> nativeExecutableStructure;
+ Strong<Structure> evalExecutableStructure;
+ Strong<Structure> programExecutableStructure;
+ Strong<Structure> functionExecutableStructure;
+ Strong<Structure> dummyMarkableCellStructure;
+ Strong<Structure> regExpStructure;
+ Strong<Structure> structureChainStructure;
+
+#if ENABLE(JSC_ZOMBIES)
+ Strong<Structure> zombieStructure;
#endif
static void storeVPtrs();
#if ENABLE(ASSEMBLER)
ExecutableAllocator executableAllocator;
+ ExecutableAllocator regexAllocator;
+#endif
+
+#if !ENABLE(JIT)
+ bool canUseJIT() { return false; } // interpreter only
+#elif !ENABLE(INTERPRETER)
+ bool canUseJIT() { return true; } // jit only
+#else
+ bool canUseJIT() { return m_canUseJIT; }
#endif
+ const StackBounds& stack()
+ {
+ return wtfThreadData().stack();
+ }
+
Lexer* lexer;
Parser* parser;
Interpreter* interpreter;
#if ENABLE(JIT)
- JITThunks jitStubs;
+ OwnPtr<JITThunks> jitStubs;
+ MacroAssemblerCodePtr getCTIStub(ThunkGenerator generator)
+ {
+ return jitStubs->ctiStub(this, generator);
+ }
+ NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator);
#endif
+ NativeExecutable* getHostFunction(NativeFunction);
+
TimeoutChecker timeoutChecker;
+ Terminator terminator;
Heap heap;
JSValue exception;
ReturnAddressPtr exceptionLocation;
#endif
- const Vector<Instruction>& numericCompareFunction(ExecState*);
- Vector<Instruction> lazyNumericCompareFunction;
- bool initializingLazyNumericCompareFunction;
-
HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
- JSGlobalObject* head;
+ unsigned globalObjectCount;
JSGlobalObject* dynamicGlobalObject;
- HashSet<JSObject*> arrayVisitedElements;
-
- CodeBlock* functionCodeBlockBeingReparsed;
- Stringifier* firstStringifierToMark;
-
- MarkStack markStack;
+ HashSet<JSObject*> stringRecursionCheckVisitedObjects;
double cachedUTCOffset;
DSTOffsetCache dstOffsetCache;
UString cachedDateString;
double cachedDateStringValue;
-
- WeakRandom weakRandom;
+
+ int maxReentryDepth;
+
+ RegExpCache* m_regExpCache;
+ BumpPointerAllocator m_regExpAllocator;
+
+#if ENABLE(REGEXP_TRACING)
+ typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
+ RTTraceList* m_rtTraceList;
+#endif
#ifndef NDEBUG
- bool mainThreadOnly;
+ ThreadIdentifier exclusiveThread;
#endif
+ CachedTranscendentalFunction<sin> cachedSin;
+
void resetDateCache();
void startSampling();
void stopSampling();
void dumpSampleData(ExecState* exec);
+ void recompileAllJSFunctions();
+ RegExpCache* regExpCache() { return m_regExpCache; }
+#if ENABLE(REGEXP_TRACING)
+ void addRegExpToTrace(PassRefPtr<RegExp> regExp);
+#endif
+ void dumpRegExpTrace();
+ HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); }
+ HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); }
+ void clearBuiltinStructures();
+
+ bool isCollectorBusy() { return heap.isBusy(); }
+ void releaseExecutableMemory();
+
private:
- JSGlobalData(bool isShared);
+ JSGlobalData(GlobalDataType, ThreadStackType);
static JSGlobalData*& sharedInstanceInternal();
void createNativeThunk();
+#if ENABLE(JIT) && ENABLE(INTERPRETER)
+ bool m_canUseJIT;
+#endif
+ StackBounds m_stack;
};
-
+
+ inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData)
+ {
+ return globalData.allocateGlobalHandle();
+ }
+
} // namespace JSC
#endif // JSGlobalData_h