Changeset 115579 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Apr 28, 2012, 1:51:27 PM (13 years ago)
Author:
[email protected]
Message:

Clarified JSGlobalData (JavaScript VM) lifetime
https://bugs.webkit.org/show_bug.cgi?id=85142

Reviewed by Anders Carlsson.

Source/JavaScriptCore:

This was so confusing that I didn't feel like I could reason about
memory lifetime in the heap without fixing it.

The rules are:

(1) JSGlobalData owns the virtual machine and all memory in it.

(2) Deleting a JSGlobalData frees the virtual machine and all memory
in it.

(Caveat emptor: if you delete the virtual machine while you're running
JIT code or accessing GC objects, you're gonna have a bad time.)

(I opted not to make arbitrary sub-objects keep the virtual machine
alive automatically because:

(a) doing that right would be complex and slow;

(b) in the case of an exiting thread or process, there's no
clear way to give the garbage collector a chance to try again
later;

(c) continuing to run the garbage collector after we've been
asked to shut down the virtual machine seems rude;

(d) we've never really supported that feature, anyway.)

(3) Normal ref-counting will do. No need to call a battery of
specialty functions to tear down a JSGlobalData. Its foibles
notwithstanding, C++ does in fact know how to execute destructors in
order.

  • API/JSContextRef.cpp:

(JSGlobalContextCreate): Removed compatibility shim for older
operating systems because it's no longer used.

(JSGlobalContextRelease): Now that we can rely on JSGlobalData to "do
the right thing", this code is much simpler. We still have one special
case to notify the garbage collector if we're removing the last
reference to the global object, since this can improve memory behavior.

  • heap/CopiedSpace.cpp:

(JSC::CopiedSpace::freeAllBlocks):

  • heap/CopiedSpace.h:

(CopiedSpace): Renamed "destroy" => "freeAllBlocks" because true
destruction-time behaviors should be limited to our C++ destructor.

  • heap/Heap.cpp:

(JSC::Heap::~Heap):
(JSC):
(JSC::Heap::lastChanceToFinalize):

  • heap/Heap.h:

(Heap):
(JSC::Heap::heap): Renamed "destroy" => "lastChanceToFinalize" because
true destruction-time behaviors should be limited to our C++
destructor.

Reorganized the code, putting code that must run before any objects
get torn down into lastChanceToFinalize, and code that just tears down
objects into our destructor.

  • heap/Local.h:

(JSC::LocalStack::LocalStack):
(JSC::LocalStack::push):
(LocalStack): See rule (2).

  • jsc.cpp:

(functionQuit):
(main):
(printUsageStatement):
(parseArguments):
(jscmain):

  • testRegExp.cpp:

(main):
(printUsageStatement):
(parseArguments):
(realMain): See rule (3).

I removed the feature of ensuring orderly tear-down when calling quit()
or running in --help mode because it didn't seem very useful and
making it work with Windows structured exception handling and
NO_RETURN didn't seem like a fun way to spend a Saturday.

  • runtime/JSGlobalData.h:
  • runtime/JSGlobalData.cpp:

(JSC::JSGlobalData::JSGlobalData): Moved heap to be the first data
member in JSGlobalData to ensure that it's destructed last, so other
objects that reference it destruct without crashing. This allowed me
to remove clearBuiltinStructures() altogether, and helped guarantee
rule (3).

(JSC::JSGlobalData::~JSGlobalData): Explicitly call
lastChanceToFinalize() at the head of our destructor to ensure that
all pending finalizers run while the virtual machine is still in a
valid state. Trying to resurrect (re-ref) the virtual machine at this
point is not valid, but all other operations are.

Changed a null to a 0xbbadbeef to clarify just how bad this beef is.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/JSGlobalObject.h:

(JSGlobalObject):
(JSC::JSGlobalObject::globalData): See rule (3).

Source/WebCore:

  • bindings/js/WorkerScriptController.cpp:

(WebCore::WorkerScriptController::~WorkerScriptController): Slightly
simpler than before. We can't just rely on our default destructor
because we need to hold the JSLock when we tear down the VM.

  • bridge/NP_jsobject.cpp:

(_NPN_InvokeDefault):
(_NPN_Invoke):
(_NPN_Evaluate):
(_NPN_Construct): Don't RefPtr<> the JSGlobalData because it makes it
seem like you know something the rest of our code doesn't know. The
plugin JSGlobalData is immortal, anyway.

I also removed some timeout checker related code because that feature
doesn't work anymore, so it was effectively dead code.

Source/WebKit/mac:

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm:

(WebKit::NetscapePluginInstanceProxy::invoke):
(WebKit::NetscapePluginInstanceProxy::invokeDefault):
(WebKit::NetscapePluginInstanceProxy::construct):

Location:
trunk/Source/JavaScriptCore
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSContextRef.cpp

    r115156 r115579  
    3939#include <wtf/text/StringHash.h>
    4040
    41 
    42 #if OS(DARWIN)
    43 #include <mach-o/dyld.h>
    44 
    45 static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; // 528.5.0
    46 #endif
    47 
    4841using namespace JSC;
     42
     43// From the API's perspective, a context group remains alive iff
     44//     (a) it has been JSContextGroupRetained
     45//     OR
     46//     (b) one of its contexts has been JSContextRetained
    4947
    5048JSContextGroupRef JSContextGroupCreate()
     
    6563}
    6664
     65// From the API's perspective, a global context remains alive iff it has been JSGlobalContextRetained.
     66
    6767JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
    6868{
    6969    initializeThreading();
    70 #if OS(DARWIN)
    71     // When running on Tiger or Leopard, or if the application was linked before JSGlobalContextCreate was changed
    72     // to use a unique JSGlobalData, we use a shared one for compatibility.
    73 #ifndef BUILDING_ON_LEOPARD
    74     if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) {
    75 #else
    76     {
    77 #endif
    78         JSLock lock(LockForReal);
    79         return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass);
    80     }
    81 #endif // OS(DARWIN)
    82 
    8370    return JSGlobalContextCreateInGroup(0, globalObjectClass);
    8471}
     
    126113
    127114    JSGlobalData& globalData = exec->globalData();
    128     JSGlobalObject* dgo = exec->dynamicGlobalObject();
    129115    IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable);
    130116
    131     // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
    132     bool releasingContextGroup = globalData.refCount() == 2;
    133     bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo);
    134     // If this is the last reference to a global data, it should also
    135     // be the only remaining reference to the global object too!
    136     ASSERT(!releasingContextGroup || releasingGlobalObject);
    137 
    138     // An API 'JSGlobalContextRef' retains two things - a global object and a
    139     // global data (or context group, in API terminology).
    140     // * If this is the last reference to any contexts in the given context group,
    141     //   call destroy on the heap (the global data is being  freed).
    142     // * If this was the last reference to the global object, then unprotecting
    143     //   it may release a lot of GC memory - tickle the activity callback to
    144     //   garbage collect soon.
    145     // * If there are more references remaining the the global object, then do nothing
    146     //   (specifically that is more protects, which we assume come from other JSGlobalContextRefs).
    147     if (releasingContextGroup) {
    148         globalData.clearBuiltinStructures();
    149         globalData.heap.destroy();
    150     } else if (releasingGlobalObject) {
     117    bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject());
     118    if (protectCountIsZero) {
    151119        globalData.heap.activityCallback()->synchronize();
    152120        globalData.heap.reportAbandonedObjectGraph();
    153121    }
    154 
    155122    globalData.deref();
    156123
  • trunk/Source/JavaScriptCore/ChangeLog

    r115548 r115579  
     12012-04-28  Geoffrey Garen  <[email protected]>
     2
     3        Clarified JSGlobalData (JavaScript VM) lifetime
     4        https://bugs.webkit.org/show_bug.cgi?id=85142
     5
     6        Reviewed by Anders Carlsson.
     7
     8        This was so confusing that I didn't feel like I could reason about
     9        memory lifetime in the heap without fixing it.
     10
     11        The rules are:
     12
     13        (1) JSGlobalData owns the virtual machine and all memory in it.
     14
     15        (2) Deleting a JSGlobalData frees the virtual machine and all memory
     16        in it.
     17
     18        (Caveat emptor: if you delete the virtual machine while you're running
     19        JIT code or accessing GC objects, you're gonna have a bad time.)
     20
     21        (I opted not to make arbitrary sub-objects keep the virtual machine
     22        alive automatically because:
     23
     24                (a) doing that right would be complex and slow;
     25
     26                (b) in the case of an exiting thread or process, there's no
     27                clear way to give the garbage collector a chance to try again
     28                later;
     29
     30                (c) continuing to run the garbage collector after we've been
     31                asked to shut down the virtual machine seems rude;
     32
     33                (d) we've never really supported that feature, anyway.)
     34
     35        (3) Normal ref-counting will do. No need to call a battery of
     36        specialty functions to tear down a JSGlobalData. Its foibles
     37        notwithstanding, C++ does in fact know how to execute destructors in
     38        order.
     39
     40        * API/JSContextRef.cpp:
     41        (JSGlobalContextCreate): Removed compatibility shim for older
     42        operating systems because it's no longer used.
     43
     44        (JSGlobalContextRelease): Now that we can rely on JSGlobalData to "do
     45        the right thing", this code is much simpler. We still have one special
     46        case to notify the garbage collector if we're removing the last
     47        reference to the global object, since this can improve memory behavior.
     48
     49        * heap/CopiedSpace.cpp:
     50        (JSC::CopiedSpace::freeAllBlocks):
     51        * heap/CopiedSpace.h:
     52        (CopiedSpace): Renamed "destroy" => "freeAllBlocks" because true
     53        destruction-time behaviors should be limited to our C++ destructor.
     54
     55        * heap/Heap.cpp:
     56        (JSC::Heap::~Heap):
     57        (JSC):
     58        (JSC::Heap::lastChanceToFinalize):
     59        * heap/Heap.h:
     60        (Heap):
     61        (JSC::Heap::heap): Renamed "destroy" => "lastChanceToFinalize" because
     62        true destruction-time behaviors should be limited to our C++
     63        destructor.
     64
     65        Reorganized the code, putting code that must run before any objects
     66        get torn down into lastChanceToFinalize, and code that just tears down
     67        objects into our destructor.
     68
     69        * heap/Local.h:
     70        (JSC::LocalStack::LocalStack):
     71        (JSC::LocalStack::push):
     72        (LocalStack): See rule (2).
     73
     74        * jsc.cpp:
     75        (functionQuit):
     76        (main):
     77        (printUsageStatement):
     78        (parseArguments):
     79        (jscmain):
     80        * testRegExp.cpp:
     81        (main):
     82        (printUsageStatement):
     83        (parseArguments):
     84        (realMain): See rule (3).
     85
     86        I removed the feature of ensuring orderly tear-down when calling quit()
     87        or running in --help mode because it didn't seem very useful and
     88        making it work with Windows structured exception handling and
     89        NO_RETURN didn't seem like a fun way to spend a Saturday.
     90
     91        * runtime/JSGlobalData.h:
     92        * runtime/JSGlobalData.cpp:
     93        (JSC::JSGlobalData::JSGlobalData): Moved heap to be the first data
     94        member in JSGlobalData to ensure that it's destructed last, so other
     95        objects that reference it destruct without crashing. This allowed me
     96        to remove clearBuiltinStructures() altogether, and helped guarantee
     97        rule (3).
     98
     99        (JSC::JSGlobalData::~JSGlobalData): Explicitly call
     100        lastChanceToFinalize() at the head of our destructor to ensure that
     101        all pending finalizers run while the virtual machine is still in a
     102        valid state. Trying to resurrect (re-ref) the virtual machine at this
     103        point is not valid, but all other operations are.
     104
     105        Changed a null to a 0xbbadbeef to clarify just how bad this beef is.
     106
     107        * runtime/JSGlobalObject.cpp:
     108        (JSC::JSGlobalObject::init):
     109        * runtime/JSGlobalObject.h:
     110        (JSGlobalObject):
     111        (JSC::JSGlobalObject::globalData): See rule (3).
     112
    11132012-04-27  Geoffrey Garen  <[email protected]>
    2114
  • trunk/Source/JavaScriptCore/heap/CopiedSpace.cpp

    r114698 r115579  
    250250}
    251251
    252 void CopiedSpace::destroy()
     252void CopiedSpace::freeAllBlocks()
    253253{
    254254    while (!m_toSpace->isEmpty()) {
  • trunk/Source/JavaScriptCore/heap/CopiedSpace.h

    r114698 r115579  
    7070    size_t capacity();
    7171
    72     void destroy();
     72    void freeAllBlocks();
    7373
    7474    static CopiedBlock* blockFor(void*);
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r115545 r115579  
    342342Heap::~Heap()
    343343{
    344     // Destroy our block freeing thread.
     344    delete m_markListSet;
     345
     346    m_objectSpace.shrink();
     347    m_storageSpace.freeAllBlocks();
     348    releaseFreeBlocks();
    345349    {
    346350        MutexLocker locker(m_freeBlockLock);
     
    350354    waitForThreadCompletion(m_blockFreeingThread);
    351355
    352     // The destroy function must already have been called, so assert this.
    353     ASSERT(!m_globalData);
    354 }
    355 
    356 void Heap::destroy()
    357 {
    358     JSLock lock(SilenceAssertionsOnly);
    359 
    360     if (!m_globalData)
    361         return;
    362 
     356    ASSERT(!size());
     357    ASSERT(!capacity());
     358}
     359
     360// The JSGlobalData is being destroyed and the collector will never run again.
     361// Run all pending finalizers now because we won't get another chance.
     362void Heap::lastChanceToFinalize()
     363{
    363364    ASSERT(!m_globalData->dynamicGlobalObject);
    364365    ASSERT(m_operationInProgress == NoOperation);
    365    
    366     // The global object is not GC protected at this point, so sweeping may delete it
    367     // (and thus the global data) before other objects that may use the global data.
    368     RefPtr<JSGlobalData> protect(m_globalData);
    369 
    370 #if ENABLE(JIT)
    371     m_globalData->jitStubs->clearHostFunctionStubs();
    372 #endif
    373 
    374     delete m_markListSet;
    375     m_markListSet = 0;
    376 
     366
     367    // FIXME: Make this a release-mode crash once we're sure no one's doing this.
     368    if (size_t size = m_protectedValues.size())
     369        LOG_ERROR("JavaScriptCore heap deallocated while %ld values were still protected", size);
     370
     371    m_weakSet.finalizeAll();
    377372    canonicalizeCellLivenessData();
    378373    clearMarks();
    379 
    380     m_weakSet.finalizeAll();
     374    sweep();
    381375    m_globalData->smallStrings.finalizeSmallStrings();
    382     m_objectSpace.shrink();
    383     m_storageSpace.destroy();
    384     ASSERT(!size());
    385376
    386377#if ENABLE(SIMPLE_HEAP_PROFILING)
     
    388379    m_destroyedTypeCounts.dump(WTF::dataFile(), "Destroyed Type Counts");
    389380#endif
    390    
    391     releaseFreeBlocks();
    392 
    393     m_globalData = 0;
    394381}
    395382
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r115288 r115579  
    7575        friend class JIT;
    7676        friend class MarkStackThreadSharedData;
    77         static Heap* heap(JSValue); // 0 for immediate values
    78         static Heap* heap(JSCell*);
     77        static Heap* heap(const JSValue); // 0 for immediate values
     78        static Heap* heap(const JSCell*);
    7979
    8080        static bool isMarked(const void*);
     
    8888        Heap(JSGlobalData*, HeapSize);
    8989        ~Heap();
    90         JS_EXPORT_PRIVATE void destroy(); // JSGlobalData must call destroy() before ~Heap().
     90        JS_EXPORT_PRIVATE void lastChanceToFinalize();
    9191
    9292        JSGlobalData* globalData() const { return m_globalData; }
     
    267267    }
    268268
    269     inline Heap* Heap::heap(JSCell* cell)
     269    inline Heap* Heap::heap(const JSCell* cell)
    270270    {
    271271        return MarkedBlock::blockFor(cell)->heap();
    272272    }
    273273
    274     inline Heap* Heap::heap(JSValue v)
     274    inline Heap* Heap::heap(const JSValue v)
    275275    {
    276276        if (!v.isCell())
  • trunk/Source/JavaScriptCore/heap/Local.h

    r96465 r115579  
    103103public:
    104104    LocalStack(JSGlobalData& globalData)
    105         : m_globalData(&globalData)
     105        : m_globalData(globalData)
    106106        , m_count(0)
    107107    {
     
    123123    {
    124124        if (m_count == m_stack.size())
    125             m_stack.append(Local<T>(*m_globalData, value));
     125            m_stack.append(Local<T>(m_globalData, value));
    126126        else
    127127            m_stack[m_count] = value;
     
    133133
    134134private:
    135     RefPtr<JSGlobalData> m_globalData;
     135    JSGlobalData& m_globalData;
    136136    Vector<Local<T>, inlineCapacity> m_stack;
    137137    unsigned m_count;
  • trunk/Source/JavaScriptCore/jsc.cpp

    r115523 r115579  
    8181using namespace WTF;
    8282
    83 static void cleanupGlobalData(JSGlobalData*);
    8483static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
    8584
     
    418417}
    419418
    420 EncodedJSValue JSC_HOST_CALL functionQuit(ExecState* exec)
    421 {
    422     // Technically, destroying the heap in the middle of JS execution is a no-no,
    423     // but we want to maintain compatibility with the Mozilla test suite, so
    424     // we pretend that execution has terminated to avoid ASSERTs, then tear down the heap.
    425     exec->globalData().dynamicGlobalObject = 0;
    426 
    427     cleanupGlobalData(&exec->globalData());
     419EncodedJSValue JSC_HOST_CALL functionQuit(ExecState*)
     420{
    428421    exit(EXIT_SUCCESS);
    429422
     
    447440#endif
    448441
    449 int jscmain(int argc, char** argv, JSGlobalData*);
     442int jscmain(int argc, char** argv);
    450443
    451444int main(int argc, char** argv)
     
    492485    // Structured Exception Handling
    493486    int res = 0;
    494     JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap).leakRef();
    495487    TRY
    496         res = jscmain(argc, argv, globalData);
     488        res = jscmain(argc, argv);
    497489    EXCEPT(res = 3)
    498 
    499     cleanupGlobalData(globalData);
    500490    return res;
    501 }
    502 
    503 static void cleanupGlobalData(JSGlobalData* globalData)
    504 {
    505     JSLock lock(SilenceAssertionsOnly);
    506     globalData->clearBuiltinStructures();
    507     globalData->heap.destroy();
    508     globalData->deref();
    509491}
    510492
     
    614596}
    615597
    616 static NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false)
     598static NO_RETURN void printUsageStatement(bool help = false)
    617599{
    618600    fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
     
    626608#endif
    627609
    628     cleanupGlobalData(globalData);
    629610    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
    630611}
    631612
    632 static void parseArguments(int argc, char** argv, CommandLine& options, JSGlobalData* globalData)
     613static void parseArguments(int argc, char** argv, CommandLine& options)
    633614{
    634615    int i = 1;
     
    637618        if (!strcmp(arg, "-f")) {
    638619            if (++i == argc)
    639                 printUsageStatement(globalData);
     620                printUsageStatement();
    640621            options.scripts.append(Script(true, argv[i]));
    641622            continue;
     
    643624        if (!strcmp(arg, "-e")) {
    644625            if (++i == argc)
    645                 printUsageStatement(globalData);
     626                printUsageStatement();
    646627            options.scripts.append(Script(false, argv[i]));
    647628            continue;
     
    669650        }
    670651        if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
    671             printUsageStatement(globalData, true);
     652            printUsageStatement(true);
    672653        options.scripts.append(Script(true, argv[i]));
    673654    }
     
    680661}
    681662
    682 int jscmain(int argc, char** argv, JSGlobalData* globalData)
     663int jscmain(int argc, char** argv)
    683664{
    684665    JSLock lock(SilenceAssertionsOnly);
    685666
     667    RefPtr<JSGlobalData> globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap);
     668
    686669    CommandLine options;
    687     parseArguments(argc, argv, options, globalData);
     670    parseArguments(argc, argv, options);
    688671
    689672    GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.arguments);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.cpp

    r115248 r115579  
    9090
    9191JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType, HeapSize heapSize)
    92     : globalDataType(globalDataType)
     92    : heap(this, heapSize)
     93    , globalDataType(globalDataType)
    9394    , clientData(0)
    9495    , topCallFrame(CallFrame::noCaller())
     
    120121    , keywords(adoptPtr(new Keywords(this)))
    121122    , interpreter(0)
    122     , heap(this, heapSize)
    123123    , jsArrayClassInfo(&JSArray::s_info)
    124124    , jsFinalObjectClassInfo(&JSFinalObject::s_info)
     
    211211}
    212212
    213 void JSGlobalData::clearBuiltinStructures()
    214 {
    215     structureStructure.clear();
    216     debuggerActivationStructure.clear();
    217     activationStructure.clear();
    218     interruptedExecutionErrorStructure.clear();
    219     terminatedExecutionErrorStructure.clear();
    220     staticScopeStructure.clear();
    221     strictEvalActivationStructure.clear();
    222     stringStructure.clear();
    223     notAnObjectStructure.clear();
    224     propertyNameIteratorStructure.clear();
    225     getterSetterStructure.clear();
    226     apiWrapperStructure.clear();
    227     scopeChainNodeStructure.clear();
    228     executableStructure.clear();
    229     nativeExecutableStructure.clear();
    230     evalExecutableStructure.clear();
    231     programExecutableStructure.clear();
    232     functionExecutableStructure.clear();
    233     regExpStructure.clear();
    234     structureChainStructure.clear();
    235 }
    236 
    237213JSGlobalData::~JSGlobalData()
    238214{
    239     // By the time this is destroyed, heap.destroy() must already have been called.
     215    heap.lastChanceToFinalize();
    240216
    241217    delete interpreter;
    242218#ifndef NDEBUG
    243     // Zeroing out to make the behavior more predictable when someone attempts to use a deleted instance.
    244     interpreter = 0;
     219    interpreter = reinterpret_cast<Interpreter*>(0xbbadbeef);
    245220#endif
    246221
  • trunk/Source/JavaScriptCore/runtime/JSGlobalData.h

    r113445 r115579  
    153153        void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
    154154
     155        Heap heap; // The heap is our first data member to ensure that it's destructed after all the objects that reference it.
     156
    155157        GlobalDataType globalDataType;
    156158        ClientData* clientData;
     
    253255        TimeoutChecker timeoutChecker;
    254256        Terminator terminator;
    255         Heap heap;
    256257
    257258        JSValue exception;
     
    330331#endif
    331332        JS_EXPORT_PRIVATE void dumpRegExpTrace();
    332         JS_EXPORT_PRIVATE void clearBuiltinStructures();
    333333
    334334        bool isCollectorBusy() { return heap.isBusy(); }
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r112624 r115579  
    134134    structure()->disableSpecificFunctionTracking();
    135135
    136     m_globalData = Heap::heap(this)->globalData();
    137     m_globalScopeChain.set(*m_globalData, this, ScopeChainNode::create(0, this, m_globalData.get(), this, thisValue));
     136    m_globalScopeChain.set(globalData(), this, ScopeChainNode::create(0, this, &globalData(), this, thisValue));
    138137
    139138    JSGlobalObject::globalExec()->init(0, 0, m_globalScopeChain.get(), CallFrame::noCaller(), 0, 0);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r113363 r115579  
    8787    protected:
    8888
    89         RefPtr<JSGlobalData> m_globalData;
    90 
    9189        size_t m_registerArraySize;
    9290        Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize];
     
    303301        void resetPrototype(JSGlobalData&, JSValue prototype);
    304302
    305         JSGlobalData& globalData() const { return *m_globalData.get(); }
     303        JSGlobalData& globalData() const { return *Heap::heap(this)->globalData(); }
    306304
    307305        static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
  • trunk/Source/JavaScriptCore/testRegExp.cpp

    r112454 r115579  
    5555using namespace WTF;
    5656
    57 static void cleanupGlobalData(JSGlobalData*);
    58 
    5957struct CommandLine {
    6058    CommandLine()
     
    160158#endif
    161159
    162 int realMain(int argc, char** argv, JSGlobalData*);
     160int realMain(int argc, char** argv);
    163161
    164162int main(int argc, char** argv)
     
    194192    // Structured Exception Handling
    195193    int res = 0;
    196     JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap).leakRef();
    197194    TRY
    198         res = realMain(argc, argv, globalData);
     195        res = realMain(argc, argv);
    199196    EXCEPT(res = 3)
    200 
    201     cleanupGlobalData(globalData);
    202197    return res;
    203 }
    204 
    205 static void cleanupGlobalData(JSGlobalData* globalData)
    206 {
    207     JSLock lock(SilenceAssertionsOnly);
    208     globalData->clearBuiltinStructures();
    209     globalData->heap.destroy();
    210     globalData->deref();
    211198}
    212199
     
    481468#define RUNNING_FROM_XCODE 0
    482469
    483 static NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false)
     470static NO_RETURN void printUsageStatement(bool help = false)
    484471{
    485472    fprintf(stderr, "Usage: regexp_test [options] file\n");
     
    487474    fprintf(stderr, "  -v|--verbose  Verbose output\n");
    488475
    489     cleanupGlobalData(globalData);
    490476    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
    491477}
    492478
    493 static void parseArguments(int argc, char** argv, CommandLine& options, JSGlobalData* globalData)
     479static void parseArguments(int argc, char** argv, CommandLine& options)
    494480{
    495481    int i = 1;
     
    497483        const char* arg = argv[i];
    498484        if (!strcmp(arg, "-h") || !strcmp(arg, "--help"))
    499             printUsageStatement(globalData, true);
     485            printUsageStatement(true);
    500486        if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose"))
    501487            options.verbose = true;
     
    508494}
    509495
    510 int realMain(int argc, char** argv, JSGlobalData* globalData)
     496int realMain(int argc, char** argv)
    511497{
    512498    JSLock lock(SilenceAssertionsOnly);
    513499
     500    RefPtr<JSGlobalData> globalData = JSGlobalData::create(ThreadStackTypeLarge, LargeHeap);
     501
    514502    CommandLine options;
    515     parseArguments(argc, argv, options, globalData);
     503    parseArguments(argc, argv, options);
    516504
    517505    GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.arguments);
Note: See TracChangeset for help on using the changeset viewer.