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

Side by Side Diff: src/debug.h

Issue 301633005: Merge Debugger and Debug. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler.cc ('k') | src/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_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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 Handle<DebugInfo> debug_info() { return debug_info_; } 195 Handle<DebugInfo> debug_info() { return debug_info_; }
196 196
197 private: 197 private:
198 // Global (weak) handle to the debug info object. 198 // Global (weak) handle to the debug info object.
199 Handle<DebugInfo> debug_info_; 199 Handle<DebugInfo> debug_info_;
200 200
201 // Next pointer for linked list. 201 // Next pointer for linked list.
202 DebugInfoListNode* next_; 202 DebugInfoListNode* next_;
203 }; 203 };
204 204
205
206
207 // Message delivered to the message handler callback. This is either a debugger
208 // event or the response to a command.
209 class MessageImpl: public v8::Debug::Message {
210 public:
211 // Create a message object for a debug event.
212 static MessageImpl NewEvent(DebugEvent event,
213 bool running,
214 Handle<JSObject> exec_state,
215 Handle<JSObject> event_data);
216
217 // Create a message object for the response to a debug command.
218 static MessageImpl NewResponse(DebugEvent event,
219 bool running,
220 Handle<JSObject> exec_state,
221 Handle<JSObject> event_data,
222 Handle<String> response_json,
223 v8::Debug::ClientData* client_data);
224
225 // Implementation of interface v8::Debug::Message.
226 virtual bool IsEvent() const;
227 virtual bool IsResponse() const;
228 virtual DebugEvent GetEvent() const;
229 virtual bool WillStartRunning() const;
230 virtual v8::Handle<v8::Object> GetExecutionState() const;
231 virtual v8::Handle<v8::Object> GetEventData() const;
232 virtual v8::Handle<v8::String> GetJSON() const;
233 virtual v8::Handle<v8::Context> GetEventContext() const;
234 virtual v8::Debug::ClientData* GetClientData() const;
235 virtual v8::Isolate* GetIsolate() const;
236
237 private:
238 MessageImpl(bool is_event,
239 DebugEvent event,
240 bool running,
241 Handle<JSObject> exec_state,
242 Handle<JSObject> event_data,
243 Handle<String> response_json,
244 v8::Debug::ClientData* client_data);
245
246 bool is_event_; // Does this message represent a debug event?
247 DebugEvent event_; // Debug event causing the break.
248 bool running_; // Will the VM start running after this event?
249 Handle<JSObject> exec_state_; // Current execution state.
250 Handle<JSObject> event_data_; // Data associated with the event.
251 Handle<String> response_json_; // Response JSON if message holds a response.
252 v8::Debug::ClientData* client_data_; // Client data passed with the request.
253 };
254
255
256 // Details of the debug event delivered to the debug event listener.
257 class EventDetailsImpl : public v8::Debug::EventDetails {
258 public:
259 EventDetailsImpl(DebugEvent event,
260 Handle<JSObject> exec_state,
261 Handle<JSObject> event_data,
262 Handle<Object> callback_data,
263 v8::Debug::ClientData* client_data);
264 virtual DebugEvent GetEvent() const;
265 virtual v8::Handle<v8::Object> GetExecutionState() const;
266 virtual v8::Handle<v8::Object> GetEventData() const;
267 virtual v8::Handle<v8::Context> GetEventContext() const;
268 virtual v8::Handle<v8::Value> GetCallbackData() const;
269 virtual v8::Debug::ClientData* GetClientData() const;
270 private:
271 DebugEvent event_; // Debug event causing the break.
272 Handle<JSObject> exec_state_; // Current execution state.
273 Handle<JSObject> event_data_; // Data associated with the event.
274 Handle<Object> callback_data_; // User data passed with the callback
275 // when it was registered.
276 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand.
277 };
278
279
280 // Message send by user to v8 debugger or debugger output message.
281 // In addition to command text it may contain a pointer to some user data
282 // which are expected to be passed along with the command reponse to message
283 // handler.
284 class CommandMessage {
285 public:
286 static CommandMessage New(const Vector<uint16_t>& command,
287 v8::Debug::ClientData* data);
288 CommandMessage();
289 ~CommandMessage();
290
291 // Deletes user data and disposes of the text.
292 void Dispose();
293 Vector<uint16_t> text() const { return text_; }
294 v8::Debug::ClientData* client_data() const { return client_data_; }
295 private:
296 CommandMessage(const Vector<uint16_t>& text,
297 v8::Debug::ClientData* data);
298
299 Vector<uint16_t> text_;
300 v8::Debug::ClientData* client_data_;
301 };
302
303
304 // A Queue of CommandMessage objects. A thread-safe version is
305 // LockingCommandMessageQueue, based on this class.
306 class CommandMessageQueue BASE_EMBEDDED {
307 public:
308 explicit CommandMessageQueue(int size);
309 ~CommandMessageQueue();
310 bool IsEmpty() const { return start_ == end_; }
311 CommandMessage Get();
312 void Put(const CommandMessage& message);
313 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear().
314 private:
315 // Doubles the size of the message queue, and copies the messages.
316 void Expand();
317
318 CommandMessage* messages_;
319 int start_;
320 int end_;
321 int size_; // The size of the queue buffer. Queue can hold size-1 messages.
322 };
323
324
325 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
326 // messages. The message data is not managed by LockingCommandMessageQueue.
327 // Pointers to the data are passed in and out. Implemented by adding a
328 // Mutex to CommandMessageQueue. Includes logging of all puts and gets.
329 class LockingCommandMessageQueue BASE_EMBEDDED {
330 public:
331 LockingCommandMessageQueue(Logger* logger, int size);
332 bool IsEmpty() const;
333 CommandMessage Get();
334 void Put(const CommandMessage& message);
335 void Clear();
336 private:
337 Logger* logger_;
338 CommandMessageQueue queue_;
339 mutable Mutex mutex_;
340 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
341 };
342
343
205 // This class contains the debugger support. The main purpose is to handle 344 // This class contains the debugger support. The main purpose is to handle
206 // setting break points in the code. 345 // setting break points in the code.
207 // 346 //
208 // This class controls the debug info for all functions which currently have 347 // This class controls the debug info for all functions which currently have
209 // active breakpoints in them. This debug info is held in the heap root object 348 // active breakpoints in them. This debug info is held in the heap root object
210 // debug_info which is a FixedArray. Each entry in this list is of class 349 // debug_info which is a FixedArray. Each entry in this list is of class
211 // DebugInfo. 350 // DebugInfo.
212 class Debug { 351 class Debug {
213 public: 352 public:
353 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
354 void OnException(Handle<Object> exception, bool uncaught);
355 void OnBeforeCompile(Handle<Script> script);
356
357 enum AfterCompileFlags {
358 NO_AFTER_COMPILE_FLAGS,
359 SEND_WHEN_DEBUGGING
360 };
361 void OnAfterCompile(Handle<Script> script,
362 AfterCompileFlags after_compile_flags);
363 void OnScriptCollected(int id);
364
365 void SetEventListener(Handle<Object> callback, Handle<Object> data);
366 void SetMessageHandler(v8::Debug::MessageHandler handler);
367
368 // Add a debugger command to the command queue.
369 void EnqueueCommandMessage(Vector<const uint16_t> command,
370 v8::Debug::ClientData* client_data = NULL);
371
372 // Check whether there are commands in the command queue.
373 bool HasCommands();
374
375 // Enqueue a debugger command to the command queue for event listeners.
376 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL);
377
378 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
379 Handle<Object> data);
380
381 Handle<Context> GetDebugContext();
382
383 bool ignore_debugger() const { return ignore_debugger_; }
384 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
385 bool live_edit_enabled() const {
386 return FLAG_enable_liveedit && live_edit_enabled_ ;
387 }
388
389 bool is_active() { return is_active_; }
390
391 class IgnoreScope {
392 public:
393 explicit IgnoreScope(Debug* debug)
394 : debug_(debug),
395 old_state_(debug->ignore_debugger_) {
396 debug_->ignore_debugger_ = true;
397 }
398
399 ~IgnoreScope() {
400 debug_->ignore_debugger_ = old_state_;
401 }
402
403 private:
404 Debug* debug_;
405 bool old_state_;
406 DISALLOW_COPY_AND_ASSIGN(IgnoreScope);
407 };
408
409
214 bool Load(); 410 bool Load();
215 void Unload(); 411 void Unload();
216 bool IsLoaded() { return !debug_context_.is_null(); } 412 bool IsLoaded() { return !debug_context_.is_null(); }
217 bool InDebugger() { return thread_local_.debugger_entry_ != NULL; } 413 bool InDebugger() { return thread_local_.debugger_entry_ != NULL; }
218 414
219 Object* Break(Arguments args); 415 Object* Break(Arguments args);
220 bool SetBreakPoint(Handle<JSFunction> function, 416 bool SetBreakPoint(Handle<JSFunction> function,
221 Handle<Object> break_point_object, 417 Handle<Object> break_point_object,
222 int* source_position); 418 int* source_position);
223 bool SetBreakPointForScript(Handle<Script> script, 419 bool SetBreakPointForScript(Handle<Script> script,
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 return reinterpret_cast<Address>(address); 547 return reinterpret_cast<Address>(address);
352 } 548 }
353 549
354 static const int kEstimatedNofDebugInfoEntries = 16; 550 static const int kEstimatedNofDebugInfoEntries = 16;
355 static const int kEstimatedNofBreakPointsInFunction = 16; 551 static const int kEstimatedNofBreakPointsInFunction = 16;
356 552
357 // Passed to MakeWeak. 553 // Passed to MakeWeak.
358 static void HandleWeakDebugInfo( 554 static void HandleWeakDebugInfo(
359 const v8::WeakCallbackData<v8::Value, void>& data); 555 const v8::WeakCallbackData<v8::Value, void>& data);
360 556
361 friend class Debugger;
362 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc 557 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc
363 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc 558 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc
364 559
365 // Threading support. 560 // Threading support.
366 char* ArchiveDebug(char* to); 561 char* ArchiveDebug(char* to);
367 char* RestoreDebug(char* from); 562 char* RestoreDebug(char* from);
368 static int ArchiveSpacePerThread(); 563 static int ArchiveSpacePerThread();
369 void FreeThreadResources() { } 564 void FreeThreadResources() { }
370 565
371 // Mirror cache handling. 566 // Mirror cache handling.
372 void ClearMirrorCache(); 567 void ClearMirrorCache();
373 568
374 // Script cache handling. 569 // Script cache handling.
375 void CreateScriptCache(); 570 void CreateScriptCache();
376 void DestroyScriptCache(); 571 void DestroyScriptCache();
377 void AddScriptToScriptCache(Handle<Script> script); 572 void AddScriptToScriptCache(Handle<Script> script);
378 Handle<FixedArray> GetLoadedScripts(); 573 Handle<FixedArray> GetLoadedScripts();
379 574
380 // Record function from which eval was called. 575 // Record function from which eval was called.
381 static void RecordEvalCaller(Handle<Script> script); 576 static void RecordEvalCaller(Handle<Script> script);
382 577
383 // Garbage collection notifications. 578 // Garbage collection notifications.
384 void AfterGarbageCollection(); 579 void AfterGarbageCollection();
385 580
386 // Code generator routines.
387 static void GenerateSlot(MacroAssembler* masm);
388 static void GenerateCallICStubDebugBreak(MacroAssembler* masm);
389 static void GenerateLoadICDebugBreak(MacroAssembler* masm);
390 static void GenerateStoreICDebugBreak(MacroAssembler* masm);
391 static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm);
392 static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm);
393 static void GenerateCompareNilICDebugBreak(MacroAssembler* masm);
394 static void GenerateReturnDebugBreak(MacroAssembler* masm);
395 static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm);
396 static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm);
397 static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm);
398 static void GenerateSlotDebugBreak(MacroAssembler* masm);
399 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
400
401 // FrameDropper is a code replacement for a JavaScript frame with possibly
402 // several frames above.
403 // There is no calling conventions here, because it never actually gets
404 // called, it only gets returned to.
405 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
406
407 // Describes how exactly a frame has been dropped from stack. 581 // Describes how exactly a frame has been dropped from stack.
408 enum FrameDropMode { 582 enum FrameDropMode {
409 // No frame has been dropped. 583 // No frame has been dropped.
410 FRAMES_UNTOUCHED, 584 FRAMES_UNTOUCHED,
411 // The top JS frame had been calling IC stub. IC stub mustn't be called now. 585 // The top JS frame had been calling IC stub. IC stub mustn't be called now.
412 FRAME_DROPPED_IN_IC_CALL, 586 FRAME_DROPPED_IN_IC_CALL,
413 // The top JS frame had been calling debug break slot stub. Patch the 587 // The top JS frame had been calling debug break slot stub. Patch the
414 // address this stub jumps to in the end. 588 // address this stub jumps to in the end.
415 FRAME_DROPPED_IN_DEBUG_SLOT_CALL, 589 FRAME_DROPPED_IN_DEBUG_SLOT_CALL,
416 // The top JS frame had been calling some C++ function. The return address 590 // The top JS frame had been calling some C++ function. The return address
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 // Normally equals 1. Stored on stack in form of Smi. 654 // Normally equals 1. Stored on stack in form of Smi.
481 static const int kInitialSize; 655 static const int kInitialSize;
482 // A value that padding words are filled with (in form of Smi). Going 656 // A value that padding words are filled with (in form of Smi). Going
483 // bottom-top, the first word not having this value is a counter word. 657 // bottom-top, the first word not having this value is a counter word.
484 static const int kPaddingValue; 658 static const int kPaddingValue;
485 }; 659 };
486 660
487 private: 661 private:
488 explicit Debug(Isolate* isolate); 662 explicit Debug(Isolate* isolate);
489 663
664 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
665 Vector<const char> constructor_name,
666 int argc,
667 Handle<Object> argv[]);
668 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
669 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
670 Handle<Object> break_points_hit);
671 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
672 Handle<Object> exception,
673 bool uncaught,
674 Handle<Object> promise);
675 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
676 Handle<Script> script, bool before);
677 MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
678
679 void CallEventCallback(v8::DebugEvent event,
680 Handle<Object> exec_state,
681 Handle<Object> event_data,
682 v8::Debug::ClientData* client_data);
683 void CallCEventCallback(v8::DebugEvent event,
684 Handle<Object> exec_state,
685 Handle<Object> event_data,
686 v8::Debug::ClientData* client_data);
687 void CallJSEventCallback(v8::DebugEvent event,
688 Handle<Object> exec_state,
689 Handle<Object> event_data);
690 void UpdateState();
691
692 void ProcessDebugEvent(v8::DebugEvent event,
693 Handle<JSObject> event_data,
694 bool auto_continue);
695 void NotifyMessageHandler(v8::DebugEvent event,
696 Handle<JSObject> exec_state,
697 Handle<JSObject> event_data,
698 bool auto_continue);
699
700 // Invoke the message handler function.
701 void InvokeMessageHandler(MessageImpl message);
702
703 inline bool EventActive() {
704 // Check whether the message handler was been cleared.
705 // TODO(yangguo): handle loading and unloading of the debugger differently.
706 // Currently argument event is not used.
707 return !ignore_debugger_ && is_active_;
708 }
709
490 static bool CompileDebuggerScript(Isolate* isolate, int index); 710 static bool CompileDebuggerScript(Isolate* isolate, int index);
491 void ClearOneShot(); 711 void ClearOneShot();
492 void ActivateStepIn(StackFrame* frame); 712 void ActivateStepIn(StackFrame* frame);
493 void ClearStepIn(); 713 void ClearStepIn();
494 void ActivateStepOut(StackFrame* frame); 714 void ActivateStepOut(StackFrame* frame);
495 void ClearStepNext(); 715 void ClearStepNext();
496 // Returns whether the compile succeeded. 716 // Returns whether the compile succeeded.
497 void RemoveDebugInfo(Handle<DebugInfo> debug_info); 717 void RemoveDebugInfo(Handle<DebugInfo> debug_info);
498 void SetAfterBreakTarget(JavaScriptFrame* frame); 718 void SetAfterBreakTarget(JavaScriptFrame* frame);
499 Handle<Object> CheckBreakPoints(Handle<Object> break_point); 719 Handle<Object> CheckBreakPoints(Handle<Object> break_point);
500 bool CheckBreakPoint(Handle<Object> break_point_object); 720 bool CheckBreakPoint(Handle<Object> break_point_object);
501 721
502 void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function); 722 void EnsureFunctionHasDebugBreakSlots(Handle<JSFunction> function);
503 void RecompileAndRelocateSuspendedGenerators( 723 void RecompileAndRelocateSuspendedGenerators(
504 const List<Handle<JSGeneratorObject> > &suspended_generators); 724 const List<Handle<JSGeneratorObject> > &suspended_generators);
505 725
506 // Global handle to debug context where all the debugger JavaScript code is 726 void ThreadInit();
507 // loaded.
508 Handle<Context> debug_context_;
509
510 // Boolean state indicating whether any break points are set.
511 bool has_break_points_;
512
513 // Cache of all scripts in the heap.
514 ScriptCache* script_cache_;
515
516 // List of active debug info objects.
517 DebugInfoListNode* debug_info_list_;
518
519 bool disable_break_;
520 bool break_on_exception_;
521 bool break_on_uncaught_exception_;
522 727
523 class PromiseOnStack { 728 class PromiseOnStack {
524 public: 729 public:
525 PromiseOnStack(Isolate* isolate, 730 PromiseOnStack(Isolate* isolate,
526 PromiseOnStack* prev, 731 PromiseOnStack* prev,
527 Handle<JSFunction> getter); 732 Handle<JSFunction> getter);
528 ~PromiseOnStack(); 733 ~PromiseOnStack();
529 StackHandler* handler() { return handler_; } 734 StackHandler* handler() { return handler_; }
530 Handle<JSFunction> getter() { return getter_; } 735 Handle<JSFunction> getter() { return getter_; }
531 PromiseOnStack* prev() { return prev_; } 736 PromiseOnStack* prev() { return prev_; }
532 private: 737 private:
533 Isolate* isolate_; 738 Isolate* isolate_;
534 StackHandler* handler_; 739 StackHandler* handler_;
535 Handle<JSFunction> getter_; 740 Handle<JSFunction> getter_;
536 PromiseOnStack* prev_; 741 PromiseOnStack* prev_;
537 }; 742 };
538 743
744 // Global handles.
745 Handle<Context> debug_context_;
746 Handle<Object> event_listener_;
747 Handle<Object> event_listener_data_;
748
749 v8::Debug::MessageHandler message_handler_;
750
751 static const int kQueueInitialSize = 4;
752 Semaphore command_received_; // Signaled for each command received.
753 LockingCommandMessageQueue command_queue_;
754 LockingCommandMessageQueue event_command_queue_;
755
756 bool is_active_;
757 bool ignore_debugger_;
758 bool live_edit_enabled_;
759 bool has_break_points_;
760 bool disable_break_;
761 bool break_on_exception_;
762 bool break_on_uncaught_exception_;
763
764 ScriptCache* script_cache_; // Cache of all scripts in the heap.
765 DebugInfoListNode* debug_info_list_; // List of active debug info objects.
766
539 // Per-thread data. 767 // Per-thread data.
540 class ThreadLocal { 768 class ThreadLocal {
541 public: 769 public:
542 // Counter for generating next break id. 770 // Counter for generating next break id.
543 int break_count_; 771 int break_count_;
544 772
545 // Current break id. 773 // Current break id.
546 int break_id_; 774 int break_id_;
547 775
548 // Frame id for the frame of the current break. 776 // Frame id for the frame of the current break.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 // When a promise is being resolved, we may want to trigger a debug event 819 // When a promise is being resolved, we may want to trigger a debug event
592 // if we catch a throw. For this purpose we remember the try-catch 820 // if we catch a throw. For this purpose we remember the try-catch
593 // handler address that would catch the exception. We also hold onto a 821 // handler address that would catch the exception. We also hold onto a
594 // closure that returns a promise if the exception is considered uncaught. 822 // closure that returns a promise if the exception is considered uncaught.
595 // Due to the possibility of reentry we use a linked list. 823 // Due to the possibility of reentry we use a linked list.
596 PromiseOnStack* promise_on_stack_; 824 PromiseOnStack* promise_on_stack_;
597 }; 825 };
598 826
599 // Storage location for registers when handling debug break calls 827 // Storage location for registers when handling debug break calls
600 ThreadLocal thread_local_; 828 ThreadLocal thread_local_;
601 void ThreadInit();
602 829
603 Isolate* isolate_; 830 Isolate* isolate_;
604 831
605 friend class Isolate; 832 friend class Isolate;
833 friend class EnterDebugger;
606 834
607 DISALLOW_COPY_AND_ASSIGN(Debug); 835 DISALLOW_COPY_AND_ASSIGN(Debug);
608 }; 836 };
609 837
610 838
611 DECLARE_RUNTIME_FUNCTION(Debug_Break); 839 DECLARE_RUNTIME_FUNCTION(Debug_Break);
612 840
613 841
614 // Message delivered to the message handler callback. This is either a debugger
615 // event or the response to a command.
616 class MessageImpl: public v8::Debug::Message {
617 public:
618 // Create a message object for a debug event.
619 static MessageImpl NewEvent(DebugEvent event,
620 bool running,
621 Handle<JSObject> exec_state,
622 Handle<JSObject> event_data);
623
624 // Create a message object for the response to a debug command.
625 static MessageImpl NewResponse(DebugEvent event,
626 bool running,
627 Handle<JSObject> exec_state,
628 Handle<JSObject> event_data,
629 Handle<String> response_json,
630 v8::Debug::ClientData* client_data);
631
632 // Implementation of interface v8::Debug::Message.
633 virtual bool IsEvent() const;
634 virtual bool IsResponse() const;
635 virtual DebugEvent GetEvent() const;
636 virtual bool WillStartRunning() const;
637 virtual v8::Handle<v8::Object> GetExecutionState() const;
638 virtual v8::Handle<v8::Object> GetEventData() const;
639 virtual v8::Handle<v8::String> GetJSON() const;
640 virtual v8::Handle<v8::Context> GetEventContext() const;
641 virtual v8::Debug::ClientData* GetClientData() const;
642 virtual v8::Isolate* GetIsolate() const;
643
644 private:
645 MessageImpl(bool is_event,
646 DebugEvent event,
647 bool running,
648 Handle<JSObject> exec_state,
649 Handle<JSObject> event_data,
650 Handle<String> response_json,
651 v8::Debug::ClientData* client_data);
652
653 bool is_event_; // Does this message represent a debug event?
654 DebugEvent event_; // Debug event causing the break.
655 bool running_; // Will the VM start running after this event?
656 Handle<JSObject> exec_state_; // Current execution state.
657 Handle<JSObject> event_data_; // Data associated with the event.
658 Handle<String> response_json_; // Response JSON if message holds a response.
659 v8::Debug::ClientData* client_data_; // Client data passed with the request.
660 };
661
662
663 // Details of the debug event delivered to the debug event listener.
664 class EventDetailsImpl : public v8::Debug::EventDetails {
665 public:
666 EventDetailsImpl(DebugEvent event,
667 Handle<JSObject> exec_state,
668 Handle<JSObject> event_data,
669 Handle<Object> callback_data,
670 v8::Debug::ClientData* client_data);
671 virtual DebugEvent GetEvent() const;
672 virtual v8::Handle<v8::Object> GetExecutionState() const;
673 virtual v8::Handle<v8::Object> GetEventData() const;
674 virtual v8::Handle<v8::Context> GetEventContext() const;
675 virtual v8::Handle<v8::Value> GetCallbackData() const;
676 virtual v8::Debug::ClientData* GetClientData() const;
677 private:
678 DebugEvent event_; // Debug event causing the break.
679 Handle<JSObject> exec_state_; // Current execution state.
680 Handle<JSObject> event_data_; // Data associated with the event.
681 Handle<Object> callback_data_; // User data passed with the callback
682 // when it was registered.
683 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand.
684 };
685
686
687 // Message send by user to v8 debugger or debugger output message.
688 // In addition to command text it may contain a pointer to some user data
689 // which are expected to be passed along with the command reponse to message
690 // handler.
691 class CommandMessage {
692 public:
693 static CommandMessage New(const Vector<uint16_t>& command,
694 v8::Debug::ClientData* data);
695 CommandMessage();
696 ~CommandMessage();
697
698 // Deletes user data and disposes of the text.
699 void Dispose();
700 Vector<uint16_t> text() const { return text_; }
701 v8::Debug::ClientData* client_data() const { return client_data_; }
702 private:
703 CommandMessage(const Vector<uint16_t>& text,
704 v8::Debug::ClientData* data);
705
706 Vector<uint16_t> text_;
707 v8::Debug::ClientData* client_data_;
708 };
709
710 // A Queue of CommandMessage objects. A thread-safe version is
711 // LockingCommandMessageQueue, based on this class.
712 class CommandMessageQueue BASE_EMBEDDED {
713 public:
714 explicit CommandMessageQueue(int size);
715 ~CommandMessageQueue();
716 bool IsEmpty() const { return start_ == end_; }
717 CommandMessage Get();
718 void Put(const CommandMessage& message);
719 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear().
720 private:
721 // Doubles the size of the message queue, and copies the messages.
722 void Expand();
723
724 CommandMessage* messages_;
725 int start_;
726 int end_;
727 int size_; // The size of the queue buffer. Queue can hold size-1 messages.
728 };
729
730
731 class MessageDispatchHelperThread;
732
733
734 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage
735 // messages. The message data is not managed by LockingCommandMessageQueue.
736 // Pointers to the data are passed in and out. Implemented by adding a
737 // Mutex to CommandMessageQueue. Includes logging of all puts and gets.
738 class LockingCommandMessageQueue BASE_EMBEDDED {
739 public:
740 LockingCommandMessageQueue(Logger* logger, int size);
741 bool IsEmpty() const;
742 CommandMessage Get();
743 void Put(const CommandMessage& message);
744 void Clear();
745 private:
746 Logger* logger_;
747 CommandMessageQueue queue_;
748 mutable Mutex mutex_;
749 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue);
750 };
751
752
753 class Debugger {
754 public:
755 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue);
756 void OnException(Handle<Object> exception, bool uncaught);
757 void OnBeforeCompile(Handle<Script> script);
758
759 enum AfterCompileFlags {
760 NO_AFTER_COMPILE_FLAGS,
761 SEND_WHEN_DEBUGGING
762 };
763 void OnAfterCompile(Handle<Script> script,
764 AfterCompileFlags after_compile_flags);
765 void OnScriptCollected(int id);
766
767 void SetEventListener(Handle<Object> callback, Handle<Object> data);
768 void SetMessageHandler(v8::Debug::MessageHandler handler);
769
770 // Add a debugger command to the command queue.
771 void EnqueueCommandMessage(Vector<const uint16_t> command,
772 v8::Debug::ClientData* client_data = NULL);
773
774 // Check whether there are commands in the command queue.
775 bool HasCommands();
776
777 // Enqueue a debugger command to the command queue for event listeners.
778 void EnqueueDebugCommand(v8::Debug::ClientData* client_data = NULL);
779
780 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<JSFunction> fun,
781 Handle<Object> data);
782
783 Handle<Context> GetDebugContext();
784
785 bool ignore_debugger() const { return ignore_debugger_; }
786 void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
787 bool live_edit_enabled() const {
788 return FLAG_enable_liveedit && live_edit_enabled_ ;
789 }
790
791 bool is_active() { return is_active_; }
792
793 class IgnoreScope {
794 public:
795 explicit IgnoreScope(Debugger* debugger)
796 : debugger_(debugger),
797 old_state_(debugger_->ignore_debugger_) {
798 debugger_->ignore_debugger_ = true;
799 }
800
801 ~IgnoreScope() {
802 debugger_->ignore_debugger_ = old_state_;
803 }
804
805 private:
806 Debugger* debugger_;
807 bool old_state_;
808 DISALLOW_COPY_AND_ASSIGN(IgnoreScope);
809 };
810
811 private:
812 explicit Debugger(Isolate* isolate);
813 ~Debugger();
814
815 MUST_USE_RESULT MaybeHandle<Object> MakeJSObject(
816 Vector<const char> constructor_name,
817 int argc,
818 Handle<Object> argv[]);
819 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
820 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
821 Handle<Object> break_points_hit);
822 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
823 Handle<Object> exception,
824 bool uncaught,
825 Handle<Object> promise);
826 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
827 Handle<Script> script, bool before);
828 MUST_USE_RESULT MaybeHandle<Object> MakeScriptCollectedEvent(int id);
829
830 void CallEventCallback(v8::DebugEvent event,
831 Handle<Object> exec_state,
832 Handle<Object> event_data,
833 v8::Debug::ClientData* client_data);
834 void CallCEventCallback(v8::DebugEvent event,
835 Handle<Object> exec_state,
836 Handle<Object> event_data,
837 v8::Debug::ClientData* client_data);
838 void CallJSEventCallback(v8::DebugEvent event,
839 Handle<Object> exec_state,
840 Handle<Object> event_data);
841 void UpdateState();
842
843 void ProcessDebugEvent(v8::DebugEvent event,
844 Handle<JSObject> event_data,
845 bool auto_continue);
846 void NotifyMessageHandler(v8::DebugEvent event,
847 Handle<JSObject> exec_state,
848 Handle<JSObject> event_data,
849 bool auto_continue);
850
851 // Invoke the message handler function.
852 void InvokeMessageHandler(MessageImpl message);
853
854 inline bool EventActive() {
855 // Check whether the message handler was been cleared.
856 // TODO(yangguo): handle loading and unloading of the debugger differently.
857 // Currently argument event is not used.
858 return !ignore_debugger_ && is_active_;
859 }
860
861 Handle<Object> event_listener_; // Global handle to listener.
862 Handle<Object> event_listener_data_;
863 bool is_active_;
864 bool ignore_debugger_; // Are we temporarily ignoring the debugger?
865 bool live_edit_enabled_; // Enable LiveEdit.
866 v8::Debug::MessageHandler message_handler_;
867 bool debugger_unload_pending_; // Was message handler cleared?
868
869 static const int kQueueInitialSize = 4;
870 LockingCommandMessageQueue command_queue_;
871 Semaphore command_received_; // Signaled for each command received.
872 LockingCommandMessageQueue event_command_queue_;
873
874 Isolate* isolate_;
875
876 friend class EnterDebugger;
877 friend class Isolate;
878
879 DISALLOW_COPY_AND_ASSIGN(Debugger);
880 };
881
882
883 // This class is used for entering the debugger. Create an instance in the stack 842 // This class is used for entering the debugger. Create an instance in the stack
884 // to enter the debugger. This will set the current break state, make sure the 843 // to enter the debugger. This will set the current break state, make sure the
885 // debugger is loaded and switch to the debugger context. If the debugger for 844 // debugger is loaded and switch to the debugger context. If the debugger for
886 // some reason could not be entered FailedToEnter will return true. 845 // some reason could not be entered FailedToEnter will return true.
887 class EnterDebugger BASE_EMBEDDED { 846 class EnterDebugger BASE_EMBEDDED {
888 public: 847 public:
889 explicit EnterDebugger(Isolate* isolate); 848 explicit EnterDebugger(Isolate* isolate);
890 ~EnterDebugger(); 849 ~EnterDebugger();
891 850
892 // Check whether the debugger could be entered. 851 // Check whether the debugger could be entered.
(...skipping 28 matching lines...) Expand all
921 isolate_->debug()->set_disable_break(prev_disable_break_); 880 isolate_->debug()->set_disable_break(prev_disable_break_);
922 } 881 }
923 882
924 private: 883 private:
925 Isolate* isolate_; 884 Isolate* isolate_;
926 // The previous state of the disable break used to restore the value when this 885 // The previous state of the disable break used to restore the value when this
927 // object is destructed. 886 // object is destructed.
928 bool prev_disable_break_; 887 bool prev_disable_break_;
929 }; 888 };
930 889
890
891 // Code generator routines.
892 class DebugCodegen : public AllStatic {
893 public:
894 static void GenerateSlot(MacroAssembler* masm);
895 static void GenerateCallICStubDebugBreak(MacroAssembler* masm);
896 static void GenerateLoadICDebugBreak(MacroAssembler* masm);
897 static void GenerateStoreICDebugBreak(MacroAssembler* masm);
898 static void GenerateKeyedLoadICDebugBreak(MacroAssembler* masm);
899 static void GenerateKeyedStoreICDebugBreak(MacroAssembler* masm);
900 static void GenerateCompareNilICDebugBreak(MacroAssembler* masm);
901 static void GenerateReturnDebugBreak(MacroAssembler* masm);
902 static void GenerateCallFunctionStubDebugBreak(MacroAssembler* masm);
903 static void GenerateCallConstructStubDebugBreak(MacroAssembler* masm);
904 static void GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm);
905 static void GenerateSlotDebugBreak(MacroAssembler* masm);
906 static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
907
908 // FrameDropper is a code replacement for a JavaScript frame with possibly
909 // several frames above.
910 // There is no calling conventions here, because it never actually gets
911 // called, it only gets returned to.
912 static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
913 };
914
931 } } // namespace v8::internal 915 } } // namespace v8::internal
932 916
933 #endif // V8_DEBUG_H_ 917 #endif // V8_DEBUG_H_
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698