Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Side by Side Diff: src/debug/debug.h

Issue 2682593003: [debugger] implement legacy debug event listeners via debug delegate. (Closed)
Patch Set: addressed comments Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/api.cc ('k') | src/debug/debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_DEBUG_H_ 5 #ifndef V8_DEBUG_DEBUG_H_
6 #define V8_DEBUG_DEBUG_H_ 6 #define V8_DEBUG_DEBUG_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/assembler.h" 10 #include "src/assembler.h"
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); } 224 Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }
225 225
226 private: 226 private:
227 // Global (weak) handle to the debug info object. 227 // Global (weak) handle to the debug info object.
228 DebugInfo** debug_info_; 228 DebugInfo** debug_info_;
229 229
230 // Next pointer for linked list. 230 // Next pointer for linked list.
231 DebugInfoListNode* next_; 231 DebugInfoListNode* next_;
232 }; 232 };
233 233
234 // Details of the debug event delivered to the debug event listener.
235 class EventDetailsImpl : public v8::Debug::EventDetails {
236 public:
237 EventDetailsImpl(DebugEvent event, Handle<JSObject> exec_state,
238 Handle<JSObject> event_data, Handle<Object> callback_data);
239 virtual DebugEvent GetEvent() const;
240 virtual v8::Local<v8::Object> GetExecutionState() const;
241 virtual v8::Local<v8::Object> GetEventData() const;
242 virtual v8::Local<v8::Context> GetEventContext() const;
243 virtual v8::Local<v8::Value> GetCallbackData() const;
244 virtual v8::Debug::ClientData* GetClientData() const { return nullptr; }
245 virtual v8::Isolate* GetIsolate() const;
246
247 private:
248 DebugEvent event_; // Debug event causing the break.
249 Handle<JSObject> exec_state_; // Current execution state.
250 Handle<JSObject> event_data_; // Data associated with the event.
251 Handle<Object> callback_data_; // User data passed with the callback
252 // when it was registered.
253 };
254
255
256 class DebugFeatureTracker { 234 class DebugFeatureTracker {
257 public: 235 public:
258 enum Feature { 236 enum Feature {
259 kActive = 1, 237 kActive = 1,
260 kBreakPoint = 2, 238 kBreakPoint = 2,
261 kStepping = 3, 239 kStepping = 3,
262 kHeapSnapshot = 4, 240 kHeapSnapshot = 4,
263 kAllocationTracking = 5, 241 kAllocationTracking = 5,
264 kProfiler = 6, 242 kProfiler = 6,
265 kLiveEdit = 7, 243 kLiveEdit = 7,
(...skipping 18 matching lines...) Expand all
284 // DebugInfo. 262 // DebugInfo.
285 class Debug { 263 class Debug {
286 public: 264 public:
287 // Debug event triggers. 265 // Debug event triggers.
288 void OnDebugBreak(Handle<Object> break_points_hit); 266 void OnDebugBreak(Handle<Object> break_points_hit);
289 267
290 void OnThrow(Handle<Object> exception); 268 void OnThrow(Handle<Object> exception);
291 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); 269 void OnPromiseReject(Handle<Object> promise, Handle<Object> value);
292 void OnCompileError(Handle<Script> script); 270 void OnCompileError(Handle<Script> script);
293 void OnAfterCompile(Handle<Script> script); 271 void OnAfterCompile(Handle<Script> script);
294 void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id); 272 void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id,
273 int parent_id);
295 274
296 // API facing.
297 void SetEventListener(Handle<Object> callback, Handle<Object> data);
298 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, 275 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun,
299 Handle<Object> data); 276 Handle<Object> data);
300 Handle<Context> GetDebugContext(); 277 Handle<Context> GetDebugContext();
301 void HandleDebugBreak(); 278 void HandleDebugBreak();
302 279
303 // Internal logic 280 // Internal logic
304 bool Load(); 281 bool Load();
305 void Break(JavaScriptFrame* frame); 282 void Break(JavaScriptFrame* frame);
306 283
307 // Scripts handling. 284 // Scripts handling.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 317
341 void RecordGenerator(Handle<JSGeneratorObject> generator_object); 318 void RecordGenerator(Handle<JSGeneratorObject> generator_object);
342 319
343 void RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, 320 void RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise,
344 Handle<Object> parent); 321 Handle<Object> parent);
345 322
346 int NextAsyncTaskId(Handle<JSObject> promise); 323 int NextAsyncTaskId(Handle<JSObject> promise);
347 324
348 bool IsBlackboxed(Handle<SharedFunctionInfo> shared); 325 bool IsBlackboxed(Handle<SharedFunctionInfo> shared);
349 326
350 void SetDebugDelegate(debug::DebugDelegate* delegate); 327 void SetDebugDelegate(debug::DebugDelegate* delegate, bool pass_ownership);
351 328
352 // Returns whether the operation succeeded. 329 // Returns whether the operation succeeded.
353 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared); 330 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);
354 void CreateDebugInfo(Handle<SharedFunctionInfo> shared); 331 void CreateDebugInfo(Handle<SharedFunctionInfo> shared);
355 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); 332 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
356 333
357 template <typename C> 334 template <typename C>
358 bool CompileToRevealInnerFunctions(C* compilable); 335 bool CompileToRevealInnerFunctions(C* compilable);
359 336
360 // This function is used in FunctionNameUsing* tests. 337 // This function is used in FunctionNameUsing* tests.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 Address restart_fp_address() { 417 Address restart_fp_address() {
441 return reinterpret_cast<Address>(&thread_local_.restart_fp_); 418 return reinterpret_cast<Address>(&thread_local_.restart_fp_);
442 } 419 }
443 420
444 StepAction last_step_action() { return thread_local_.last_step_action_; } 421 StepAction last_step_action() { return thread_local_.last_step_action_; }
445 422
446 DebugFeatureTracker* feature_tracker() { return &feature_tracker_; } 423 DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }
447 424
448 private: 425 private:
449 explicit Debug(Isolate* isolate); 426 explicit Debug(Isolate* isolate);
427 ~Debug() { DCHECK_NULL(debug_delegate_); }
450 428
451 void UpdateState(); 429 void UpdateState();
452 void UpdateHookOnFunctionCall(); 430 void UpdateHookOnFunctionCall();
431 void RemoveDebugDelegate();
453 void Unload(); 432 void Unload();
454 void SetNextBreakId() { 433 void SetNextBreakId() {
455 thread_local_.break_id_ = ++thread_local_.break_count_; 434 thread_local_.break_id_ = ++thread_local_.break_count_;
456 } 435 }
457 436
458 // Return the number of virtual frames below debugger entry. 437 // Return the number of virtual frames below debugger entry.
459 int CurrentFrameCount(); 438 int CurrentFrameCount();
460 439
461 inline bool ignore_events() const { 440 inline bool ignore_events() const {
462 return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check(); 441 return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check();
463 } 442 }
464 inline bool break_disabled() const { 443 inline bool break_disabled() const { return break_disabled_; }
465 return break_disabled_ || in_debug_event_listener_;
466 }
467 444
468 void clear_suspended_generator() { 445 void clear_suspended_generator() {
469 thread_local_.suspended_generator_ = Smi::kZero; 446 thread_local_.suspended_generator_ = Smi::kZero;
470 } 447 }
471 448
472 bool has_suspended_generator() const { 449 bool has_suspended_generator() const {
473 return thread_local_.suspended_generator_ != Smi::kZero; 450 return thread_local_.suspended_generator_ != Smi::kZero;
474 } 451 }
475 452
476 // There are three types of event listeners: C++ message_handler,
477 // JavaScript event listener and C++ event listener.
478 // Currently inspector still uses C++ event listener and installs
479 // more specific event listeners for part of events. Calling of
480 // C++ event listener is redundant when more specific event listener
481 // is presented. Other clients can install JavaScript event listener
482 // (e.g. some of NodeJS module).
483 bool non_inspector_listener_exists() const {
484 return !event_listener_.is_null() && !event_listener_->IsForeign();
485 }
486
487 bool IsExceptionBlackboxed(bool uncaught); 453 bool IsExceptionBlackboxed(bool uncaught);
488 454
489 void OnException(Handle<Object> exception, Handle<Object> promise); 455 void OnException(Handle<Object> exception, Handle<Object> promise);
490 456
491 // Constructors for debug event objects. 457 // Constructors for debug event objects.
492 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); 458 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
493 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( 459 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
494 Handle<Object> break_points_hit); 460 Handle<Object> break_points_hit);
495 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( 461 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
496 Handle<Object> exception, 462 Handle<Object> exception,
497 bool uncaught, 463 bool uncaught,
498 Handle<Object> promise); 464 Handle<Object> promise);
499 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( 465 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
500 Handle<Script> script, v8::DebugEvent type); 466 Handle<Script> script, v8::DebugEvent type);
501 MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<Smi> type, 467 MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
502 Handle<Smi> id); 468 v8::debug::PromiseDebugActionType type, int id);
503 469
504 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); 470 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script);
505 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); 471 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data);
506 472
507 // Find the closest source position for a break point for a given position. 473 // Find the closest source position for a break point for a given position.
508 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, 474 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position,
509 BreakPositionAlignment alignment); 475 BreakPositionAlignment alignment);
510 // Instrument code to break at break points. 476 // Instrument code to break at break points.
511 void ApplyBreakPoints(Handle<DebugInfo> debug_info); 477 void ApplyBreakPoints(Handle<DebugInfo> debug_info);
512 // Clear code from instrumentation. 478 // Clear code from instrumentation.
(...skipping 19 matching lines...) Expand all
532 DCHECK(isolate_->context() == *debug_context()); 498 DCHECK(isolate_->context() == *debug_context());
533 DCHECK(in_debug_scope()); 499 DCHECK(in_debug_scope());
534 } 500 }
535 501
536 void ThreadInit(); 502 void ThreadInit();
537 503
538 void PrintBreakLocation(); 504 void PrintBreakLocation();
539 505
540 // Global handles. 506 // Global handles.
541 Handle<Context> debug_context_; 507 Handle<Context> debug_context_;
542 Handle<Object> event_listener_;
543 Handle<Object> event_listener_data_;
544 508
545 debug::DebugDelegate* debug_delegate_ = nullptr; 509 debug::DebugDelegate* debug_delegate_ = nullptr;
510 bool owns_debug_delegate_ = false;
546 511
547 // Debugger is active, i.e. there is a debug event listener attached. 512 // Debugger is active, i.e. there is a debug event listener attached.
548 bool is_active_; 513 bool is_active_;
549 // Debugger needs to be notified on every new function call. 514 // Debugger needs to be notified on every new function call.
550 // Used for stepping and read-only checks 515 // Used for stepping and read-only checks
551 bool hook_on_function_call_; 516 bool hook_on_function_call_;
552 // Suppress debug events. 517 // Suppress debug events.
553 bool is_suppressed_; 518 bool is_suppressed_;
554 // LiveEdit is enabled. 519 // LiveEdit is enabled.
555 bool live_edit_enabled_; 520 bool live_edit_enabled_;
556 // Do not trigger debug break events. 521 // Do not trigger debug break events.
557 bool break_disabled_; 522 bool break_disabled_;
558 // Do not break on break points. 523 // Do not break on break points.
559 bool break_points_active_; 524 bool break_points_active_;
560 // Nested inside a debug event listener.
561 bool in_debug_event_listener_;
562 // Trigger debug break events for all exceptions. 525 // Trigger debug break events for all exceptions.
563 bool break_on_exception_; 526 bool break_on_exception_;
564 // Trigger debug break events for uncaught exceptions. 527 // Trigger debug break events for uncaught exceptions.
565 bool break_on_uncaught_exception_; 528 bool break_on_uncaught_exception_;
566 // Termination exception because side effect check has failed. 529 // Termination exception because side effect check has failed.
567 bool side_effect_check_failed_; 530 bool side_effect_check_failed_;
568 531
569 // List of active debug info objects. 532 // List of active debug info objects.
570 DebugInfoListNode* debug_info_list_; 533 DebugInfoListNode* debug_info_list_;
571 534
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 ThreadLocal thread_local_; 578 ThreadLocal thread_local_;
616 579
617 Isolate* isolate_; 580 Isolate* isolate_;
618 581
619 friend class Isolate; 582 friend class Isolate;
620 friend class DebugScope; 583 friend class DebugScope;
621 friend class DisableBreak; 584 friend class DisableBreak;
622 friend class LiveEdit; 585 friend class LiveEdit;
623 friend class SuppressDebug; 586 friend class SuppressDebug;
624 friend class NoSideEffectScope; 587 friend class NoSideEffectScope;
588 friend class LegacyDebugDelegate;
625 589
626 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc 590 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc
627 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc 591 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc
628 592
629 DISALLOW_COPY_AND_ASSIGN(Debug); 593 DISALLOW_COPY_AND_ASSIGN(Debug);
630 }; 594 };
631 595
596 class LegacyDebugDelegate : public v8::debug::DebugDelegate {
597 public:
598 explicit LegacyDebugDelegate(Isolate* isolate) : isolate_(isolate) {}
599 void PromiseEventOccurred(v8::debug::PromiseDebugActionType type, int id,
600 int parent_id) override;
601 void ScriptCompiled(v8::Local<v8::debug::Script> script,
602 bool has_compile_error) override;
603 void BreakProgramRequested(v8::Local<v8::Context> paused_context,
604 v8::Local<v8::Object> exec_state,
605 v8::Local<v8::Value> break_points_hit) override;
606 void ExceptionThrown(v8::Local<v8::Context> paused_context,
607 v8::Local<v8::Object> exec_state,
608 v8::Local<v8::Value> exception,
609 v8::Local<v8::Value> promise, bool is_uncaught) override;
610 bool IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
611 const v8::debug::Location& start,
612 const v8::debug::Location& end) override {
613 return false;
614 }
615
616 protected:
617 Isolate* isolate_;
618
619 private:
620 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data);
621 virtual void ProcessDebugEvent(v8::DebugEvent event,
622 Handle<JSObject> event_data,
623 Handle<JSObject> exec_state) = 0;
624 };
625
626 class JavaScriptDebugDelegate : public LegacyDebugDelegate {
627 public:
628 JavaScriptDebugDelegate(Isolate* isolate, Handle<JSFunction> listener,
629 Handle<Object> data);
630 virtual ~JavaScriptDebugDelegate();
631
632 private:
633 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data,
634 Handle<JSObject> exec_state) override;
635
636 Handle<JSFunction> listener_;
637 Handle<Object> data_;
638 };
639
640 class NativeDebugDelegate : public LegacyDebugDelegate {
641 public:
642 NativeDebugDelegate(Isolate* isolate, v8::Debug::EventCallback callback,
643 Handle<Object> data);
644 virtual ~NativeDebugDelegate();
645
646 private:
647 // Details of the debug event delivered to the debug event listener.
648 class EventDetails : public v8::Debug::EventDetails {
649 public:
650 EventDetails(DebugEvent event, Handle<JSObject> exec_state,
651 Handle<JSObject> event_data, Handle<Object> callback_data);
652 virtual DebugEvent GetEvent() const;
653 virtual v8::Local<v8::Object> GetExecutionState() const;
654 virtual v8::Local<v8::Object> GetEventData() const;
655 virtual v8::Local<v8::Context> GetEventContext() const;
656 virtual v8::Local<v8::Value> GetCallbackData() const;
657 virtual v8::Debug::ClientData* GetClientData() const { return nullptr; }
658 virtual v8::Isolate* GetIsolate() const;
659
660 private:
661 DebugEvent event_; // Debug event causing the break.
662 Handle<JSObject> exec_state_; // Current execution state.
663 Handle<JSObject> event_data_; // Data associated with the event.
664 Handle<Object> callback_data_; // User data passed with the callback
665 // when it was registered.
666 };
667
668 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data,
669 Handle<JSObject> exec_state) override;
670
671 v8::Debug::EventCallback callback_;
672 Handle<Object> data_;
673 };
632 674
633 // This scope is used to load and enter the debug context and create a new 675 // This scope is used to load and enter the debug context and create a new
634 // break state. Leaving the scope will restore the previous state. 676 // break state. Leaving the scope will restore the previous state.
635 // On failure to load, FailedToEnter returns true. 677 // On failure to load, FailedToEnter returns true.
636 class DebugScope BASE_EMBEDDED { 678 class DebugScope BASE_EMBEDDED {
637 public: 679 public:
638 explicit DebugScope(Debug* debug); 680 explicit DebugScope(Debug* debug);
639 ~DebugScope(); 681 ~DebugScope();
640 682
641 // Check whether loading was successful. 683 // Check whether loading was successful.
(...skipping 13 matching lines...) Expand all
655 bool failed_; // Did the debug context fail to load? 697 bool failed_; // Did the debug context fail to load?
656 SaveContext save_; // Saves previous context. 698 SaveContext save_; // Saves previous context.
657 PostponeInterruptsScope no_termination_exceptons_; 699 PostponeInterruptsScope no_termination_exceptons_;
658 }; 700 };
659 701
660 702
661 // Stack allocated class for disabling break. 703 // Stack allocated class for disabling break.
662 class DisableBreak BASE_EMBEDDED { 704 class DisableBreak BASE_EMBEDDED {
663 public: 705 public:
664 explicit DisableBreak(Debug* debug) 706 explicit DisableBreak(Debug* debug)
665 : debug_(debug), 707 : debug_(debug), previous_break_disabled_(debug->break_disabled_) {
666 previous_break_disabled_(debug->break_disabled_),
667 previous_in_debug_event_listener_(debug->in_debug_event_listener_) {
668 debug_->break_disabled_ = true; 708 debug_->break_disabled_ = true;
669 debug_->in_debug_event_listener_ = true;
670 } 709 }
671 ~DisableBreak() { 710 ~DisableBreak() {
672 debug_->break_disabled_ = previous_break_disabled_; 711 debug_->break_disabled_ = previous_break_disabled_;
673 debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
674 } 712 }
675 713
676 private: 714 private:
677 Debug* debug_; 715 Debug* debug_;
678 bool previous_break_disabled_; 716 bool previous_break_disabled_;
679 bool previous_in_debug_event_listener_;
680 DISALLOW_COPY_AND_ASSIGN(DisableBreak); 717 DISALLOW_COPY_AND_ASSIGN(DisableBreak);
681 }; 718 };
682 719
683 720
684 class SuppressDebug BASE_EMBEDDED { 721 class SuppressDebug BASE_EMBEDDED {
685 public: 722 public:
686 explicit SuppressDebug(Debug* debug) 723 explicit SuppressDebug(Debug* debug)
687 : debug_(debug), old_state_(debug->is_suppressed_) { 724 : debug_(debug), old_state_(debug->is_suppressed_) {
688 debug_->is_suppressed_ = true; 725 debug_->is_suppressed_ = true;
689 } 726 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 Handle<Code> code); 774 Handle<Code> code);
738 static bool DebugBreakSlotIsPatched(Address pc); 775 static bool DebugBreakSlotIsPatched(Address pc);
739 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); 776 static void ClearDebugBreakSlot(Isolate* isolate, Address pc);
740 }; 777 };
741 778
742 779
743 } // namespace internal 780 } // namespace internal
744 } // namespace v8 781 } // namespace v8
745 782
746 #endif // V8_DEBUG_DEBUG_H_ 783 #endif // V8_DEBUG_DEBUG_H_
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/debug/debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698