Changeset 162598 in webkit for trunk/Source/JavaScriptCore/debugger/Debugger.cpp
- Timestamp:
- Jan 22, 2014, 11:39:58 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/debugger/Debugger.cpp
r160082 r162598 1 1 /* 2 * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved. 3 3 * Copyright (C) 1999-2001 Harri Porten ([email protected]) 4 4 * Copyright (C) 2001 Peter Kelly ([email protected]) … … 25 25 #include "Debugger.h" 26 26 27 #include "CodeBlock.h" 27 28 #include "DebuggerCallFrame.h" 28 29 #include "Error.h" 30 29 31 #include "HeapIterationScope.h" 30 32 #include "Interpreter.h" … … 140 142 141 143 Debugger::Debugger(bool isInWorkerThread) 142 : m_pauseOnExceptionsState(DontPauseOnExceptions) 144 : m_vm(nullptr) 145 , m_pauseOnExceptionsState(DontPauseOnExceptions) 143 146 , m_pauseOnNextStatement(false) 144 147 , m_isPaused(false) … … 152 155 , m_lastExecutedSourceID(noSourceID) 153 156 , m_topBreakpointID(noBreakpointID) 154 , m_needsOpDebugCallbacks(false)155 157 , m_shouldPause(false) 156 158 { … … 167 169 { 168 170 ASSERT(!globalObject->debugger()); 171 if (!m_vm) 172 m_vm = &globalObject->vm(); 173 else 174 ASSERT(m_vm == &globalObject->vm()); 169 175 globalObject->setDebugger(this); 170 176 m_globalObjects.add(globalObject); … … 185 191 m_globalObjects.remove(globalObject); 186 192 globalObject->setDebugger(0); 193 if (!m_globalObjects.size()) 194 m_vm = nullptr; 187 195 } 188 196 … … 190 198 { 191 199 m_shouldPause = value; 192 updateNeedForOpDebugCallbacks(); 200 } 201 202 void Debugger::registerCodeBlock(CodeBlock* codeBlock) 203 { 204 applyBreakpoints(codeBlock); 205 } 206 207 void Debugger::unregisterCodeBlock(CodeBlock* codeBlock) 208 { 209 codeBlock->clearAllBreakpoints(); 210 } 211 212 void Debugger::toggleBreakpoint(CodeBlock* codeBlock, Breakpoint& breakpoint, BreakpointState enabledOrNot) 213 { 214 ASSERT(codeBlock->jitCode()->jitType() == JITCode::InterpreterThunk 215 || codeBlock->jitCode()->jitType() == JITCode::BaselineJIT); 216 217 ScriptExecutable* executable = codeBlock->ownerExecutable(); 218 219 SourceID sourceID = static_cast<SourceID>(executable->sourceID()); 220 if (breakpoint.sourceID != sourceID) 221 return; 222 223 unsigned line = breakpoint.line; 224 unsigned column = breakpoint.column; 225 226 unsigned startLine = executable->lineNo(); 227 unsigned startColumn = executable->startColumn(); 228 unsigned endLine = executable->lastLine(); 229 unsigned endColumn = executable->endColumn(); 230 231 // Inspector breakpoint line and column values are zero-based but the executable 232 // and CodeBlock line and column values are one-based. 233 line += 1; 234 column = column ? column + 1 : Breakpoint::unspecifiedColumn; 235 236 if (line < startLine || line > endLine) 237 return; 238 if (column != Breakpoint::unspecifiedColumn) { 239 if (line == startLine && column < startColumn) 240 return; 241 if (line == endLine && column > endColumn) 242 return; 243 } 244 if (!codeBlock->hasOpDebugForLineAndColumn(line, column)) 245 return; 246 247 if (enabledOrNot == BreakpointEnabled) 248 codeBlock->addBreakpoint(1); 249 else 250 codeBlock->removeBreakpoint(1); 251 } 252 253 void Debugger::applyBreakpoints(CodeBlock* codeBlock) 254 { 255 BreakpointIDToBreakpointMap& breakpoints = m_breakpointIDToBreakpoint; 256 for (auto it = breakpoints.begin(); it != breakpoints.end(); ++it) { 257 Breakpoint& breakpoint = *it->value; 258 toggleBreakpoint(codeBlock, breakpoint, BreakpointEnabled); 259 } 260 } 261 262 class Debugger::ToggleBreakpointFunctor { 263 public: 264 ToggleBreakpointFunctor(Debugger* debugger, Breakpoint& breakpoint, BreakpointState enabledOrNot) 265 : m_debugger(debugger) 266 , m_breakpoint(breakpoint) 267 , m_enabledOrNot(enabledOrNot) 268 { 269 } 270 271 bool operator()(CodeBlock* codeBlock) 272 { 273 if (m_debugger == codeBlock->globalObject()->debugger()) 274 m_debugger->toggleBreakpoint(codeBlock, m_breakpoint, m_enabledOrNot); 275 return false; 276 } 277 278 private: 279 Debugger* m_debugger; 280 Breakpoint& m_breakpoint; 281 BreakpointState m_enabledOrNot; 282 }; 283 284 void Debugger::toggleBreakpoint(Breakpoint& breakpoint, Debugger::BreakpointState enabledOrNot) 285 { 286 if (!m_vm) 287 return; 288 HeapIterationScope iterationScope(m_vm->heap); 289 ToggleBreakpointFunctor functor(this, breakpoint, enabledOrNot); 290 m_vm->heap.forEachCodeBlock(functor); 193 291 } 194 292 … … 206 304 HeapIterationScope iterationScope(vm->heap); 207 305 vm->heap.objectSpace().forEachLiveCell(iterationScope, recompiler); 208 }209 210 void Debugger::updateNeedForOpDebugCallbacks()211 {212 size_t numberOfBreakpoints = m_breakpointIDToBreakpoint.size();213 m_needsOpDebugCallbacks = m_shouldPause || numberOfBreakpoints;214 306 } 215 307 … … 248 340 m_breakpointIDToBreakpoint.set(id, &breakpoints.last()); 249 341 250 updateNeedForOpDebugCallbacks();342 toggleBreakpoint(breakpoint, BreakpointEnabled); 251 343 252 344 return id; … … 267 359 LineToBreakpointsMap::iterator breaksIt = it->value.find(breakpoint.line); 268 360 ASSERT(breaksIt != it->value.end()); 361 362 toggleBreakpoint(breakpoint, BreakpointDisabled); 269 363 270 364 BreakpointsInLine& breakpoints = breaksIt->value; … … 283 377 } 284 378 } 285 286 updateNeedForOpDebugCallbacks();287 379 } 288 380 … … 311 403 unsigned breakColumn = breakpoints[i].column; 312 404 // Since frontend truncates the indent, the first statement in a line must match the breakpoint (line,0). 405 ASSERT(this == m_currentCallFrame->codeBlock()->globalObject()->debugger()); 313 406 if ((line != m_lastExecutedLine && line == breakLine && !breakColumn) 314 407 || (line == breakLine && column == breakColumn)) { … … 346 439 } 347 440 441 class Debugger::ClearBreakpointsFunctor { 442 public: 443 ClearBreakpointsFunctor(Debugger* debugger) 444 : m_debugger(debugger) 445 { 446 } 447 448 bool operator()(CodeBlock* codeBlock) 449 { 450 if (codeBlock->numBreakpoints() && m_debugger == codeBlock->globalObject()->debugger()) 451 codeBlock->clearAllBreakpoints(); 452 return false; 453 } 454 455 private: 456 Debugger* m_debugger; 457 }; 458 348 459 void Debugger::clearBreakpoints() 349 460 { … … 352 463 m_sourceIDToBreakpoints.clear(); 353 464 354 updateNeedForOpDebugCallbacks(); 465 if (!m_vm) 466 return; 467 HeapIterationScope iterationScope(m_vm->heap); 468 ClearBreakpointsFunctor functor(this); 469 m_vm->heap.forEachCodeBlock(functor); 355 470 } 356 471 … … 374 489 void Debugger::breakProgram() 375 490 { 376 if (m_isPaused || !m_currentCallFrame)491 if (m_isPaused) 377 492 return; 378 493 379 494 m_pauseOnNextStatement = true; 380 495 setShouldPause(true); 496 m_currentCallFrame = m_vm->topCallFrame; 497 ASSERT(m_currentCallFrame); 381 498 pauseIfNeeded(m_currentCallFrame); 382 499 } … … 433 550 updateCallFrame(callFrame); 434 551 pauseIfNeeded(callFrame); 435 if (! needsOpDebugCallbacks())552 if (!shouldPause()) 436 553 m_currentCallFrame = 0; 437 554 } … … 478 595 if (!m_pauseOnNextStatement && !m_pauseOnCallFrame) { 479 596 setShouldPause(false); 480 if (!needsOpDebugCallbacks()) 481 m_currentCallFrame = 0; 597 m_currentCallFrame = nullptr; 482 598 } 483 599 } … … 549 665 if (!m_isInWorkerThread) 550 666 updateCallFrameAndPauseIfNeeded(callFrame); 551 else if ( needsOpDebugCallbacks())667 else if (shouldPause()) 552 668 updateCallFrame(callFrame); 553 669 }
Note:
See TracChangeset
for help on using the changeset viewer.