Ignore:
Timestamp:
Jan 24, 2014, 11:07:31 AM (11 years ago)
Author:
[email protected]
Message:

Removing the need for Debugger* and m_shouldPause op_debug check.
<https://webkit.org/b/127532>

Reviewed by Geoffrey Garen.

This patch replaces the checking of the Debugger::m_shouldPause flag
with a procedure to set a SteppingMode flag on all CodeBlocks under
the management of the debugger. This simplifies the op_debug checking
logic in all the execution engines.

  • bytecode/CodeBlock.cpp:
  • bytecode/CodeBlock.h:

(JSC::CodeBlock::hasDebuggerRequests):
(JSC::CodeBlock::debuggerRequestsAddress):
(JSC::CodeBlock::setSteppingMode):
(JSC::CodeBlock::clearDebuggerRequests):

  • CodeBlock::m_debuggerRequests is a union of m_numBreakpoints and the new m_steppingMode. The debugger can add/remove breakpoints to the CodeBlock as well as set the stepping mode. By having m_debuggerRequests as a union of the 2 bit fields, the op_debug code can now check if any of the 2 requests made on the CodeBlock is still in effect just by testing a single int.
  • debugger/Debugger.cpp:

(JSC::Debugger::Debugger):
(JSC::Debugger::detach):

  • This was bug from before where I forgot to clear the CodeBlock breakpoints before detaching. We now take care of it by clearing all debugger requests made to the CodeBlock.

(JSC::Debugger::SetSteppingModeFunctor::SetSteppingModeFunctor):
(JSC::Debugger::SetSteppingModeFunctor::operator()):
(JSC::Debugger::setSteppingMode):
(JSC::Debugger::ClearCodeBlockDebuggerRequestsFunctor::ClearCodeBlockDebuggerRequestsFunctor):
(JSC::Debugger::ClearCodeBlockDebuggerRequestsFunctor::operator()):
(JSC::Debugger::clearBreakpoints):

(JSC::Debugger::ClearDebuggerRequestsFunctor::ClearDebuggerRequestsFunctor):
(JSC::Debugger::ClearDebuggerRequestsFunctor::operator()):
(JSC::Debugger::clearDebuggerRequests):

  • We need a distinct clearDebuggerRequests() from clearBreakpoints() because:
    1. When we detach a globalObject, we only want to clear the debugger requests in CodeBlocks from that global.
    2. Clearing the debugger requests in the CodeBlocks is not the same as clearing the breakpoints. The breakpoints are still in effect for the next time a globalObject is attached, or for other globalObjects that are still attached.

(JSC::Debugger::setPauseOnNextStatement):
(JSC::Debugger::breakProgram):
(JSC::Debugger::stepIntoStatement):
(JSC::Debugger::updateCallFrameAndPauseIfNeeded):
(JSC::Debugger::pauseIfNeeded):
(JSC::Debugger::exception):
(JSC::Debugger::willExecuteProgram):
(JSC::Debugger::didReachBreakpoint):

  • debugger/Debugger.h:
  • We're always going to support the debugger. So, there's no longer a need to check ENABLE(JAVASCRIPT_DEBUGGER). Removed the unneeded code.
  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::debug):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_debug):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_debug):

  • llint/LowLevelInterpreter.asm:
  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::setDebugger):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/debugger/Debugger.cpp

    r162652 r162711  
    149149    , m_hasHandlerForExceptionCallback(false)
    150150    , m_isInWorkerThread(isInWorkerThread)
     151    , m_steppingMode(SteppingModeDisabled)
    151152    , m_reasonForPause(NotPaused)
    152153    , m_pauseOnCallFrame(0)
     
    155156    , m_lastExecutedSourceID(noSourceID)
    156157    , m_topBreakpointID(noBreakpointID)
    157     , m_shouldPause(false)
    158158{
    159159}
     
    190190    ASSERT(m_globalObjects.contains(globalObject));
    191191    m_globalObjects.remove(globalObject);
     192
     193    clearDebuggerRequests(globalObject);
    192194    globalObject->setDebugger(0);
    193195    if (!m_globalObjects.size())
     
    195197}
    196198
    197 void Debugger::setShouldPause(bool value)
    198 {
    199     m_shouldPause = value;
     199class Debugger::SetSteppingModeFunctor {
     200public:
     201    SetSteppingModeFunctor(Debugger* debugger, SteppingMode mode)
     202        : m_debugger(debugger)
     203        , m_mode(mode)
     204    {
     205    }
     206
     207    bool operator()(CodeBlock* codeBlock)
     208    {
     209        if (m_debugger == codeBlock->globalObject()->debugger()) {
     210            if (m_mode == SteppingModeEnabled)
     211                codeBlock->setSteppingMode(CodeBlock::SteppingModeEnabled);
     212            else
     213                codeBlock->setSteppingMode(CodeBlock::SteppingModeDisabled);
     214        }
     215        return false;
     216    }
     217
     218private:
     219    Debugger* m_debugger;
     220    SteppingMode m_mode;
     221};
     222
     223void Debugger::setSteppingMode(SteppingMode mode)
     224{
     225    if (mode == m_steppingMode)
     226        return;
     227    m_steppingMode = mode;
     228
     229    if (!m_vm)
     230        return;
     231    HeapIterationScope iterationScope(m_vm->heap);
     232    SetSteppingModeFunctor functor(this, mode);
     233    m_vm->heap.forEachCodeBlock(functor);
    200234}
    201235
     
    203237{
    204238    applyBreakpoints(codeBlock);
    205 }
    206 
    207 void Debugger::unregisterCodeBlock(CodeBlock* codeBlock)
    208 {
    209     codeBlock->clearAllBreakpoints();
     239    if (isStepping())
     240        codeBlock->setSteppingMode(CodeBlock::SteppingModeEnabled);
    210241}
    211242
     
    436467}
    437468
    438 class Debugger::ClearBreakpointsFunctor {
     469class Debugger::ClearCodeBlockDebuggerRequestsFunctor {
    439470public:
    440     ClearBreakpointsFunctor(Debugger* debugger)
     471    ClearCodeBlockDebuggerRequestsFunctor(Debugger* debugger)
    441472        : m_debugger(debugger)
    442473    {
     
    445476    bool operator()(CodeBlock* codeBlock)
    446477    {
    447         if (codeBlock->numBreakpoints() && m_debugger == codeBlock->globalObject()->debugger())
    448             codeBlock->clearAllBreakpoints();
     478        if (codeBlock->hasDebuggerRequests() && m_debugger == codeBlock->globalObject()->debugger())
     479            codeBlock->clearDebuggerRequests();
    449480        return false;
    450481    }
     
    463494        return;
    464495    HeapIterationScope iterationScope(m_vm->heap);
    465     ClearBreakpointsFunctor functor(this);
     496    ClearCodeBlockDebuggerRequestsFunctor functor(this);
     497    m_vm->heap.forEachCodeBlock(functor);
     498}
     499
     500class Debugger::ClearDebuggerRequestsFunctor {
     501public:
     502    ClearDebuggerRequestsFunctor(JSGlobalObject* globalObject)
     503        : m_globalObject(globalObject)
     504    {
     505    }
     506
     507    bool operator()(CodeBlock* codeBlock)
     508    {
     509        if (codeBlock->hasDebuggerRequests() && m_globalObject == codeBlock->globalObject())
     510            codeBlock->clearDebuggerRequests();
     511        return false;
     512    }
     513
     514private:
     515    JSGlobalObject* m_globalObject;
     516};
     517
     518void Debugger::clearDebuggerRequests(JSGlobalObject* globalObject)
     519{
     520    ASSERT(m_vm);
     521    HeapIterationScope iterationScope(m_vm->heap);
     522    ClearDebuggerRequestsFunctor functor(globalObject);
    466523    m_vm->heap.forEachCodeBlock(functor);
    467524}
     
    481538    m_pauseOnNextStatement = pause;
    482539    if (pause)
    483         setShouldPause(true);
     540        setSteppingMode(SteppingModeEnabled);
    484541}
    485542
     
    490547
    491548    m_pauseOnNextStatement = true;
    492     setShouldPause(true);
     549    setSteppingMode(SteppingModeEnabled);
    493550    m_currentCallFrame = m_vm->topCallFrame;
    494551    ASSERT(m_currentCallFrame);
     
    511568
    512569    m_pauseOnNextStatement = true;
    513     setShouldPause(true);
     570    setSteppingMode(SteppingModeEnabled);
    514571    notifyDoneProcessingDebuggerEvents();
    515572}
     
    547604    updateCallFrame(callFrame);
    548605    pauseIfNeeded(callFrame);
    549     if (!shouldPause())
     606    if (!isStepping())
    550607        m_currentCallFrame = 0;
    551608}
     
    591648
    592649    if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) {
    593         setShouldPause(false);
     650        setSteppingMode(SteppingModeDisabled);
    594651        m_currentCallFrame = nullptr;
    595652    }
     
    604661    if (m_pauseOnExceptionsState == PauseOnAllExceptions || (m_pauseOnExceptionsState == PauseOnUncaughtExceptions && !hasHandler)) {
    605662        m_pauseOnNextStatement = true;
    606         setShouldPause(true);
     663        setSteppingMode(SteppingModeEnabled);
    607664    }
    608665
     
    662719    if (!m_isInWorkerThread)
    663720        updateCallFrameAndPauseIfNeeded(callFrame);
    664     else if (shouldPause())
     721    else if (isStepping())
    665722        updateCallFrame(callFrame);
    666723}
     
    692749    PauseReasonDeclaration reason(*this, PausedForBreakpoint);
    693750    m_pauseOnNextStatement = true;
    694     setShouldPause(true);
     751    setSteppingMode(SteppingModeEnabled);
    695752    updateCallFrameAndPauseIfNeeded(callFrame);
    696753}
Note: See TracChangeset for help on using the changeset viewer.