diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/JavaScriptCore/runtime/JSGlobalData.h | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSGlobalData.h')
-rw-r--r-- | Source/JavaScriptCore/runtime/JSGlobalData.h | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h new file mode 100644 index 000000000..1619f9297 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSGlobalData.h @@ -0,0 +1,386 @@ +/* + * 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 "Intrinsic.h" +#include "DateInstanceCache.h" +#include "ExecutableAllocator.h" +#include "Heap.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 HandleStack; + class IdentifierTable; + class Interpreter; + class JSGlobalObject; + class JSObject; + class Keywords; + class NativeExecutable; + class ParserArena; + 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 + }; + + struct TypedArrayDescriptor { + TypedArrayDescriptor() + : m_classInfo(0) + , m_storageOffset(0) + , m_lengthOffset(0) + { + } + TypedArrayDescriptor(const ClassInfo* classInfo, size_t storageOffset, size_t lengthOffset) + : m_classInfo(classInfo) + , m_storageOffset(storageOffset) + , m_lengthOffset(lengthOffset) + { + } + const ClassInfo* m_classInfo; + size_t m_storageOffset; + size_t m_lengthOffset; + }; + + 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(ThreadStackType, HeapSize = SmallHeap); + static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType, HeapSize = SmallHeap); + static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType, HeapSize = SmallHeap); + ~JSGlobalData(); + + void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); } + + GlobalDataType globalDataType; + ClientData* clientData; + CallFrame* topCallFrame; + + 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* 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; + + 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> regExpStructure; + Strong<Structure> structureChainStructure; + + 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; + Vector<CodeBlock*> codeBlocksBeingCompiled; + void startedCompiling(CodeBlock* codeBlock) + { + codeBlocksBeingCompiled.append(codeBlock); + } + + void finishedCompiling(CodeBlock* codeBlock) + { + ASSERT_UNUSED(codeBlock, codeBlock == codeBlocksBeingCompiled.last()); + codeBlocksBeingCompiled.removeLast(); + } + +#if ENABLE(ASSEMBLER) + ExecutableAllocator executableAllocator; +#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(); + } + + OwnPtr<ParserArena> parserArena; + OwnPtr<Keywords> keywords; + Interpreter* interpreter; +#if ENABLE(JIT) + OwnPtr<JITThunks> jitStubs; + MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator) + { + return jitStubs->ctiStub(this, generator); + } + NativeExecutable* getHostFunction(NativeFunction, Intrinsic); +#endif + NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor); + + TimeoutChecker timeoutChecker; + Terminator terminator; + Heap heap; + + JSValue exception; +#if ENABLE(JIT) + ReturnAddressPtr exceptionLocation; + JSValue hostCallReturnValue; +#if ENABLE(DFG_JIT) + uint32_t osrExitIndex; + void* osrExitJumpDestination; + Vector<void*> scratchBuffers; + size_t sizeOfLastScratchBuffer; + + void* scratchBufferForSize(size_t size) + { + if (!size) + return 0; + + if (size > sizeOfLastScratchBuffer) { + // Protect against a N^2 memory usage pathology by ensuring + // that at worst, we get a geometric series, meaning that the + // total memory usage is somewhere around + // max(scratch buffer size) * 4. + sizeOfLastScratchBuffer = size * 2; + + scratchBuffers.append(fastMalloc(sizeOfLastScratchBuffer)); + } + + return scratchBuffers.last(); + } +#endif +#endif + + HashMap<OpaqueJSClass*, OwnPtr<OpaqueJSClassContextData> > opaqueJSClassData; + + JSGlobalObject* dynamicGlobalObject; + + HashSet<JSObject*> stringRecursionCheckVisitedObjects; + + double cachedUTCOffset; + DSTOffsetCache dstOffsetCache; + + UString cachedDateString; + double cachedDateStringValue; + + int maxReentryDepth; + + 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(); + void clearBuiltinStructures(); + + bool isCollectorBusy() { return heap.isBusy(); } + void releaseExecutableMemory(); + +#if ENABLE(GC_VALIDATION) + bool isInitializingObject() const; + void setInitializingObject(bool); +#endif + +#if CPU(X86) && ENABLE(JIT) + unsigned m_timeoutCount; +#endif + +#define registerTypedArrayFunction(type, capitalizedType) \ + void registerTypedArrayDescriptor(const capitalizedType##Array*, const TypedArrayDescriptor& descriptor) \ + { \ + ASSERT(!m_##type##ArrayDescriptor.m_classInfo || m_##type##ArrayDescriptor.m_classInfo == descriptor.m_classInfo); \ + m_##type##ArrayDescriptor = descriptor; \ + } \ + const TypedArrayDescriptor& type##ArrayDescriptor() const { return m_##type##ArrayDescriptor; } + + registerTypedArrayFunction(int8, Int8); + registerTypedArrayFunction(int16, Int16); + registerTypedArrayFunction(int32, Int32); + registerTypedArrayFunction(uint8, Uint8); + registerTypedArrayFunction(uint16, Uint16); + registerTypedArrayFunction(uint32, Uint32); + registerTypedArrayFunction(float32, Float32); + registerTypedArrayFunction(float64, Float64); +#undef registerTypedArrayFunction + + private: + JSGlobalData(GlobalDataType, ThreadStackType, HeapSize); + static JSGlobalData*& sharedInstanceInternal(); + void createNativeThunk(); +#if ENABLE(JIT) && ENABLE(INTERPRETER) + bool m_canUseJIT; +#endif + StackBounds m_stack; +#if ENABLE(GC_VALIDATION) + bool m_isInitializingObject; +#endif + TypedArrayDescriptor m_int8ArrayDescriptor; + TypedArrayDescriptor m_int16ArrayDescriptor; + TypedArrayDescriptor m_int32ArrayDescriptor; + TypedArrayDescriptor m_uint8ArrayDescriptor; + TypedArrayDescriptor m_uint16ArrayDescriptor; + TypedArrayDescriptor m_uint32ArrayDescriptor; + TypedArrayDescriptor m_float32ArrayDescriptor; + TypedArrayDescriptor m_float64ArrayDescriptor; + }; + +#if ENABLE(GC_VALIDATION) + inline bool JSGlobalData::isInitializingObject() const + { + return m_isInitializingObject; + } + + inline void JSGlobalData::setInitializingObject(bool initializingObject) + { + m_isInitializingObject = initializingObject; + } +#endif + +} // namespace JSC + +#endif // JSGlobalData_h |