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