OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_DEBUG_H_ | 5 #ifndef V8_DEBUG_H_ |
6 #define V8_DEBUG_H_ | 6 #define V8_DEBUG_H_ |
7 | 7 |
8 #include "allocation.h" | 8 #include "allocation.h" |
9 #include "arguments.h" | 9 #include "arguments.h" |
10 #include "assembler.h" | 10 #include "assembler.h" |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 | 344 |
345 // This class contains the debugger support. The main purpose is to handle | 345 // This class contains the debugger support. The main purpose is to handle |
346 // setting break points in the code. | 346 // setting break points in the code. |
347 // | 347 // |
348 // This class controls the debug info for all functions which currently have | 348 // This class controls the debug info for all functions which currently have |
349 // active breakpoints in them. This debug info is held in the heap root object | 349 // active breakpoints in them. This debug info is held in the heap root object |
350 // debug_info which is a FixedArray. Each entry in this list is of class | 350 // debug_info which is a FixedArray. Each entry in this list is of class |
351 // DebugInfo. | 351 // DebugInfo. |
352 class Debug { | 352 class Debug { |
353 public: | 353 public: |
354 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); | |
355 void OnException(Handle<Object> exception, bool uncaught); | |
356 void OnBeforeCompile(Handle<Script> script); | |
357 | |
358 enum AfterCompileFlags { | 354 enum AfterCompileFlags { |
359 NO_AFTER_COMPILE_FLAGS, | 355 NO_AFTER_COMPILE_FLAGS, |
360 SEND_WHEN_DEBUGGING | 356 SEND_WHEN_DEBUGGING |
361 }; | 357 }; |
| 358 |
| 359 // Debug event triggers. |
| 360 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); |
| 361 void OnException(Handle<Object> exception, bool uncaught); |
| 362 void OnBeforeCompile(Handle<Script> script); |
362 void OnAfterCompile(Handle<Script> script, | 363 void OnAfterCompile(Handle<Script> script, |
363 AfterCompileFlags after_compile_flags); | 364 AfterCompileFlags after_compile_flags); |
364 void OnScriptCollected(int id); | 365 void OnScriptCollected(int id); |
365 | 366 |
| 367 // API facing. |
366 void SetEventListener(Handle<Object> callback, Handle<Object> data); | 368 void SetEventListener(Handle<Object> callback, Handle<Object> data); |
367 void SetMessageHandler(v8::Debug::MessageHandler handler); | 369 void SetMessageHandler(v8::Debug::MessageHandler handler); |
368 | |
369 // Add a debugger command to the command queue. | |
370 void EnqueueCommandMessage(Vector<const uint16_t> command, | 370 void EnqueueCommandMessage(Vector<const uint16_t> command, |
371 v8::Debug::ClientData* client_data = NULL); | 371 v8::Debug::ClientData* client_data = NULL); |
372 | |
373 // Check whether there are commands in the command queue. | |
374 bool HasCommands(); | |
375 | |
376 // Enqueue a debugger command to the command queue for event listeners. | 372 // Enqueue a debugger command to the command queue for event listeners. |
377 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); | 373 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL); |
378 | |
379 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, | 374 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun, |
380 Handle<Object> data); | 375 Handle<Object> data); |
| 376 Handle<Context> GetDebugContext(); |
| 377 void DebugBreakHelper(); |
| 378 void ProcessDebugMessages(bool debug_command_only); |
381 | 379 |
382 Handle<Context> GetDebugContext(); | 380 // Flags and states. |
383 | |
384 bool ignore_debugger() const { return ignore_debugger_; } | |
385 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } | 381 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; } |
386 bool live_edit_enabled() const { | 382 bool live_edit_enabled() const { |
387 return FLAG_enable_liveedit && live_edit_enabled_ ; | 383 return FLAG_enable_liveedit && live_edit_enabled_ ; |
388 } | 384 } |
389 | 385 |
390 bool is_active() { return is_active_; } | 386 inline bool is_active() const { return is_active_; } |
| 387 inline bool is_loaded() const { return !debug_context_.is_null(); } |
| 388 inline bool has_break_points() const { return has_break_points_; } |
| 389 inline bool is_entered() const { |
| 390 return thread_local_.debugger_entry_ != NULL; |
| 391 } |
391 | 392 |
392 class IgnoreScope { | 393 void set_disable_break(bool v) { break_disabled_ = v; } |
393 public: | |
394 explicit IgnoreScope(Debug* debug) | |
395 : debug_(debug), | |
396 old_state_(debug->ignore_debugger_) { | |
397 debug_->ignore_debugger_ = true; | |
398 } | |
399 | |
400 ~IgnoreScope() { | |
401 debug_->ignore_debugger_ = old_state_; | |
402 } | |
403 | |
404 private: | |
405 Debug* debug_; | |
406 bool old_state_; | |
407 DISALLOW_COPY_AND_ASSIGN(IgnoreScope); | |
408 }; | |
409 | |
410 | 394 |
411 bool Load(); | 395 bool Load(); |
412 void Unload(); | |
413 bool IsLoaded() { return !debug_context_.is_null(); } | |
414 bool InDebugger() { return thread_local_.debugger_entry_ != NULL; } | |
415 | 396 |
416 void Break(Arguments args, JavaScriptFrame*); | 397 void Break(Arguments args, JavaScriptFrame*); |
417 void SetAfterBreakTarget(JavaScriptFrame* frame); | 398 void SetAfterBreakTarget(JavaScriptFrame* frame); |
| 399 |
418 bool SetBreakPoint(Handle<JSFunction> function, | 400 bool SetBreakPoint(Handle<JSFunction> function, |
419 Handle<Object> break_point_object, | 401 Handle<Object> break_point_object, |
420 int* source_position); | 402 int* source_position); |
421 bool SetBreakPointForScript(Handle<Script> script, | 403 bool SetBreakPointForScript(Handle<Script> script, |
422 Handle<Object> break_point_object, | 404 Handle<Object> break_point_object, |
423 int* source_position, | 405 int* source_position, |
424 BreakPositionAlignment alignment); | 406 BreakPositionAlignment alignment); |
425 void ClearBreakPoint(Handle<Object> break_point_object); | 407 void ClearBreakPoint(Handle<Object> break_point_object); |
426 void ClearAllBreakPoints(); | 408 void ClearAllBreakPoints(); |
427 void FloodWithOneShot(Handle<JSFunction> function); | 409 void FloodWithOneShot(Handle<JSFunction> function); |
428 void FloodBoundFunctionWithOneShot(Handle<JSFunction> function); | 410 void FloodBoundFunctionWithOneShot(Handle<JSFunction> function); |
429 void FloodHandlerWithOneShot(); | 411 void FloodHandlerWithOneShot(); |
430 void ChangeBreakOnException(ExceptionBreakType type, bool enable); | 412 void ChangeBreakOnException(ExceptionBreakType type, bool enable); |
431 bool IsBreakOnException(ExceptionBreakType type); | 413 bool IsBreakOnException(ExceptionBreakType type); |
432 | 414 |
433 void PromiseHandlePrologue(Handle<JSFunction> promise_getter); | 415 void PromiseHandlePrologue(Handle<JSFunction> promise_getter); |
434 void PromiseHandleEpilogue(); | 416 void PromiseHandleEpilogue(); |
435 // Returns a promise if it does not have a reject handler. | 417 // Returns a promise if it does not have a reject handler. |
436 Handle<Object> GetPromiseForUncaughtException(); | 418 Handle<Object> GetPromiseForUncaughtException(); |
437 | 419 |
438 void PrepareStep(StepAction step_action, | 420 void PrepareStep(StepAction step_action, |
439 int step_count, | 421 int step_count, |
440 StackFrame::Id frame_id); | 422 StackFrame::Id frame_id); |
441 void ClearStepping(); | 423 void ClearStepping(); |
442 void ClearStepOut(); | 424 void ClearStepOut(); |
443 bool IsStepping() { return thread_local_.step_count_ > 0; } | 425 bool IsStepping() { return thread_local_.step_count_ > 0; } |
444 bool StepNextContinue(BreakLocationIterator* break_location_iterator, | 426 bool StepNextContinue(BreakLocationIterator* break_location_iterator, |
445 JavaScriptFrame* frame); | 427 JavaScriptFrame* frame); |
| 428 |
| 429 // Returns whether the operation succeeded. Compilation can only be triggered |
| 430 // if a valid closure is passed as the second argument, otherwise the shared |
| 431 // function needs to be compiled already. |
| 432 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared, |
| 433 Handle<JSFunction> function); |
446 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); | 434 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); |
447 static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); | 435 static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); |
448 | 436 |
449 void PrepareForBreakPoints(); | 437 void PrepareForBreakPoints(); |
450 | 438 |
451 // This function is used in FunctionNameUsing* tests. | 439 // This function is used in FunctionNameUsing* tests. |
452 Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position); | 440 Object* FindSharedFunctionInfoInScript(Handle<Script> script, int position); |
453 | 441 |
454 // Returns whether the operation succeeded. Compilation can only be triggered | |
455 // if a valid closure is passed as the second argument, otherwise the shared | |
456 // function needs to be compiled already. | |
457 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared, | |
458 Handle<JSFunction> function); | |
459 | 442 |
460 // Returns true if the current stub call is patched to call the debugger. | 443 // Returns true if the current stub call is patched to call the debugger. |
461 static bool IsDebugBreak(Address addr); | 444 static bool IsDebugBreak(Address addr); |
462 // Returns true if the current return statement has been patched to be | 445 // Returns true if the current return statement has been patched to be |
463 // a debugger breakpoint. | 446 // a debugger breakpoint. |
464 static bool IsDebugBreakAtReturn(RelocInfo* rinfo); | 447 static bool IsDebugBreakAtReturn(RelocInfo* rinfo); |
465 | |
466 // Check whether a code stub with the specified major key is a possible break | 448 // Check whether a code stub with the specified major key is a possible break |
467 // point location. | 449 // point location. |
468 static bool IsSourceBreakStub(Code* code); | 450 static bool IsSourceBreakStub(Code* code); |
469 static bool IsBreakStub(Code* code); | 451 static bool IsBreakStub(Code* code); |
470 | |
471 // Find the builtin to use for invoking the debug break | 452 // Find the builtin to use for invoking the debug break |
472 static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode); | 453 static Handle<Code> FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode); |
473 | 454 |
474 static Handle<Object> GetSourceBreakLocations( | 455 static Handle<Object> GetSourceBreakLocations( |
475 Handle<SharedFunctionInfo> shared, | 456 Handle<SharedFunctionInfo> shared, |
476 BreakPositionAlignment position_aligment); | 457 BreakPositionAlignment position_aligment); |
477 | 458 |
478 // Getter for the debug_context. | 459 // Getter for the debug_context. |
479 inline Handle<Context> debug_context() { return debug_context_; } | 460 inline Handle<Context> debug_context() { return debug_context_; } |
480 | 461 |
481 // Check whether a global object is the debug global object. | 462 // Check whether a global object is the debug global object. |
482 bool IsDebugGlobal(GlobalObject* global); | 463 bool IsDebugGlobal(GlobalObject* global); |
483 | 464 |
484 // Check whether this frame is just about to return. | 465 // Check whether this frame is just about to return. |
485 bool IsBreakAtReturn(JavaScriptFrame* frame); | 466 bool IsBreakAtReturn(JavaScriptFrame* frame); |
486 | 467 |
487 // Fast check to see if any break points are active. | 468 StackFrame::Id break_frame_id() { return thread_local_.break_frame_id_; } |
488 inline bool has_break_points() { return has_break_points_; } | |
489 | |
490 void NewBreak(StackFrame::Id break_frame_id); | |
491 void SetBreak(StackFrame::Id break_frame_id, int break_id); | |
492 StackFrame::Id break_frame_id() { | |
493 return thread_local_.break_frame_id_; | |
494 } | |
495 int break_id() { return thread_local_.break_id_; } | 469 int break_id() { return thread_local_.break_id_; } |
496 | 470 |
497 bool StepInActive() { return thread_local_.step_into_fp_ != 0; } | 471 bool StepInActive() { return thread_local_.step_into_fp_ != 0; } |
498 void HandleStepIn(Handle<JSFunction> function, | 472 void HandleStepIn(Handle<JSFunction> function, |
499 Handle<Object> holder, | 473 Handle<Object> holder, |
500 Address fp, | 474 Address fp, |
501 bool is_constructor); | 475 bool is_constructor); |
502 Address step_in_fp() { return thread_local_.step_into_fp_; } | 476 Address step_in_fp() { return thread_local_.step_into_fp_; } |
503 Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } | 477 Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } |
504 | 478 |
505 bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } | 479 bool StepOutActive() { return thread_local_.step_out_fp_ != 0; } |
506 Address step_out_fp() { return thread_local_.step_out_fp_; } | 480 Address step_out_fp() { return thread_local_.step_out_fp_; } |
507 | 481 |
508 EnterDebugger* debugger_entry() { | 482 EnterDebugger* debugger_entry() { return thread_local_.debugger_entry_; } |
509 return thread_local_.debugger_entry_; | |
510 } | |
511 void set_debugger_entry(EnterDebugger* entry) { | |
512 thread_local_.debugger_entry_ = entry; | |
513 } | |
514 | 483 |
515 // Check whether any of the specified interrupts are pending. | 484 // Check whether any of the specified interrupts are pending. |
516 bool has_pending_interrupt() { | 485 bool has_pending_interrupt() { |
517 return thread_local_.has_pending_interrupt_; | 486 return thread_local_.has_pending_interrupt_; |
518 } | 487 } |
519 | 488 |
520 // Set specified interrupts as pending. | 489 // Set specified interrupts as pending. |
521 void set_has_pending_interrupt(bool value) { | 490 void set_has_pending_interrupt(bool value) { |
522 thread_local_.has_pending_interrupt_ = value; | 491 thread_local_.has_pending_interrupt_ = value; |
523 } | 492 } |
524 | 493 |
525 // Getter and setter for the disable break state. | |
526 bool disable_break() { return disable_break_; } | |
527 void set_disable_break(bool disable_break) { | |
528 disable_break_ = disable_break; | |
529 } | |
530 | |
531 // Getters for the current exception break state. | 494 // Getters for the current exception break state. |
532 bool break_on_exception() { return break_on_exception_; } | 495 bool break_on_exception() { return break_on_exception_; } |
533 bool break_on_uncaught_exception() { | 496 bool break_on_uncaught_exception() { |
534 return break_on_uncaught_exception_; | 497 return break_on_uncaught_exception_; |
535 } | 498 } |
536 | 499 |
537 void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, | 500 void FramesHaveBeenDropped(StackFrame::Id new_break_frame_id, |
538 LiveEdit::FrameDropMode mode, | 501 LiveEdit::FrameDropMode mode, |
539 Object** restarter_frame_function_pointer); | 502 Object** restarter_frame_function_pointer); |
540 | 503 |
(...skipping 15 matching lines...) Expand all Loading... |
556 | 519 |
557 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc | 520 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc |
558 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc | 521 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc |
559 | 522 |
560 // Threading support. | 523 // Threading support. |
561 char* ArchiveDebug(char* to); | 524 char* ArchiveDebug(char* to); |
562 char* RestoreDebug(char* from); | 525 char* RestoreDebug(char* from); |
563 static int ArchiveSpacePerThread(); | 526 static int ArchiveSpacePerThread(); |
564 void FreeThreadResources() { } | 527 void FreeThreadResources() { } |
565 | 528 |
566 // Mirror cache handling. | |
567 void ClearMirrorCache(); | |
568 | |
569 // Script cache handling. | 529 // Script cache handling. |
570 void CreateScriptCache(); | 530 void CreateScriptCache(); |
571 void DestroyScriptCache(); | 531 void DestroyScriptCache(); |
572 void AddScriptToScriptCache(Handle<Script> script); | 532 void AddScriptToScriptCache(Handle<Script> script); |
573 Handle<FixedArray> GetLoadedScripts(); | 533 Handle<FixedArray> GetLoadedScripts(); |
574 | 534 |
575 // Record function from which eval was called. | 535 // Record function from which eval was called. |
576 static void RecordEvalCaller(Handle<Script> script); | 536 static void RecordEvalCaller(Handle<Script> script); |
577 | 537 |
578 // Garbage collection notifications. | 538 // Garbage collection notifications. |
579 void AfterGarbageCollection(); | 539 void AfterGarbageCollection(); |
580 | 540 |
581 private: | 541 private: |
582 explicit Debug(Isolate* isolate); | 542 explicit Debug(Isolate* isolate); |
583 | 543 |
| 544 void UpdateState(); |
| 545 void Unload(); |
| 546 |
| 547 // Mirror cache handling. |
| 548 void ClearMirrorCache(); |
| 549 |
| 550 void SetNextBreakId() { |
| 551 thread_local_.break_id_ = ++thread_local_.break_count_; |
| 552 } |
| 553 |
| 554 // Check whether there are commands in the command queue. |
| 555 inline bool has_commands() const { return !command_queue_.IsEmpty(); } |
| 556 |
| 557 // Constructors for debug event objects. |
584 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( | 558 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject( |
585 Vector<const char> constructor_name, | 559 const char* constructor_name, |
586 int argc, | 560 int argc, |
587 Handle<Object> argv[]); | 561 Handle<Object> argv[]); |
588 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); | 562 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); |
589 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( | 563 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( |
590 Handle<Object> break_points_hit); | 564 Handle<Object> break_points_hit); |
591 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( | 565 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( |
592 Handle<Object> exception, | 566 Handle<Object> exception, |
593 bool uncaught, | 567 bool uncaught, |
594 Handle<Object> promise); | 568 Handle<Object> promise); |
595 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( | 569 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( |
596 Handle<Script> script, bool before); | 570 Handle<Script> script, bool before); |
597 MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id); | 571 MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id); |
598 | 572 |
| 573 |
599 void CallEventCallback(v8::DebugEvent event, | 574 void CallEventCallback(v8::DebugEvent event, |
600 Handle<Object> exec_state, | 575 Handle<Object> exec_state, |
601 Handle<Object> event_data, | 576 Handle<Object> event_data, |
602 v8::Debug::ClientData* client_data); | 577 v8::Debug::ClientData* client_data); |
603 void CallCEventCallback(v8::DebugEvent event, | |
604 Handle<Object> exec_state, | |
605 Handle<Object> event_data, | |
606 v8::Debug::ClientData* client_data); | |
607 void CallJSEventCallback(v8::DebugEvent event, | |
608 Handle<Object> exec_state, | |
609 Handle<Object> event_data); | |
610 void UpdateState(); | |
611 | 578 |
612 void ProcessDebugEvent(v8::DebugEvent event, | 579 void ProcessDebugEvent(v8::DebugEvent event, |
613 Handle<JSObject> event_data, | 580 Handle<JSObject> event_data, |
614 bool auto_continue); | 581 bool auto_continue); |
615 void NotifyMessageHandler(v8::DebugEvent event, | 582 void NotifyMessageHandler(v8::DebugEvent event, |
616 Handle<JSObject> exec_state, | 583 Handle<JSObject> exec_state, |
617 Handle<JSObject> event_data, | 584 Handle<JSObject> event_data, |
618 bool auto_continue); | 585 bool auto_continue); |
619 | 586 |
620 // Invoke the message handler function. | 587 // Invoke the message handler function. |
621 void InvokeMessageHandler(MessageImpl message); | 588 void InvokeMessageHandler(MessageImpl message); |
622 | 589 |
623 inline bool EventActive() { | 590 inline bool EventActive() { |
624 // Check whether the message handler was been cleared. | 591 // Check whether the message handler was been cleared. |
625 // TODO(yangguo): handle loading and unloading of the debugger differently. | 592 // TODO(yangguo): handle loading and unloading of the debugger differently. |
626 // Currently argument event is not used. | 593 // Currently argument event is not used. |
627 return !ignore_debugger_ && is_active_; | 594 return !is_suppressed_ && is_active_; |
628 } | 595 } |
629 | 596 |
630 static bool CompileDebuggerScript(Isolate* isolate, int index); | 597 static bool CompileDebuggerScript(Isolate* isolate, int index); |
631 void ClearOneShot(); | 598 void ClearOneShot(); |
632 void ActivateStepIn(StackFrame* frame); | 599 void ActivateStepIn(StackFrame* frame); |
633 void ClearStepIn(); | 600 void ClearStepIn(); |
634 void ActivateStepOut(StackFrame* frame); | 601 void ActivateStepOut(StackFrame* frame); |
635 void ClearStepNext(); | 602 void ClearStepNext(); |
636 // Returns whether the compile succeeded. | 603 // Returns whether the compile succeeded. |
637 void RemoveDebugInfo(Handle<DebugInfo> debug_info); | 604 void RemoveDebugInfo(Handle<DebugInfo> debug_info); |
(...skipping 28 matching lines...) Expand all Loading... |
666 Handle<Object> event_listener_data_; | 633 Handle<Object> event_listener_data_; |
667 | 634 |
668 v8::Debug::MessageHandler message_handler_; | 635 v8::Debug::MessageHandler message_handler_; |
669 | 636 |
670 static const int kQueueInitialSize = 4; | 637 static const int kQueueInitialSize = 4; |
671 Semaphore command_received_; // Signaled for each command received. | 638 Semaphore command_received_; // Signaled for each command received. |
672 LockingCommandMessageQueue command_queue_; | 639 LockingCommandMessageQueue command_queue_; |
673 LockingCommandMessageQueue event_command_queue_; | 640 LockingCommandMessageQueue event_command_queue_; |
674 | 641 |
675 bool is_active_; | 642 bool is_active_; |
676 bool ignore_debugger_; | 643 bool is_suppressed_; |
677 bool live_edit_enabled_; | 644 bool live_edit_enabled_; |
678 bool has_break_points_; | 645 bool has_break_points_; |
679 bool disable_break_; | 646 bool break_disabled_; |
680 bool break_on_exception_; | 647 bool break_on_exception_; |
681 bool break_on_uncaught_exception_; | 648 bool break_on_uncaught_exception_; |
682 | 649 |
683 ScriptCache* script_cache_; // Cache of all scripts in the heap. | 650 ScriptCache* script_cache_; // Cache of all scripts in the heap. |
684 DebugInfoListNode* debug_info_list_; // List of active debug info objects. | 651 DebugInfoListNode* debug_info_list_; // List of active debug info objects. |
685 | 652 |
686 // Storage location for jump when exiting debug break calls. | 653 // Storage location for jump when exiting debug break calls. |
687 // Note that this address is not GC safe. It should be computed immediately | 654 // Note that this address is not GC safe. It should be computed immediately |
688 // before returning to the DebugBreakCallHelper. | 655 // before returning to the DebugBreakCallHelper. |
689 Address after_break_target_; | 656 Address after_break_target_; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 }; | 713 }; |
747 | 714 |
748 // Storage location for registers when handling debug break calls | 715 // Storage location for registers when handling debug break calls |
749 ThreadLocal thread_local_; | 716 ThreadLocal thread_local_; |
750 | 717 |
751 Isolate* isolate_; | 718 Isolate* isolate_; |
752 | 719 |
753 friend class Isolate; | 720 friend class Isolate; |
754 friend class EnterDebugger; | 721 friend class EnterDebugger; |
755 friend class FrameDropper; | 722 friend class FrameDropper; |
| 723 friend class DisableBreak; |
| 724 friend class SuppressDebug; |
756 | 725 |
757 DISALLOW_COPY_AND_ASSIGN(Debug); | 726 DISALLOW_COPY_AND_ASSIGN(Debug); |
758 }; | 727 }; |
759 | 728 |
760 | 729 |
761 DECLARE_RUNTIME_FUNCTION(Debug_Break); | 730 DECLARE_RUNTIME_FUNCTION(Debug_Break); |
762 | 731 |
763 | 732 |
764 // This class is used for entering the debugger. Create an instance in the stack | 733 // This class is used for entering the debugger. Create an instance in the stack |
765 // to enter the debugger. This will set the current break state, make sure the | 734 // to enter the debugger. This will set the current break state, make sure the |
(...skipping 20 matching lines...) Expand all Loading... |
786 StackFrame::Id break_frame_id_; // Previous break frame id. | 755 StackFrame::Id break_frame_id_; // Previous break frame id. |
787 int break_id_; // Previous break id. | 756 int break_id_; // Previous break id. |
788 bool load_failed_; // Did the debugger fail to load? | 757 bool load_failed_; // Did the debugger fail to load? |
789 SaveContext save_; // Saves previous context. | 758 SaveContext save_; // Saves previous context. |
790 }; | 759 }; |
791 | 760 |
792 | 761 |
793 // Stack allocated class for disabling break. | 762 // Stack allocated class for disabling break. |
794 class DisableBreak BASE_EMBEDDED { | 763 class DisableBreak BASE_EMBEDDED { |
795 public: | 764 public: |
796 explicit DisableBreak(Isolate* isolate, bool disable_break) | 765 explicit DisableBreak(Debug* debug, bool disable_break) |
797 : isolate_(isolate) { | 766 : debug_(debug), old_state_(debug->break_disabled_) { |
798 prev_disable_break_ = isolate_->debug()->disable_break(); | 767 debug_->break_disabled_ = disable_break; |
799 isolate_->debug()->set_disable_break(disable_break); | |
800 } | 768 } |
801 ~DisableBreak() { | 769 ~DisableBreak() { debug_->break_disabled_ = old_state_; } |
802 isolate_->debug()->set_disable_break(prev_disable_break_); | |
803 } | |
804 | 770 |
805 private: | 771 private: |
806 Isolate* isolate_; | 772 Debug* debug_; |
807 // The previous state of the disable break used to restore the value when this | 773 bool old_state_; |
808 // object is destructed. | 774 DISALLOW_COPY_AND_ASSIGN(DisableBreak); |
809 bool prev_disable_break_; | |
810 }; | 775 }; |
811 | 776 |
812 | 777 |
| 778 class SuppressDebug BASE_EMBEDDED { |
| 779 public: |
| 780 explicit SuppressDebug(Debug* debug) |
| 781 : debug_(debug), old_state_(debug->is_suppressed_) { |
| 782 debug_->is_suppressed_ = true; |
| 783 } |
| 784 ~SuppressDebug() { debug_->is_suppressed_ = old_state_; } |
| 785 |
| 786 private: |
| 787 Debug* debug_; |
| 788 bool old_state_; |
| 789 DISALLOW_COPY_AND_ASSIGN(SuppressDebug); |
| 790 }; |
| 791 |
| 792 |
813 // Code generator routines. | 793 // Code generator routines. |
814 class DebugCodegen : public AllStatic { | 794 class DebugCodegen : public AllStatic { |
815 public: | 795 public: |
816 static void GenerateSlot(MacroAssembler* masm); | 796 static void GenerateSlot(MacroAssembler* masm); |
817 static void GenerateCallICStubDebugBreak(MacroAssembler* masm); | 797 static void GenerateCallICStubDebugBreak(MacroAssembler* masm); |
818 static void GenerateLoadICDebugBreak(MacroAssembler* masm); | 798 static void GenerateLoadICDebugBreak(MacroAssembler* masm); |
819 static void GenerateStoreICDebugBreak(MacroAssembler* masm); | 799 static void GenerateStoreICDebugBreak(MacroAssembler* masm); |
820 static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm); | 800 static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm); |
821 static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm); | 801 static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm); |
822 static void GenerateCompareNilICDebugBreak(MacroAssembler* masm); | 802 static void GenerateCompareNilICDebugBreak(MacroAssembler* masm); |
823 static void GenerateReturnDebugBreak(MacroAssembler* masm); | 803 static void GenerateReturnDebugBreak(MacroAssembler* masm); |
824 static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm); | 804 static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm); |
825 static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm); | 805 static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm); |
826 static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm); | 806 static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm); |
827 static void GenerateSlotDebugBreak(MacroAssembler* masm); | 807 static void GenerateSlotDebugBreak(MacroAssembler* masm); |
828 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm); | 808 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm); |
829 | 809 |
830 // FrameDropper is a code replacement for a JavaScript frame with possibly | 810 // FrameDropper is a code replacement for a JavaScript frame with possibly |
831 // several frames above. | 811 // several frames above. |
832 // There is no calling conventions here, because it never actually gets | 812 // There is no calling conventions here, because it never actually gets |
833 // called, it only gets returned to. | 813 // called, it only gets returned to. |
834 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); | 814 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm); |
835 }; | 815 }; |
836 | 816 |
837 | 817 |
838 } } // namespace v8::internal | 818 } } // namespace v8::internal |
839 | 819 |
840 #endif // V8_DEBUG_H_ | 820 #endif // V8_DEBUG_H_ |
OLD | NEW |