1 /* 2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 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. 16 * 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. 27 */ 28 29 #ifndef JSGlobalData_h 30 #define JSGlobalData_h 31 32 #include "CachedTranscendentalFunction.h" 33 #include "Heap.h" 34 #include "DateInstanceCache.h" 35 #include "ExecutableAllocator.h" 36 #include "Strong.h" 37 #include "JITStubs.h" 38 #include "JSValue.h" 39 #include "NumericStrings.h" 40 #include "SmallStrings.h" 41 #include "Terminator.h" 42 #include "TimeoutChecker.h" 43 #include "WeakRandom.h" 44 #include <wtf/BumpPointerAllocator.h> 45 #include <wtf/Forward.h> 46 #include <wtf/HashMap.h> 47 #include <wtf/RefCounted.h> 48 #include <wtf/ThreadSpecific.h> 49 #include <wtf/WTFThreadData.h> 50 #if ENABLE(REGEXP_TRACING) 51 #include <wtf/ListHashSet.h> 52 #endif 53 54 struct OpaqueJSClass; 55 struct OpaqueJSClassContextData; 56 57 namespace JSC { 58 59 class CodeBlock; 60 class CommonIdentifiers; 61 class HandleStack; 62 class IdentifierTable; 63 class Interpreter; 64 class JSGlobalObject; 65 class JSObject; 66 class Lexer; 67 class NativeExecutable; 68 class Parser; 69 class RegExpCache; 70 class Stringifier; 71 class Structure; 72 class UString; 73 #if ENABLE(REGEXP_TRACING) 74 class RegExp; 75 #endif 76 77 struct HashTable; 78 struct Instruction; 79 80 struct DSTOffsetCache { DSTOffsetCacheDSTOffsetCache81 DSTOffsetCache() 82 { 83 reset(); 84 } 85 resetDSTOffsetCache86 void reset() 87 { 88 offset = 0.0; 89 start = 0.0; 90 end = -1.0; 91 increment = 0.0; 92 } 93 94 double offset; 95 double start; 96 double end; 97 double increment; 98 }; 99 100 enum ThreadStackType { 101 ThreadStackTypeLarge, 102 ThreadStackTypeSmall 103 }; 104 105 class JSGlobalData : public RefCounted<JSGlobalData> { 106 public: 107 // WebCore has a one-to-one mapping of threads to JSGlobalDatas; 108 // either create() or createLeaked() should only be called once 109 // on a thread, this is the 'default' JSGlobalData (it uses the 110 // thread's default string uniquing table from wtfThreadData). 111 // API contexts created using the new context group aware interface 112 // create APIContextGroup objects which require less locking of JSC 113 // than the old singleton APIShared JSGlobalData created for use by 114 // the original API. 115 enum GlobalDataType { Default, APIContextGroup, APIShared }; 116 117 struct ClientData { 118 virtual ~ClientData() = 0; 119 }; 120 isSharedInstance()121 bool isSharedInstance() { return globalDataType == APIShared; } usingAPI()122 bool usingAPI() { return globalDataType != Default; } 123 static bool sharedInstanceExists(); 124 static JSGlobalData& sharedInstance(); 125 126 static PassRefPtr<JSGlobalData> create(ThreadStackType); 127 static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType); 128 static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType); 129 ~JSGlobalData(); 130 131 #if ENABLE(JSC_MULTIPLE_THREADS) 132 // Will start tracking threads that use the heap, which is resource-heavy. makeUsableFromMultipleThreads()133 void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); } 134 #endif 135 136 GlobalDataType globalDataType; 137 ClientData* clientData; 138 139 const HashTable* arrayTable; 140 const HashTable* dateTable; 141 const HashTable* jsonTable; 142 const HashTable* mathTable; 143 const HashTable* numberTable; 144 const HashTable* objectConstructorTable; 145 const HashTable* regExpTable; 146 const HashTable* regExpConstructorTable; 147 const HashTable* stringTable; 148 149 Strong<Structure> structureStructure; 150 Strong<Structure> activationStructure; 151 Strong<Structure> interruptedExecutionErrorStructure; 152 Strong<Structure> terminatedExecutionErrorStructure; 153 Strong<Structure> staticScopeStructure; 154 Strong<Structure> strictEvalActivationStructure; 155 Strong<Structure> stringStructure; 156 Strong<Structure> notAnObjectStructure; 157 Strong<Structure> propertyNameIteratorStructure; 158 Strong<Structure> getterSetterStructure; 159 Strong<Structure> apiWrapperStructure; 160 Strong<Structure> scopeChainNodeStructure; 161 Strong<Structure> executableStructure; 162 Strong<Structure> nativeExecutableStructure; 163 Strong<Structure> evalExecutableStructure; 164 Strong<Structure> programExecutableStructure; 165 Strong<Structure> functionExecutableStructure; 166 Strong<Structure> dummyMarkableCellStructure; 167 Strong<Structure> structureChainStructure; 168 169 #if ENABLE(JSC_ZOMBIES) 170 Strong<Structure> zombieStructure; 171 #endif 172 173 static void storeVPtrs(); 174 static JS_EXPORTDATA void* jsArrayVPtr; 175 static JS_EXPORTDATA void* jsByteArrayVPtr; 176 static JS_EXPORTDATA void* jsStringVPtr; 177 static JS_EXPORTDATA void* jsFunctionVPtr; 178 179 IdentifierTable* identifierTable; 180 CommonIdentifiers* propertyNames; 181 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. 182 SmallStrings smallStrings; 183 NumericStrings numericStrings; 184 DateInstanceCache dateInstanceCache; 185 186 #if ENABLE(ASSEMBLER) 187 ExecutableAllocator executableAllocator; 188 ExecutableAllocator regexAllocator; 189 #endif 190 191 #if !ENABLE(JIT) canUseJIT()192 bool canUseJIT() { return false; } // interpreter only 193 #elif !ENABLE(INTERPRETER) canUseJIT()194 bool canUseJIT() { return true; } // jit only 195 #else canUseJIT()196 bool canUseJIT() { return m_canUseJIT; } 197 #endif 198 stack()199 const StackBounds& stack() 200 { 201 return (globalDataType == Default) 202 ? m_stack 203 : wtfThreadData().stack(); 204 } 205 206 Lexer* lexer; 207 Parser* parser; 208 Interpreter* interpreter; 209 #if ENABLE(JIT) 210 OwnPtr<JITThunks> jitStubs; getCTIStub(ThunkGenerator generator)211 MacroAssemblerCodePtr getCTIStub(ThunkGenerator generator) 212 { 213 return jitStubs->ctiStub(this, generator); 214 } 215 NativeExecutable* getHostFunction(NativeFunction, ThunkGenerator); 216 #endif 217 NativeExecutable* getHostFunction(NativeFunction); 218 219 TimeoutChecker timeoutChecker; 220 Terminator terminator; 221 Heap heap; 222 223 JSValue exception; 224 #if ENABLE(JIT) 225 ReturnAddressPtr exceptionLocation; 226 #endif 227 228 HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData; 229 230 unsigned globalObjectCount; 231 JSGlobalObject* dynamicGlobalObject; 232 233 HashSet<JSObject*> stringRecursionCheckVisitedObjects; 234 235 double cachedUTCOffset; 236 DSTOffsetCache dstOffsetCache; 237 238 UString cachedDateString; 239 double cachedDateStringValue; 240 241 int maxReentryDepth; 242 243 RegExpCache* m_regExpCache; 244 BumpPointerAllocator m_regExpAllocator; 245 246 #if ENABLE(REGEXP_TRACING) 247 typedef ListHashSet<RefPtr<RegExp> > RTTraceList; 248 RTTraceList* m_rtTraceList; 249 #endif 250 251 #ifndef NDEBUG 252 ThreadIdentifier exclusiveThread; 253 #endif 254 255 CachedTranscendentalFunction<sin> cachedSin; 256 257 void resetDateCache(); 258 259 void startSampling(); 260 void stopSampling(); 261 void dumpSampleData(ExecState* exec); 262 void recompileAllJSFunctions(); regExpCache()263 RegExpCache* regExpCache() { return m_regExpCache; } 264 #if ENABLE(REGEXP_TRACING) 265 void addRegExpToTrace(PassRefPtr<RegExp> regExp); 266 #endif 267 void dumpRegExpTrace(); allocateGlobalHandle()268 HandleSlot allocateGlobalHandle() { return heap.allocateGlobalHandle(); } allocateLocalHandle()269 HandleSlot allocateLocalHandle() { return heap.allocateLocalHandle(); } 270 void clearBuiltinStructures(); 271 272 private: 273 JSGlobalData(GlobalDataType, ThreadStackType); 274 static JSGlobalData*& sharedInstanceInternal(); 275 void createNativeThunk(); 276 #if ENABLE(JIT) && ENABLE(INTERPRETER) 277 bool m_canUseJIT; 278 #endif 279 StackBounds m_stack; 280 }; 281 allocateGlobalHandle(JSGlobalData & globalData)282 inline HandleSlot allocateGlobalHandle(JSGlobalData& globalData) 283 { 284 return globalData.allocateGlobalHandle(); 285 } 286 287 } // namespace JSC 288 289 #endif // JSGlobalData_h 290