Ignore:
Timestamp:
Jun 8, 2012, 11:17:16 AM (13 years ago)
Author:
[email protected]
Message:

Don't rely on weak pointers for eager CodeBlock finalization
https://bugs.webkit.org/show_bug.cgi?id=88465

Reviewed by Gavin Barraclough.

This is incompatible with lazy weak pointer finalization.

I considered just making CodeBlock finalization lazy-friendly, but it
turns out that the heap is already way up in CodeBlock's business when
it comes to finalization, so I decided to finish the job and move full
responsibility for CodeBlock finalization into the heap.

will build.

  • debugger/Debugger.cpp: Updated for rename.
  • heap/Heap.cpp:

(JSC::Heap::deleteAllCompiledCode): Renamed for consistency. Fixed a bug
where we would not delete code for a code block that had been previously
jettisoned. I don't know if this happens in practice -- I mostly did
this to improve consistency with deleteUnmarkedCompiledCode.

(JSC::Heap::deleteUnmarkedCompiledCode): New function, responsible for
eager finalization of unmarked code blocks.

(JSC::Heap::collect): Updated for rename. Updated to call
deleteUnmarkedCompiledCode(), which takes care of jettisoned DFG code
blocks too.

(JSC::Heap::addCompiledCode): Renamed, since this points to all code
now, not just functions.

  • heap/Heap.h:

(Heap): Keep track of all user code, not just functions. This is a
negligible additional overhead, since most code is function code.

  • runtime/Executable.cpp:

(JSC::*::finalize): Removed these functions, since we don't rely on
weak pointer finalization anymore.

(JSC::FunctionExecutable::FunctionExecutable): Moved linked-list stuff
into base class so all executables can be in the list.

(JSC::EvalExecutable::clearCode):
(JSC::ProgramExecutable::clearCode):
(JSC::FunctionExecutable::clearCode): All we need to do is delete our
CodeBlock -- that will delete all of its internal data structures.

(JSC::FunctionExecutable::clearCodeIfNotCompiling): Factored out a helper
function to improve clarity.

  • runtime/Executable.h:

(JSC::ExecutableBase): Moved linked-list stuff
into base class so all executables can be in the list.

(JSC::NativeExecutable::create):
(NativeExecutable):
(ScriptExecutable):
(JSC::ScriptExecutable::finishCreation):
(JSC::EvalExecutable::create):
(EvalExecutable):
(JSC::ProgramExecutable::create):
(ProgramExecutable):
(FunctionExecutable):
(JSC::FunctionExecutable::create): Don't use a finalizer -- the heap
will call us back to destroy our code block.

(JSC::FunctionExecutable::discardCode): Renamed to clearCodeIfNotCompiling()
for clarity.

(JSC::FunctionExecutable::isCompiling): New helper function, for clarity.

(JSC::ScriptExecutable::clearCodeVirtual): New helper function, since
the heap needs to make polymorphic calls to clear code.

  • runtime/JSGlobalData.cpp:

(JSC::StackPreservingRecompiler::operator()):

  • runtime/JSGlobalObject.cpp:

(JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Updated for
renames.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r119633 r119844  
    644644}
    645645
    646 void Heap::discardAllCompiledCode()
    647 {
    648     // If JavaScript is running, it's not safe to recompile, since we'll end
    649     // up throwing away code that is live on the stack.
     646void Heap::deleteAllCompiledCode()
     647{
     648    // If JavaScript is running, it's not safe to delete code, since we'll end
     649    // up deleting code that is live on the stack.
    650650    if (m_globalData->dynamicGlobalObject)
    651651        return;
    652652
    653     for (FunctionExecutable* current = m_functions.head(); current; current = current->next())
    654         current->discardCode();
     653    for (ExecutableBase* current = m_compiledCode.head(); current; current = current->next()) {
     654        if (!current->isFunctionExecutable())
     655            continue;
     656        static_cast<FunctionExecutable*>(current)->clearCodeIfNotCompiling();
     657    }
     658
     659    m_dfgCodeBlocks.clearMarks();
     660    m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
     661}
     662
     663void Heap::deleteUnmarkedCompiledCode()
     664{
     665    ExecutableBase* next;
     666    for (ExecutableBase* current = m_compiledCode.head(); current; current = next) {
     667        next = current->next();
     668        if (isMarked(current))
     669            continue;
     670
     671        // We do this because executable memory is limited on some platforms and because
     672        // CodeBlock requires eager finalization.
     673        ExecutableBase::clearCodeVirtual(current);
     674        m_compiledCode.remove(current);
     675    }
     676
     677    m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
    655678}
    656679
     
    681704    double lastGCStartTime = WTF::currentTime();
    682705    if (lastGCStartTime - m_lastCodeDiscardTime > minute) {
    683         discardAllCompiledCode();
     706        deleteAllCompiledCode();
    684707        m_lastCodeDiscardTime = WTF::currentTime();
    685708    }
     
    704727    }
    705728
     729    JAVASCRIPTCORE_GC_MARKED();
     730
    706731    {
    707732        GCPHASE(FinalizeUnconditionalFinalizers);
     
    714739        m_globalData->smallStrings.finalizeSmallStrings();
    715740    }
    716    
    717     JAVASCRIPTCORE_GC_MARKED();
    718741
    719742    {
    720743        GCPHASE(DeleteCodeBlocks);
    721         m_dfgCodeBlocks.deleteUnmarkedJettisonedCodeBlocks();
     744        deleteUnmarkedCompiledCode();
    722745    }
    723746
     
    809832}
    810833
    811 void Heap::addFunctionExecutable(FunctionExecutable* executable)
    812 {
    813     m_functions.append(executable);
    814 }
    815 
    816 void Heap::removeFunctionExecutable(FunctionExecutable* executable)
    817 {
    818     m_functions.remove(executable);
     834void Heap::addCompiledCode(ExecutableBase* executable)
     835{
     836    m_compiledCode.append(executable);
    819837}
    820838
Note: See TracChangeset for help on using the changeset viewer.