#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 "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;
namespace JSC {
+ class CodeBlock;
class CommonIdentifiers;
- class FunctionBodyNode;
+ class HandleStack;
class IdentifierTable;
- class Instruction;
class Interpreter;
class JSGlobalObject;
class JSObject;
class Lexer;
+ class NativeExecutable;
class Parser;
- class ScopeNode;
+ class RegExpCache;
class Stringifier;
class Structure;
class UString;
+#if ENABLE(REGEXP_TRACING)
+ class RegExp;
+#endif
struct HashTable;
- struct VPtrSet;
+ struct Instruction;
+
+ struct DSTOffsetCache {
+ DSTOffsetCache()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ offset = 0.0;
+ start = 0.0;
+ end = -1.0;
+ increment = 0.0;
+ }
+
+ double offset;
+ double start;
+ double end;
+ 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(bool isShared = false);
- static PassRefPtr<JSGlobalData> createLeaked();
+ 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;
-#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
- void* jsArrayVPtr;
- void* jsByteArrayVPtr;
- void* jsStringVPtr;
- void* jsFunctionVPtr;
+ static void storeVPtrs();
+ static JS_EXPORTDATA void* jsArrayVPtr;
+ static JS_EXPORTDATA void* jsByteArrayVPtr;
+ static JS_EXPORTDATA void* jsStringVPtr;
+ static JS_EXPORTDATA void* jsFunctionVPtr;
IdentifierTable* identifierTable;
CommonIdentifiers* propertyNames;
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.
SmallStrings smallStrings;
-
+ NumericStrings numericStrings;
+ DateInstanceCache dateInstanceCache;
+
#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;
+ HashSet<JSObject*> stringRecursionCheckVisitedObjects;
+
+ double cachedUTCOffset;
+ DSTOffsetCache dstOffsetCache;
+
+ UString cachedDateString;
+ double cachedDateStringValue;
+
+ int maxReentryDepth;
- ScopeNode* scopeNodeBeingReparsed;
- Stringifier* firstStringifierToMark;
+ RegExpCache* m_regExpCache;
+ BumpPointerAllocator m_regExpAllocator;
+
+#if ENABLE(REGEXP_TRACING)
+ typedef ListHashSet<RefPtr<RegExp> > RTTraceList;
+ RTTraceList* m_rtTraceList;
+#endif
+
+#ifndef NDEBUG
+ 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, const VPtrSet&);
+ 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