| 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_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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); } | 233 Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); } |
| 234 | 234 |
| 235 private: | 235 private: |
| 236 // Global (weak) handle to the debug info object. | 236 // Global (weak) handle to the debug info object. |
| 237 DebugInfo** debug_info_; | 237 DebugInfo** debug_info_; |
| 238 | 238 |
| 239 // Next pointer for linked list. | 239 // Next pointer for linked list. |
| 240 DebugInfoListNode* next_; | 240 DebugInfoListNode* next_; |
| 241 }; | 241 }; |
| 242 | 242 |
| 243 // Message delivered to the message handler callback. This is either a debugger |
| 244 // event or the response to a command. |
| 245 class MessageImpl : public v8::Debug::Message { |
| 246 public: |
| 247 // Create a message object for a debug event. |
| 248 static MessageImpl NewEvent(DebugEvent event, bool running, |
| 249 Handle<JSObject> exec_state, |
| 250 Handle<JSObject> event_data); |
| 251 |
| 252 // Create a message object for the response to a debug command. |
| 253 static MessageImpl NewResponse(DebugEvent event, bool running, |
| 254 Handle<JSObject> exec_state, |
| 255 Handle<JSObject> event_data, |
| 256 Handle<String> response_json, |
| 257 v8::Debug::ClientData* client_data); |
| 258 |
| 259 // Implementation of interface v8::Debug::Message. |
| 260 virtual bool IsEvent() const; |
| 261 virtual bool IsResponse() const; |
| 262 virtual DebugEvent GetEvent() const; |
| 263 virtual bool WillStartRunning() const; |
| 264 virtual v8::Local<v8::Object> GetExecutionState() const; |
| 265 virtual v8::Local<v8::Object> GetEventData() const; |
| 266 virtual v8::Local<v8::String> GetJSON() const; |
| 267 virtual v8::Local<v8::Context> GetEventContext() const; |
| 268 virtual v8::Debug::ClientData* GetClientData() const; |
| 269 virtual v8::Isolate* GetIsolate() const; |
| 270 |
| 271 private: |
| 272 MessageImpl(bool is_event, DebugEvent event, bool running, |
| 273 Handle<JSObject> exec_state, Handle<JSObject> event_data, |
| 274 Handle<String> response_json, v8::Debug::ClientData* client_data); |
| 275 |
| 276 bool is_event_; // Does this message represent a debug event? |
| 277 DebugEvent event_; // Debug event causing the break. |
| 278 bool running_; // Will the VM start running after this event? |
| 279 Handle<JSObject> exec_state_; // Current execution state. |
| 280 Handle<JSObject> event_data_; // Data associated with the event. |
| 281 Handle<String> response_json_; // Response JSON if message holds a response. |
| 282 v8::Debug::ClientData* client_data_; // Client data passed with the request. |
| 283 }; |
| 243 | 284 |
| 244 // Details of the debug event delivered to the debug event listener. | 285 // Details of the debug event delivered to the debug event listener. |
| 245 class EventDetailsImpl : public v8::DebugInterface::EventDetails { | 286 class EventDetailsImpl : public v8::DebugInterface::EventDetails { |
| 246 public: | 287 public: |
| 247 EventDetailsImpl(DebugEvent event, | 288 EventDetailsImpl(DebugEvent event, |
| 248 Handle<JSObject> exec_state, | 289 Handle<JSObject> exec_state, |
| 249 Handle<JSObject> event_data, | 290 Handle<JSObject> event_data, |
| 250 Handle<Object> callback_data, | 291 Handle<Object> callback_data, |
| 251 v8::Debug::ClientData* client_data); | 292 v8::Debug::ClientData* client_data); |
| 252 virtual DebugEvent GetEvent() const; | 293 virtual DebugEvent GetEvent() const; |
| 253 virtual v8::Local<v8::Object> GetExecutionState() const; | 294 virtual v8::Local<v8::Object> GetExecutionState() const; |
| 254 virtual v8::Local<v8::Object> GetEventData() const; | 295 virtual v8::Local<v8::Object> GetEventData() const; |
| 255 virtual v8::Local<v8::Context> GetEventContext() const; | 296 virtual v8::Local<v8::Context> GetEventContext() const; |
| 256 virtual v8::Local<v8::Value> GetCallbackData() const; | 297 virtual v8::Local<v8::Value> GetCallbackData() const; |
| 257 virtual v8::Debug::ClientData* GetClientData() const; | 298 virtual v8::Debug::ClientData* GetClientData() const; |
| 258 virtual v8::Isolate* GetIsolate() const; | 299 virtual v8::Isolate* GetIsolate() const; |
| 259 | 300 |
| 260 private: | 301 private: |
| 261 DebugEvent event_; // Debug event causing the break. | 302 DebugEvent event_; // Debug event causing the break. |
| 262 Handle<JSObject> exec_state_; // Current execution state. | 303 Handle<JSObject> exec_state_; // Current execution state. |
| 263 Handle<JSObject> event_data_; // Data associated with the event. | 304 Handle<JSObject> event_data_; // Data associated with the event. |
| 264 Handle<Object> callback_data_; // User data passed with the callback | 305 Handle<Object> callback_data_; // User data passed with the callback |
| 265 // when it was registered. | 306 // when it was registered. |
| 266 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. | 307 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. |
| 267 }; | 308 }; |
| 268 | 309 |
| 310 // Message send by user to v8 debugger or debugger output message. |
| 311 // In addition to command text it may contain a pointer to some user data |
| 312 // which are expected to be passed along with the command reponse to message |
| 313 // handler. |
| 314 class CommandMessage { |
| 315 public: |
| 316 static CommandMessage New(const Vector<uint16_t>& command, |
| 317 v8::Debug::ClientData* data); |
| 318 CommandMessage(); |
| 319 |
| 320 // Deletes user data and disposes of the text. |
| 321 void Dispose(); |
| 322 Vector<uint16_t> text() const { return text_; } |
| 323 v8::Debug::ClientData* client_data() const { return client_data_; } |
| 324 |
| 325 private: |
| 326 CommandMessage(const Vector<uint16_t>& text, v8::Debug::ClientData* data); |
| 327 |
| 328 Vector<uint16_t> text_; |
| 329 v8::Debug::ClientData* client_data_; |
| 330 }; |
| 331 |
| 332 // A Queue of CommandMessage objects. A thread-safe version is |
| 333 // LockingCommandMessageQueue, based on this class. |
| 334 class CommandMessageQueue BASE_EMBEDDED { |
| 335 public: |
| 336 explicit CommandMessageQueue(int size); |
| 337 ~CommandMessageQueue(); |
| 338 bool IsEmpty() const { return start_ == end_; } |
| 339 CommandMessage Get(); |
| 340 void Put(const CommandMessage& message); |
| 341 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear(). |
| 342 |
| 343 private: |
| 344 // Doubles the size of the message queue, and copies the messages. |
| 345 void Expand(); |
| 346 |
| 347 CommandMessage* messages_; |
| 348 int start_; |
| 349 int end_; |
| 350 int size_; // The size of the queue buffer. Queue can hold size-1 messages. |
| 351 }; |
| 352 |
| 353 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage |
| 354 // messages. The message data is not managed by LockingCommandMessageQueue. |
| 355 // Pointers to the data are passed in and out. Implemented by adding a |
| 356 // Mutex to CommandMessageQueue. Includes logging of all puts and gets. |
| 357 class LockingCommandMessageQueue BASE_EMBEDDED { |
| 358 public: |
| 359 LockingCommandMessageQueue(Logger* logger, int size); |
| 360 bool IsEmpty() const; |
| 361 CommandMessage Get(); |
| 362 void Put(const CommandMessage& message); |
| 363 void Clear(); |
| 364 |
| 365 private: |
| 366 Logger* logger_; |
| 367 CommandMessageQueue queue_; |
| 368 mutable base::Mutex mutex_; |
| 369 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); |
| 370 }; |
| 269 | 371 |
| 270 class DebugFeatureTracker { | 372 class DebugFeatureTracker { |
| 271 public: | 373 public: |
| 272 enum Feature { | 374 enum Feature { |
| 273 kActive = 1, | 375 kActive = 1, |
| 274 kBreakPoint = 2, | 376 kBreakPoint = 2, |
| 275 kStepping = 3, | 377 kStepping = 3, |
| 276 kHeapSnapshot = 4, | 378 kHeapSnapshot = 4, |
| 277 kAllocationTracking = 5, | 379 kAllocationTracking = 5, |
| 278 kProfiler = 6, | 380 kProfiler = 6, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 292 // This class contains the debugger support. The main purpose is to handle | 394 // This class contains the debugger support. The main purpose is to handle |
| 293 // setting break points in the code. | 395 // setting break points in the code. |
| 294 // | 396 // |
| 295 // This class controls the debug info for all functions which currently have | 397 // This class controls the debug info for all functions which currently have |
| 296 // active breakpoints in them. This debug info is held in the heap root object | 398 // active breakpoints in them. This debug info is held in the heap root object |
| 297 // debug_info which is a FixedArray. Each entry in this list is of class | 399 // debug_info which is a FixedArray. Each entry in this list is of class |
| 298 // DebugInfo. | 400 // DebugInfo. |
| 299 class Debug { | 401 class Debug { |
| 300 public: | 402 public: |
| 301 // Debug event triggers. | 403 // Debug event triggers. |
| 302 void OnDebugBreak(Handle<Object> break_points_hit); | 404 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); |
| 303 | 405 |
| 304 void OnThrow(Handle<Object> exception); | 406 void OnThrow(Handle<Object> exception); |
| 305 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); | 407 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); |
| 306 void OnCompileError(Handle<Script> script); | 408 void OnCompileError(Handle<Script> script); |
| 409 void OnBeforeCompile(Handle<Script> script); |
| 307 void OnAfterCompile(Handle<Script> script); | 410 void OnAfterCompile(Handle<Script> script); |
| 308 void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, | 411 void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, |
| 309 Handle<String> name); | 412 Handle<String> name); |
| 310 | 413 |
| 311 // API facing. | 414 // API facing. |
| 312 void SetEventListener(Handle<Object> callback, Handle<Object> data); | 415 void SetEventListener(Handle<Object> callback, Handle<Object> data); |
| 313 void SetMessageHandler(v8::Debug::MessageHandler handler); | 416 void SetMessageHandler(v8::Debug::MessageHandler handler); |
| 417 void EnqueueCommandMessage(Vector<const uint16_t> command, |
| 418 v8::Debug::ClientData* client_data = NULL); |
| 314 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, | 419 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, |
| 315 Handle<Object> data); | 420 Handle<Object> data); |
| 316 Handle<Context> GetDebugContext(); | 421 Handle<Context> GetDebugContext(); |
| 317 void HandleDebugBreak(); | 422 void HandleDebugBreak(); |
| 318 void ProcessDebugMessages(); | 423 void ProcessDebugMessages(bool debug_command_only); |
| 319 | 424 |
| 320 // Internal logic | 425 // Internal logic |
| 321 bool Load(); | 426 bool Load(); |
| 322 void Break(JavaScriptFrame* frame); | 427 void Break(JavaScriptFrame* frame); |
| 323 void SetAfterBreakTarget(JavaScriptFrame* frame); | 428 void SetAfterBreakTarget(JavaScriptFrame* frame); |
| 324 | 429 |
| 325 // Scripts handling. | 430 // Scripts handling. |
| 326 Handle<FixedArray> GetLoadedScripts(); | 431 Handle<FixedArray> GetLoadedScripts(); |
| 327 | 432 |
| 328 // Break point handling. | 433 // Break point handling. |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 private: | 552 private: |
| 448 explicit Debug(Isolate* isolate); | 553 explicit Debug(Isolate* isolate); |
| 449 | 554 |
| 450 void UpdateState(); | 555 void UpdateState(); |
| 451 void Unload(); | 556 void Unload(); |
| 452 void SetNextBreakId() { | 557 void SetNextBreakId() { |
| 453 thread_local_.break_id_ = ++thread_local_.break_count_; | 558 thread_local_.break_id_ = ++thread_local_.break_count_; |
| 454 } | 559 } |
| 455 | 560 |
| 456 // Check whether there are commands in the command queue. | 561 // Check whether there are commands in the command queue. |
| 562 inline bool has_commands() const { return !command_queue_.IsEmpty(); } |
| 457 inline bool ignore_events() const { return is_suppressed_ || !is_active_; } | 563 inline bool ignore_events() const { return is_suppressed_ || !is_active_; } |
| 458 inline bool break_disabled() const { | 564 inline bool break_disabled() const { |
| 459 return break_disabled_ || in_debug_event_listener_; | 565 return break_disabled_ || in_debug_event_listener_; |
| 460 } | 566 } |
| 461 | 567 |
| 462 void clear_suspended_generator() { | 568 void clear_suspended_generator() { |
| 463 thread_local_.suspended_generator_ = Smi::kZero; | 569 thread_local_.suspended_generator_ = Smi::kZero; |
| 464 } | 570 } |
| 465 | 571 |
| 466 bool has_suspended_generator() const { | 572 bool has_suspended_generator() const { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 484 Handle<String> name); | 590 Handle<String> name); |
| 485 | 591 |
| 486 // Mirror cache handling. | 592 // Mirror cache handling. |
| 487 void ClearMirrorCache(); | 593 void ClearMirrorCache(); |
| 488 | 594 |
| 489 void CallEventCallback(v8::DebugEvent event, | 595 void CallEventCallback(v8::DebugEvent event, |
| 490 Handle<Object> exec_state, | 596 Handle<Object> exec_state, |
| 491 Handle<Object> event_data, | 597 Handle<Object> event_data, |
| 492 v8::Debug::ClientData* client_data); | 598 v8::Debug::ClientData* client_data); |
| 493 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); | 599 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); |
| 494 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); | 600 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, |
| 601 bool auto_continue); |
| 602 void NotifyMessageHandler(v8::DebugEvent event, Handle<JSObject> exec_state, |
| 603 Handle<JSObject> event_data, bool auto_continue); |
| 604 void InvokeMessageHandler(MessageImpl message); |
| 495 | 605 |
| 496 // Find the closest source position for a break point for a given position. | 606 // Find the closest source position for a break point for a given position. |
| 497 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, | 607 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, |
| 498 BreakPositionAlignment alignment); | 608 BreakPositionAlignment alignment); |
| 499 // Instrument code to break at break points. | 609 // Instrument code to break at break points. |
| 500 void ApplyBreakPoints(Handle<DebugInfo> debug_info); | 610 void ApplyBreakPoints(Handle<DebugInfo> debug_info); |
| 501 // Clear code from instrumentation. | 611 // Clear code from instrumentation. |
| 502 void ClearBreakPoints(Handle<DebugInfo> debug_info); | 612 void ClearBreakPoints(Handle<DebugInfo> debug_info); |
| 503 // Clear all code from instrumentation. | 613 // Clear all code from instrumentation. |
| 504 void ClearAllBreakPoints(); | 614 void ClearAllBreakPoints(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 527 | 637 |
| 528 void PrintBreakLocation(); | 638 void PrintBreakLocation(); |
| 529 | 639 |
| 530 // Global handles. | 640 // Global handles. |
| 531 Handle<Context> debug_context_; | 641 Handle<Context> debug_context_; |
| 532 Handle<Object> event_listener_; | 642 Handle<Object> event_listener_; |
| 533 Handle<Object> event_listener_data_; | 643 Handle<Object> event_listener_data_; |
| 534 | 644 |
| 535 v8::Debug::MessageHandler message_handler_; | 645 v8::Debug::MessageHandler message_handler_; |
| 536 | 646 |
| 647 static const int kQueueInitialSize = 4; |
| 648 base::Semaphore command_received_; // Signaled for each command received. |
| 649 LockingCommandMessageQueue command_queue_; |
| 650 |
| 537 bool is_active_; | 651 bool is_active_; |
| 538 bool is_suppressed_; | 652 bool is_suppressed_; |
| 539 bool live_edit_enabled_; | 653 bool live_edit_enabled_; |
| 540 bool break_disabled_; | 654 bool break_disabled_; |
| 541 bool break_points_active_; | 655 bool break_points_active_; |
| 542 bool in_debug_event_listener_; | 656 bool in_debug_event_listener_; |
| 543 bool break_on_exception_; | 657 bool break_on_exception_; |
| 544 bool break_on_uncaught_exception_; | 658 bool break_on_uncaught_exception_; |
| 545 | 659 |
| 546 DebugInfoListNode* debug_info_list_; // List of active debug info objects. | 660 DebugInfoListNode* debug_info_list_; // List of active debug info objects. |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 Handle<Code> code); | 813 Handle<Code> code); |
| 700 static bool DebugBreakSlotIsPatched(Address pc); | 814 static bool DebugBreakSlotIsPatched(Address pc); |
| 701 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); | 815 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); |
| 702 }; | 816 }; |
| 703 | 817 |
| 704 | 818 |
| 705 } // namespace internal | 819 } // namespace internal |
| 706 } // namespace v8 | 820 } // namespace v8 |
| 707 | 821 |
| 708 #endif // V8_DEBUG_DEBUG_H_ | 822 #endif // V8_DEBUG_DEBUG_H_ |
| OLD | NEW |