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 }; | |
284 | 243 |
285 // Details of the debug event delivered to the debug event listener. | 244 // Details of the debug event delivered to the debug event listener. |
286 class EventDetailsImpl : public v8::DebugInterface::EventDetails { | 245 class EventDetailsImpl : public v8::DebugInterface::EventDetails { |
287 public: | 246 public: |
288 EventDetailsImpl(DebugEvent event, | 247 EventDetailsImpl(DebugEvent event, |
289 Handle<JSObject> exec_state, | 248 Handle<JSObject> exec_state, |
290 Handle<JSObject> event_data, | 249 Handle<JSObject> event_data, |
291 Handle<Object> callback_data, | 250 Handle<Object> callback_data, |
292 v8::Debug::ClientData* client_data); | 251 v8::Debug::ClientData* client_data); |
293 virtual DebugEvent GetEvent() const; | 252 virtual DebugEvent GetEvent() const; |
294 virtual v8::Local<v8::Object> GetExecutionState() const; | 253 virtual v8::Local<v8::Object> GetExecutionState() const; |
295 virtual v8::Local<v8::Object> GetEventData() const; | 254 virtual v8::Local<v8::Object> GetEventData() const; |
296 virtual v8::Local<v8::Context> GetEventContext() const; | 255 virtual v8::Local<v8::Context> GetEventContext() const; |
297 virtual v8::Local<v8::Value> GetCallbackData() const; | 256 virtual v8::Local<v8::Value> GetCallbackData() const; |
298 virtual v8::Debug::ClientData* GetClientData() const; | 257 virtual v8::Debug::ClientData* GetClientData() const; |
299 virtual v8::Isolate* GetIsolate() const; | 258 virtual v8::Isolate* GetIsolate() const; |
300 | 259 |
301 private: | 260 private: |
302 DebugEvent event_; // Debug event causing the break. | 261 DebugEvent event_; // Debug event causing the break. |
303 Handle<JSObject> exec_state_; // Current execution state. | 262 Handle<JSObject> exec_state_; // Current execution state. |
304 Handle<JSObject> event_data_; // Data associated with the event. | 263 Handle<JSObject> event_data_; // Data associated with the event. |
305 Handle<Object> callback_data_; // User data passed with the callback | 264 Handle<Object> callback_data_; // User data passed with the callback |
306 // when it was registered. | 265 // when it was registered. |
307 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. | 266 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. |
308 }; | 267 }; |
309 | 268 |
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 }; | |
371 | 269 |
372 class DebugFeatureTracker { | 270 class DebugFeatureTracker { |
373 public: | 271 public: |
374 enum Feature { | 272 enum Feature { |
375 kActive = 1, | 273 kActive = 1, |
376 kBreakPoint = 2, | 274 kBreakPoint = 2, |
377 kStepping = 3, | 275 kStepping = 3, |
378 kHeapSnapshot = 4, | 276 kHeapSnapshot = 4, |
379 kAllocationTracking = 5, | 277 kAllocationTracking = 5, |
380 kProfiler = 6, | 278 kProfiler = 6, |
(...skipping 13 matching lines...) Expand all Loading... |
394 // This class contains the debugger support. The main purpose is to handle | 292 // This class contains the debugger support. The main purpose is to handle |
395 // setting break points in the code. | 293 // setting break points in the code. |
396 // | 294 // |
397 // This class controls the debug info for all functions which currently have | 295 // This class controls the debug info for all functions which currently have |
398 // active breakpoints in them. This debug info is held in the heap root object | 296 // active breakpoints in them. This debug info is held in the heap root object |
399 // debug_info which is a FixedArray. Each entry in this list is of class | 297 // debug_info which is a FixedArray. Each entry in this list is of class |
400 // DebugInfo. | 298 // DebugInfo. |
401 class Debug { | 299 class Debug { |
402 public: | 300 public: |
403 // Debug event triggers. | 301 // Debug event triggers. |
404 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); | 302 void OnDebugBreak(Handle<Object> break_points_hit); |
405 | 303 |
406 void OnThrow(Handle<Object> exception); | 304 void OnThrow(Handle<Object> exception); |
407 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); | 305 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); |
408 void OnCompileError(Handle<Script> script); | 306 void OnCompileError(Handle<Script> script); |
409 void OnAfterCompile(Handle<Script> script); | 307 void OnAfterCompile(Handle<Script> script); |
410 void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, | 308 void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, |
411 Handle<String> name); | 309 Handle<String> name); |
412 | 310 |
413 // API facing. | 311 // API facing. |
414 void SetEventListener(Handle<Object> callback, Handle<Object> data); | 312 void SetEventListener(Handle<Object> callback, Handle<Object> data); |
415 void SetMessageHandler(v8::Debug::MessageHandler handler); | 313 void SetMessageHandler(v8::Debug::MessageHandler handler); |
416 void EnqueueCommandMessage(Vector<const uint16_t> command, | |
417 v8::Debug::ClientData* client_data = NULL); | |
418 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, | 314 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, |
419 Handle<Object> data); | 315 Handle<Object> data); |
420 Handle<Context> GetDebugContext(); | 316 Handle<Context> GetDebugContext(); |
421 void HandleDebugBreak(); | 317 void HandleDebugBreak(); |
422 void ProcessDebugMessages(bool debug_command_only); | 318 void ProcessDebugMessages(); |
423 | 319 |
424 // Internal logic | 320 // Internal logic |
425 bool Load(); | 321 bool Load(); |
426 void Break(JavaScriptFrame* frame); | 322 void Break(JavaScriptFrame* frame); |
427 void SetAfterBreakTarget(JavaScriptFrame* frame); | 323 void SetAfterBreakTarget(JavaScriptFrame* frame); |
428 | 324 |
429 // Scripts handling. | 325 // Scripts handling. |
430 Handle<FixedArray> GetLoadedScripts(); | 326 Handle<FixedArray> GetLoadedScripts(); |
431 | 327 |
432 // Break point handling. | 328 // Break point handling. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 private: | 447 private: |
552 explicit Debug(Isolate* isolate); | 448 explicit Debug(Isolate* isolate); |
553 | 449 |
554 void UpdateState(); | 450 void UpdateState(); |
555 void Unload(); | 451 void Unload(); |
556 void SetNextBreakId() { | 452 void SetNextBreakId() { |
557 thread_local_.break_id_ = ++thread_local_.break_count_; | 453 thread_local_.break_id_ = ++thread_local_.break_count_; |
558 } | 454 } |
559 | 455 |
560 // Check whether there are commands in the command queue. | 456 // Check whether there are commands in the command queue. |
561 inline bool has_commands() const { return !command_queue_.IsEmpty(); } | |
562 inline bool ignore_events() const { return is_suppressed_ || !is_active_; } | 457 inline bool ignore_events() const { return is_suppressed_ || !is_active_; } |
563 inline bool break_disabled() const { | 458 inline bool break_disabled() const { |
564 return break_disabled_ || in_debug_event_listener_; | 459 return break_disabled_ || in_debug_event_listener_; |
565 } | 460 } |
566 | 461 |
567 void clear_suspended_generator() { | 462 void clear_suspended_generator() { |
568 thread_local_.suspended_generator_ = Smi::kZero; | 463 thread_local_.suspended_generator_ = Smi::kZero; |
569 } | 464 } |
570 | 465 |
571 bool has_suspended_generator() const { | 466 bool has_suspended_generator() const { |
(...skipping 17 matching lines...) Expand all Loading... |
589 Handle<String> name); | 484 Handle<String> name); |
590 | 485 |
591 // Mirror cache handling. | 486 // Mirror cache handling. |
592 void ClearMirrorCache(); | 487 void ClearMirrorCache(); |
593 | 488 |
594 void CallEventCallback(v8::DebugEvent event, | 489 void CallEventCallback(v8::DebugEvent event, |
595 Handle<Object> exec_state, | 490 Handle<Object> exec_state, |
596 Handle<Object> event_data, | 491 Handle<Object> event_data, |
597 v8::Debug::ClientData* client_data); | 492 v8::Debug::ClientData* client_data); |
598 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); | 493 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); |
599 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, | 494 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); |
600 bool auto_continue); | |
601 void NotifyMessageHandler(v8::DebugEvent event, Handle<JSObject> exec_state, | |
602 Handle<JSObject> event_data, bool auto_continue); | |
603 void InvokeMessageHandler(MessageImpl message); | |
604 | 495 |
605 // Find the closest source position for a break point for a given position. | 496 // Find the closest source position for a break point for a given position. |
606 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, | 497 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, |
607 BreakPositionAlignment alignment); | 498 BreakPositionAlignment alignment); |
608 // Instrument code to break at break points. | 499 // Instrument code to break at break points. |
609 void ApplyBreakPoints(Handle<DebugInfo> debug_info); | 500 void ApplyBreakPoints(Handle<DebugInfo> debug_info); |
610 // Clear code from instrumentation. | 501 // Clear code from instrumentation. |
611 void ClearBreakPoints(Handle<DebugInfo> debug_info); | 502 void ClearBreakPoints(Handle<DebugInfo> debug_info); |
612 // Clear all code from instrumentation. | 503 // Clear all code from instrumentation. |
613 void ClearAllBreakPoints(); | 504 void ClearAllBreakPoints(); |
(...skipping 22 matching lines...) Expand all Loading... |
636 | 527 |
637 void PrintBreakLocation(); | 528 void PrintBreakLocation(); |
638 | 529 |
639 // Global handles. | 530 // Global handles. |
640 Handle<Context> debug_context_; | 531 Handle<Context> debug_context_; |
641 Handle<Object> event_listener_; | 532 Handle<Object> event_listener_; |
642 Handle<Object> event_listener_data_; | 533 Handle<Object> event_listener_data_; |
643 | 534 |
644 v8::Debug::MessageHandler message_handler_; | 535 v8::Debug::MessageHandler message_handler_; |
645 | 536 |
646 static const int kQueueInitialSize = 4; | |
647 base::Semaphore command_received_; // Signaled for each command received. | |
648 LockingCommandMessageQueue command_queue_; | |
649 | |
650 bool is_active_; | 537 bool is_active_; |
651 bool is_suppressed_; | 538 bool is_suppressed_; |
652 bool live_edit_enabled_; | 539 bool live_edit_enabled_; |
653 bool break_disabled_; | 540 bool break_disabled_; |
654 bool break_points_active_; | 541 bool break_points_active_; |
655 bool in_debug_event_listener_; | 542 bool in_debug_event_listener_; |
656 bool break_on_exception_; | 543 bool break_on_exception_; |
657 bool break_on_uncaught_exception_; | 544 bool break_on_uncaught_exception_; |
658 | 545 |
659 DebugInfoListNode* debug_info_list_; // List of active debug info objects. | 546 DebugInfoListNode* debug_info_list_; // List of active debug info objects. |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 Handle<Code> code); | 699 Handle<Code> code); |
813 static bool DebugBreakSlotIsPatched(Address pc); | 700 static bool DebugBreakSlotIsPatched(Address pc); |
814 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); | 701 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); |
815 }; | 702 }; |
816 | 703 |
817 | 704 |
818 } // namespace internal | 705 } // namespace internal |
819 } // namespace v8 | 706 } // namespace v8 |
820 | 707 |
821 #endif // V8_DEBUG_DEBUG_H_ | 708 #endif // V8_DEBUG_DEBUG_H_ |
OLD | NEW |