JavaScriptCore/runtime/JSGlobalData.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2008 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 #include "config.h"
       
    30 #include "JSGlobalData.h"
       
    31 
       
    32 #include "ArgList.h"
       
    33 #include "Collector.h"
       
    34 #include "CommonIdentifiers.h"
       
    35 #include "FunctionConstructor.h"
       
    36 #include "GetterSetter.h"
       
    37 #include "Interpreter.h"
       
    38 #include "JSActivation.h"
       
    39 #include "JSAPIValueWrapper.h"
       
    40 #include "JSArray.h"
       
    41 #include "JSByteArray.h"
       
    42 #include "JSClassRef.h"
       
    43 #include "JSFunction.h"
       
    44 #include "JSLock.h"
       
    45 #include "JSNotAnObject.h"
       
    46 #include "JSPropertyNameIterator.h"
       
    47 #include "JSStaticScopeObject.h"
       
    48 #include "Lexer.h"
       
    49 #include "Lookup.h"
       
    50 #include "Nodes.h"
       
    51 #include "Parser.h"
       
    52 #include "RegExpCache.h"
       
    53 #include <wtf/WTFThreadData.h>
       
    54 
       
    55 #if ENABLE(JSC_MULTIPLE_THREADS)
       
    56 #include <wtf/Threading.h>
       
    57 #endif
       
    58 
       
    59 #if PLATFORM(MAC)
       
    60 #include "ProfilerServer.h"
       
    61 #include <CoreFoundation/CoreFoundation.h>
       
    62 #endif
       
    63 
       
    64 using namespace WTF;
       
    65 
       
    66 namespace JSC {
       
    67 
       
    68 extern JSC_CONST_HASHTABLE HashTable arrayTable;
       
    69 extern JSC_CONST_HASHTABLE HashTable jsonTable;
       
    70 extern JSC_CONST_HASHTABLE HashTable dateTable;
       
    71 extern JSC_CONST_HASHTABLE HashTable mathTable;
       
    72 extern JSC_CONST_HASHTABLE HashTable numberTable;
       
    73 extern JSC_CONST_HASHTABLE HashTable regExpTable;
       
    74 extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable;
       
    75 extern JSC_CONST_HASHTABLE HashTable stringTable;
       
    76 
       
    77 void* JSGlobalData::jsArrayVPtr;
       
    78 void* JSGlobalData::jsByteArrayVPtr;
       
    79 void* JSGlobalData::jsStringVPtr;
       
    80 void* JSGlobalData::jsFunctionVPtr;
       
    81 
       
    82 void JSGlobalData::storeVPtrs()
       
    83 {
       
    84     CollectorCell cell;
       
    85     void* storage = &cell;
       
    86 
       
    87     COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell);
       
    88     JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
       
    89     JSGlobalData::jsArrayVPtr = jsArray->vptr();
       
    90     jsArray->~JSCell();
       
    91 
       
    92     COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell);
       
    93     JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
       
    94     JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr();
       
    95     jsByteArray->~JSCell();
       
    96 
       
    97     COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell);
       
    98     JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
       
    99     JSGlobalData::jsStringVPtr = jsString->vptr();
       
   100     jsString->~JSCell();
       
   101 
       
   102     COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell);
       
   103     JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
       
   104     JSGlobalData::jsFunctionVPtr = jsFunction->vptr();
       
   105     jsFunction->~JSCell();
       
   106 }
       
   107 
       
   108 JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType)
       
   109     : globalDataType(globalDataType)
       
   110     , clientData(0)
       
   111     , arrayTable(fastNew<HashTable>(JSC::arrayTable))
       
   112     , dateTable(fastNew<HashTable>(JSC::dateTable))
       
   113     , jsonTable(fastNew<HashTable>(JSC::jsonTable))
       
   114     , mathTable(fastNew<HashTable>(JSC::mathTable))
       
   115     , numberTable(fastNew<HashTable>(JSC::numberTable))
       
   116     , regExpTable(fastNew<HashTable>(JSC::regExpTable))
       
   117     , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
       
   118     , stringTable(fastNew<HashTable>(JSC::stringTable))
       
   119     , activationStructure(JSActivation::createStructure(jsNull()))
       
   120     , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
       
   121     , terminatedExecutionErrorStructure(JSObject::createStructure(jsNull()))
       
   122     , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
       
   123     , stringStructure(JSString::createStructure(jsNull()))
       
   124     , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
       
   125     , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
       
   126     , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull()))
       
   127     , getterSetterStructure(GetterSetter::createStructure(jsNull()))
       
   128     , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
       
   129     , dummyMarkableCellStructure(JSCell::createDummyStructure())
       
   130 #if USE(JSVALUE32)
       
   131     , numberStructure(JSNumberCell::createStructure(jsNull()))
       
   132 #endif
       
   133     , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
       
   134     , propertyNames(new CommonIdentifiers(this))
       
   135     , emptyList(new MarkedArgumentBuffer)
       
   136     , lexer(new Lexer(this))
       
   137     , parser(new Parser)
       
   138     , interpreter(new Interpreter)
       
   139     , heap(this)
       
   140     , head(0)
       
   141     , dynamicGlobalObject(0)
       
   142     , functionCodeBlockBeingReparsed(0)
       
   143     , firstStringifierToMark(0)
       
   144     , markStack(jsArrayVPtr)
       
   145     , cachedUTCOffset(NaN)
       
   146     , weakRandom(static_cast<int>(currentTime()))
       
   147     , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
       
   148     , m_regExpCache(new RegExpCache(this))
       
   149 #ifndef NDEBUG
       
   150     , exclusiveThread(0)
       
   151 #endif
       
   152 {
       
   153 #if PLATFORM(MAC)
       
   154     startProfilerServerIfNeeded();
       
   155 #endif
       
   156 #if ENABLE(JIT) && ENABLE(INTERPRETER)
       
   157 #if PLATFORM(CF)
       
   158     CFStringRef canUseJITKey = CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman);
       
   159     CFBooleanRef canUseJIT = (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication);
       
   160     if (canUseJIT) {
       
   161         m_canUseJIT = kCFBooleanTrue == canUseJIT;
       
   162         CFRelease(canUseJIT);
       
   163     } else
       
   164         m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
       
   165     CFRelease(canUseJITKey);
       
   166 #elif OS(UNIX)
       
   167     m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
       
   168 #else
       
   169     m_canUseJIT = true;
       
   170 #endif
       
   171 #endif
       
   172 #if ENABLE(JIT)
       
   173 #if ENABLE(INTERPRETER)
       
   174     if (m_canUseJIT)
       
   175         m_canUseJIT = executableAllocator.isValid();
       
   176 #endif
       
   177     jitStubs = new JITThunks(this);
       
   178 #endif
       
   179 }
       
   180 
       
   181 JSGlobalData::~JSGlobalData()
       
   182 {
       
   183     // By the time this is destroyed, heap.destroy() must already have been called.
       
   184 
       
   185     delete interpreter;
       
   186 #ifndef NDEBUG
       
   187     // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
       
   188     interpreter = 0;
       
   189 #endif
       
   190 
       
   191     arrayTable->deleteTable();
       
   192     dateTable->deleteTable();
       
   193     jsonTable->deleteTable();
       
   194     mathTable->deleteTable();
       
   195     numberTable->deleteTable();
       
   196     regExpTable->deleteTable();
       
   197     regExpConstructorTable->deleteTable();
       
   198     stringTable->deleteTable();
       
   199 
       
   200     fastDelete(const_cast<HashTable*>(arrayTable));
       
   201     fastDelete(const_cast<HashTable*>(dateTable));
       
   202     fastDelete(const_cast<HashTable*>(jsonTable));
       
   203     fastDelete(const_cast<HashTable*>(mathTable));
       
   204     fastDelete(const_cast<HashTable*>(numberTable));
       
   205     fastDelete(const_cast<HashTable*>(regExpTable));
       
   206     fastDelete(const_cast<HashTable*>(regExpConstructorTable));
       
   207     fastDelete(const_cast<HashTable*>(stringTable));
       
   208 
       
   209     delete parser;
       
   210     delete lexer;
       
   211 
       
   212     deleteAllValues(opaqueJSClassData);
       
   213 
       
   214     delete emptyList;
       
   215 
       
   216     delete propertyNames;
       
   217     if (globalDataType != Default)
       
   218         deleteIdentifierTable(identifierTable);
       
   219 
       
   220     delete clientData;
       
   221     delete m_regExpCache;
       
   222 }
       
   223 
       
   224 PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type)
       
   225 {
       
   226     return adoptRef(new JSGlobalData(APIContextGroup, type));
       
   227 }
       
   228 
       
   229 PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
       
   230 {
       
   231     return adoptRef(new JSGlobalData(Default, type));
       
   232 }
       
   233 
       
   234 PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
       
   235 {
       
   236     Structure::startIgnoringLeaks();
       
   237     RefPtr<JSGlobalData> data = create(type);
       
   238     Structure::stopIgnoringLeaks();
       
   239     return data.release();
       
   240 }
       
   241 
       
   242 bool JSGlobalData::sharedInstanceExists()
       
   243 {
       
   244     return sharedInstanceInternal();
       
   245 }
       
   246 
       
   247 JSGlobalData& JSGlobalData::sharedInstance()
       
   248 {
       
   249     JSGlobalData*& instance = sharedInstanceInternal();
       
   250     if (!instance) {
       
   251         instance = adoptRef(new JSGlobalData(APIShared, ThreadStackTypeSmall)).leakRef();
       
   252 #if ENABLE(JSC_MULTIPLE_THREADS)
       
   253         instance->makeUsableFromMultipleThreads();
       
   254 #endif
       
   255     }
       
   256     return *instance;
       
   257 }
       
   258 
       
   259 JSGlobalData*& JSGlobalData::sharedInstanceInternal()
       
   260 {
       
   261     ASSERT(JSLock::currentThreadIsHoldingLock());
       
   262     static JSGlobalData* sharedInstance;
       
   263     return sharedInstance;
       
   264 }
       
   265 
       
   266 #if ENABLE(JIT)
       
   267 PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
       
   268 {
       
   269     return jitStubs->hostFunctionStub(this, function);
       
   270 }
       
   271 PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
       
   272 {
       
   273     return jitStubs->hostFunctionStub(this, function, generator);
       
   274 }
       
   275 #endif
       
   276 
       
   277 JSGlobalData::ClientData::~ClientData()
       
   278 {
       
   279 }
       
   280 
       
   281 void JSGlobalData::resetDateCache()
       
   282 {
       
   283     cachedUTCOffset = NaN;
       
   284     dstOffsetCache.reset();
       
   285     cachedDateString = UString();
       
   286     dateInstanceCache.reset();
       
   287 }
       
   288 
       
   289 void JSGlobalData::startSampling()
       
   290 {
       
   291     interpreter->startSampling();
       
   292 }
       
   293 
       
   294 void JSGlobalData::stopSampling()
       
   295 {
       
   296     interpreter->stopSampling();
       
   297 }
       
   298 
       
   299 void JSGlobalData::dumpSampleData(ExecState* exec)
       
   300 {
       
   301     interpreter->dumpSampleData(exec);
       
   302 }
       
   303 
       
   304 } // namespace JSC