/* * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef JSGlobalData_h #define JSGlobalData_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 #include #include #include #include #include #if ENABLE(REGEXP_TRACING) #include #endif struct OpaqueJSClass; struct OpaqueJSClassContextData; namespace JSC { 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 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 { 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 create(ThreadStackType); static PassRefPtr createLeaked(ThreadStackType); static PassRefPtr createContextGroup(ThreadStackType); ~JSGlobalData(); #if ENABLE(JSC_MULTIPLE_THREADS) // Will start tracking threads that use the heap, which is resource-heavy. void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); } #endif GlobalDataType globalDataType; ClientData* clientData; const HashTable* arrayTable; const HashTable* dateTable; const HashTable* jsonTable; const HashTable* mathTable; const HashTable* numberTable; const HashTable* objectConstructorTable; const HashTable* regExpTable; const HashTable* regExpConstructorTable; const HashTable* stringTable; Strong structureStructure; Strong activationStructure; Strong interruptedExecutionErrorStructure; Strong terminatedExecutionErrorStructure; Strong staticScopeStructure; Strong strictEvalActivationStructure; Strong stringStructure; Strong notAnObjectStructure; Strong propertyNameIteratorStructure; Strong getterSetterStructure; Strong apiWrapperStructure; Strong scopeChainNodeStructure; Strong executableStructure; Strong nativeExecutableStructure; Strong evalExecutableStructure; Strong programExecutableStructure; Strong functionExecutableStructure; Strong dummyMarkableCellStructure; Strong structureChainStructure; #if ENABLE(JSC_ZOMBIES) Strong zombieStructure; #endif 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 (globalDataType == Default) ? m_stack : wtfThreadData().stack(); } Lexer* lexer; Parser* parser; Interpreter* interpreter; #if ENABLE(JIT) OwnPtr 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; #if ENABLE(JIT) ReturnAddressPtr exceptionLocation; #endif HashMap opaqueJSClassData; unsigned globalObjectCount; JSGlobalObject* dynamicGlobalObject; HashSet stringRecursionCheckVisitedObjects; double cachedUTCOffset; DSTOffsetCache dstOffsetCache; UString cachedDateString; double cachedDateStringValue; int maxReentryDepth; RegExpCache* m_regExpCache; BumpPointerAllocator m_regExpAllocator; #if ENABLE(REGEXP_TRACING) typedef ListHashSet > RTTraceList; RTTraceList* m_rtTraceList; #endif #ifndef NDEBUG ThreadIdentifier exclusiveThread; #endif CachedTranscendentalFunction 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); #endif void dumpRegExpTrace(); HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); } HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); } void clearBuiltinStructures(); private: 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