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 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 | 243 |
244 // Message delivered to the message handler callback. This is either a debugger | |
245 // event or the response to a command. | |
246 class MessageImpl: public v8::Debug::Message { | |
247 public: | |
248 // Create a message object for a debug event. | |
249 static MessageImpl NewEvent(DebugEvent event, | |
250 bool running, | |
251 Handle<JSObject> exec_state, | |
252 Handle<JSObject> event_data); | |
253 | |
254 // Create a message object for the response to a debug command. | |
255 static MessageImpl NewResponse(DebugEvent event, | |
256 bool running, | |
257 Handle<JSObject> exec_state, | |
258 Handle<JSObject> event_data, | |
259 Handle<String> response_json, | |
260 v8::Debug::ClientData* client_data); | |
261 | |
262 // Implementation of interface v8::Debug::Message. | |
263 virtual bool IsEvent() const; | |
264 virtual bool IsResponse() const; | |
265 virtual DebugEvent GetEvent() const; | |
266 virtual bool WillStartRunning() const; | |
267 virtual v8::Local<v8::Object> GetExecutionState() const; | |
268 virtual v8::Local<v8::Object> GetEventData() const; | |
269 virtual v8::Local<v8::String> GetJSON() const; | |
270 virtual v8::Local<v8::Context> GetEventContext() const; | |
271 virtual v8::Debug::ClientData* GetClientData() const; | |
272 virtual v8::Isolate* GetIsolate() const; | |
273 | |
274 private: | |
275 MessageImpl(bool is_event, | |
276 DebugEvent event, | |
277 bool running, | |
278 Handle<JSObject> exec_state, | |
279 Handle<JSObject> event_data, | |
280 Handle<String> response_json, | |
281 v8::Debug::ClientData* client_data); | |
282 | |
283 bool is_event_; // Does this message represent a debug event? | |
284 DebugEvent event_; // Debug event causing the break. | |
285 bool running_; // Will the VM start running after this event? | |
286 Handle<JSObject> exec_state_; // Current execution state. | |
287 Handle<JSObject> event_data_; // Data associated with the event. | |
288 Handle<String> response_json_; // Response JSON if message holds a response. | |
289 v8::Debug::ClientData* client_data_; // Client data passed with the request. | |
290 }; | |
291 | |
292 | |
293 // Details of the debug event delivered to the debug event listener. | 244 // Details of the debug event delivered to the debug event listener. |
294 class EventDetailsImpl : public v8::DebugInterface::EventDetails { | 245 class EventDetailsImpl : public v8::DebugInterface::EventDetails { |
295 public: | 246 public: |
296 EventDetailsImpl(DebugEvent event, | 247 EventDetailsImpl(DebugEvent event, |
297 Handle<JSObject> exec_state, | 248 Handle<JSObject> exec_state, |
298 Handle<JSObject> event_data, | 249 Handle<JSObject> event_data, |
299 Handle<Object> callback_data, | 250 Handle<Object> callback_data, |
300 v8::Debug::ClientData* client_data); | 251 v8::Debug::ClientData* client_data); |
301 virtual DebugEvent GetEvent() const; | 252 virtual DebugEvent GetEvent() const; |
302 virtual v8::Local<v8::Object> GetExecutionState() const; | 253 virtual v8::Local<v8::Object> GetExecutionState() const; |
303 virtual v8::Local<v8::Object> GetEventData() const; | 254 virtual v8::Local<v8::Object> GetEventData() const; |
304 virtual v8::Local<v8::Context> GetEventContext() const; | 255 virtual v8::Local<v8::Context> GetEventContext() const; |
305 virtual v8::Local<v8::Value> GetCallbackData() const; | 256 virtual v8::Local<v8::Value> GetCallbackData() const; |
306 virtual v8::Debug::ClientData* GetClientData() const; | 257 virtual v8::Debug::ClientData* GetClientData() const; |
307 virtual v8::Isolate* GetIsolate() const; | 258 virtual v8::Isolate* GetIsolate() const; |
308 | 259 |
309 private: | 260 private: |
310 DebugEvent event_; // Debug event causing the break. | 261 DebugEvent event_; // Debug event causing the break. |
311 Handle<JSObject> exec_state_; // Current execution state. | 262 Handle<JSObject> exec_state_; // Current execution state. |
312 Handle<JSObject> event_data_; // Data associated with the event. | 263 Handle<JSObject> event_data_; // Data associated with the event. |
313 Handle<Object> callback_data_; // User data passed with the callback | 264 Handle<Object> callback_data_; // User data passed with the callback |
314 // when it was registered. | 265 // when it was registered. |
315 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. | 266 v8::Debug::ClientData* client_data_; // Data passed to DebugBreakForCommand. |
316 }; | 267 }; |
317 | 268 |
318 | 269 |
319 // Message send by user to v8 debugger or debugger output message. | |
320 // In addition to command text it may contain a pointer to some user data | |
321 // which are expected to be passed along with the command reponse to message | |
322 // handler. | |
323 class CommandMessage { | |
324 public: | |
325 static CommandMessage New(const Vector<uint16_t>& command, | |
326 v8::Debug::ClientData* data); | |
327 CommandMessage(); | |
328 | |
329 // Deletes user data and disposes of the text. | |
330 void Dispose(); | |
331 Vector<uint16_t> text() const { return text_; } | |
332 v8::Debug::ClientData* client_data() const { return client_data_; } | |
333 private: | |
334 CommandMessage(const Vector<uint16_t>& text, | |
335 v8::Debug::ClientData* data); | |
336 | |
337 Vector<uint16_t> text_; | |
338 v8::Debug::ClientData* client_data_; | |
339 }; | |
340 | |
341 | |
342 // A Queue of CommandMessage objects. A thread-safe version is | |
343 // LockingCommandMessageQueue, based on this class. | |
344 class CommandMessageQueue BASE_EMBEDDED { | |
345 public: | |
346 explicit CommandMessageQueue(int size); | |
347 ~CommandMessageQueue(); | |
348 bool IsEmpty() const { return start_ == end_; } | |
349 CommandMessage Get(); | |
350 void Put(const CommandMessage& message); | |
351 void Clear() { start_ = end_ = 0; } // Queue is empty after Clear(). | |
352 private: | |
353 // Doubles the size of the message queue, and copies the messages. | |
354 void Expand(); | |
355 | |
356 CommandMessage* messages_; | |
357 int start_; | |
358 int end_; | |
359 int size_; // The size of the queue buffer. Queue can hold size-1 messages. | |
360 }; | |
361 | |
362 | |
363 // LockingCommandMessageQueue is a thread-safe circular buffer of CommandMessage | |
364 // messages. The message data is not managed by LockingCommandMessageQueue. | |
365 // Pointers to the data are passed in and out. Implemented by adding a | |
366 // Mutex to CommandMessageQueue. Includes logging of all puts and gets. | |
367 class LockingCommandMessageQueue BASE_EMBEDDED { | |
368 public: | |
369 LockingCommandMessageQueue(Logger* logger, int size); | |
370 bool IsEmpty() const; | |
371 CommandMessage Get(); | |
372 void Put(const CommandMessage& message); | |
373 void Clear(); | |
374 private: | |
375 Logger* logger_; | |
376 CommandMessageQueue queue_; | |
377 mutable base::Mutex mutex_; | |
378 DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); | |
379 }; | |
380 | |
381 | |
382 class DebugFeatureTracker { | 270 class DebugFeatureTracker { |
383 public: | 271 public: |
384 enum Feature { | 272 enum Feature { |
385 kActive = 1, | 273 kActive = 1, |
386 kBreakPoint = 2, | 274 kBreakPoint = 2, |
387 kStepping = 3, | 275 kStepping = 3, |
388 kHeapSnapshot = 4, | 276 kHeapSnapshot = 4, |
389 kAllocationTracking = 5, | 277 kAllocationTracking = 5, |
390 kProfiler = 6, | 278 kProfiler = 6, |
391 kLiveEdit = 7, | 279 kLiveEdit = 7, |
(...skipping 12 matching lines...) Expand all Loading... |
404 // 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 |
405 // setting break points in the code. | 293 // setting break points in the code. |
406 // | 294 // |
407 // 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 |
408 // 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 |
409 // 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 |
410 // DebugInfo. | 298 // DebugInfo. |
411 class Debug { | 299 class Debug { |
412 public: | 300 public: |
413 // Debug event triggers. | 301 // Debug event triggers. |
414 void OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue); | 302 void OnDebugBreak(Handle<Object> break_points_hit); |
415 | 303 |
416 void OnThrow(Handle<Object> exception); | 304 void OnThrow(Handle<Object> exception); |
417 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); | 305 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); |
418 void OnCompileError(Handle<Script> script); | 306 void OnCompileError(Handle<Script> script); |
419 void OnBeforeCompile(Handle<Script> script); | 307 void OnBeforeCompile(Handle<Script> script); |
420 void OnAfterCompile(Handle<Script> script); | 308 void OnAfterCompile(Handle<Script> script); |
421 void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, | 309 void OnAsyncTaskEvent(Handle<String> type, Handle<Object> id, |
422 Handle<String> name); | 310 Handle<String> name); |
423 | 311 |
424 // API facing. | 312 // API facing. |
425 void SetEventListener(Handle<Object> callback, Handle<Object> data); | 313 void SetEventListener(Handle<Object> callback, Handle<Object> data); |
426 void SetMessageHandler(v8::Debug::MessageHandler handler); | 314 void SetMessageHandler(v8::Debug::MessageHandler handler); |
427 void EnqueueCommandMessage(Vector<const uint16_t> command, | |
428 v8::Debug::ClientData* client_data = NULL); | |
429 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, | 315 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, |
430 Handle<Object> data); | 316 Handle<Object> data); |
431 Handle<Context> GetDebugContext(); | 317 Handle<Context> GetDebugContext(); |
432 void HandleDebugBreak(); | 318 void HandleDebugBreak(); |
433 void ProcessDebugMessages(bool debug_command_only); | 319 void ProcessDebugMessages(); |
434 | 320 |
435 // Internal logic | 321 // Internal logic |
436 bool Load(); | 322 bool Load(); |
437 void Break(JavaScriptFrame* frame); | 323 void Break(JavaScriptFrame* frame); |
438 void SetAfterBreakTarget(JavaScriptFrame* frame); | 324 void SetAfterBreakTarget(JavaScriptFrame* frame); |
439 | 325 |
440 // Scripts handling. | 326 // Scripts handling. |
441 Handle<FixedArray> GetLoadedScripts(); | 327 Handle<FixedArray> GetLoadedScripts(); |
442 | 328 |
443 // Break point handling. | 329 // Break point handling. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 private: | 448 private: |
563 explicit Debug(Isolate* isolate); | 449 explicit Debug(Isolate* isolate); |
564 | 450 |
565 void UpdateState(); | 451 void UpdateState(); |
566 void Unload(); | 452 void Unload(); |
567 void SetNextBreakId() { | 453 void SetNextBreakId() { |
568 thread_local_.break_id_ = ++thread_local_.break_count_; | 454 thread_local_.break_id_ = ++thread_local_.break_count_; |
569 } | 455 } |
570 | 456 |
571 // Check whether there are commands in the command queue. | 457 // Check whether there are commands in the command queue. |
572 inline bool has_commands() const { return !command_queue_.IsEmpty(); } | |
573 inline bool ignore_events() const { return is_suppressed_ || !is_active_; } | 458 inline bool ignore_events() const { return is_suppressed_ || !is_active_; } |
574 inline bool break_disabled() const { | 459 inline bool break_disabled() const { |
575 return break_disabled_ || in_debug_event_listener_; | 460 return break_disabled_ || in_debug_event_listener_; |
576 } | 461 } |
577 | 462 |
578 void clear_suspended_generator() { | 463 void clear_suspended_generator() { |
579 thread_local_.suspended_generator_ = Smi::kZero; | 464 thread_local_.suspended_generator_ = Smi::kZero; |
580 } | 465 } |
581 | 466 |
582 bool has_suspended_generator() const { | 467 bool has_suspended_generator() const { |
(...skipping 17 matching lines...) Expand all Loading... |
600 Handle<String> name); | 485 Handle<String> name); |
601 | 486 |
602 // Mirror cache handling. | 487 // Mirror cache handling. |
603 void ClearMirrorCache(); | 488 void ClearMirrorCache(); |
604 | 489 |
605 void CallEventCallback(v8::DebugEvent event, | 490 void CallEventCallback(v8::DebugEvent event, |
606 Handle<Object> exec_state, | 491 Handle<Object> exec_state, |
607 Handle<Object> event_data, | 492 Handle<Object> event_data, |
608 v8::Debug::ClientData* client_data); | 493 v8::Debug::ClientData* client_data); |
609 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); | 494 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); |
610 void ProcessDebugEvent(v8::DebugEvent event, | 495 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); |
611 Handle<JSObject> event_data, | |
612 bool auto_continue); | |
613 void NotifyMessageHandler(v8::DebugEvent event, | |
614 Handle<JSObject> exec_state, | |
615 Handle<JSObject> event_data, | |
616 bool auto_continue); | |
617 void InvokeMessageHandler(MessageImpl message); | |
618 | 496 |
619 // Find the closest source position for a break point for a given position. | 497 // Find the closest source position for a break point for a given position. |
620 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, | 498 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, |
621 BreakPositionAlignment alignment); | 499 BreakPositionAlignment alignment); |
622 // Instrument code to break at break points. | 500 // Instrument code to break at break points. |
623 void ApplyBreakPoints(Handle<DebugInfo> debug_info); | 501 void ApplyBreakPoints(Handle<DebugInfo> debug_info); |
624 // Clear code from instrumentation. | 502 // Clear code from instrumentation. |
625 void ClearBreakPoints(Handle<DebugInfo> debug_info); | 503 void ClearBreakPoints(Handle<DebugInfo> debug_info); |
626 // Clear all code from instrumentation. | 504 // Clear all code from instrumentation. |
627 void ClearAllBreakPoints(); | 505 void ClearAllBreakPoints(); |
(...skipping 22 matching lines...) Expand all Loading... |
650 | 528 |
651 void PrintBreakLocation(); | 529 void PrintBreakLocation(); |
652 | 530 |
653 // Global handles. | 531 // Global handles. |
654 Handle<Context> debug_context_; | 532 Handle<Context> debug_context_; |
655 Handle<Object> event_listener_; | 533 Handle<Object> event_listener_; |
656 Handle<Object> event_listener_data_; | 534 Handle<Object> event_listener_data_; |
657 | 535 |
658 v8::Debug::MessageHandler message_handler_; | 536 v8::Debug::MessageHandler message_handler_; |
659 | 537 |
660 static const int kQueueInitialSize = 4; | |
661 base::Semaphore command_received_; // Signaled for each command received. | |
662 LockingCommandMessageQueue command_queue_; | |
663 | |
664 bool is_active_; | 538 bool is_active_; |
665 bool is_suppressed_; | 539 bool is_suppressed_; |
666 bool live_edit_enabled_; | 540 bool live_edit_enabled_; |
667 bool break_disabled_; | 541 bool break_disabled_; |
668 bool break_points_active_; | 542 bool break_points_active_; |
669 bool in_debug_event_listener_; | 543 bool in_debug_event_listener_; |
670 bool break_on_exception_; | 544 bool break_on_exception_; |
671 bool break_on_uncaught_exception_; | 545 bool break_on_uncaught_exception_; |
672 | 546 |
673 DebugInfoListNode* debug_info_list_; // List of active debug info objects. | 547 DebugInfoListNode* debug_info_list_; // List of active debug info objects. |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 Handle<Code> code); | 700 Handle<Code> code); |
827 static bool DebugBreakSlotIsPatched(Address pc); | 701 static bool DebugBreakSlotIsPatched(Address pc); |
828 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); | 702 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); |
829 }; | 703 }; |
830 | 704 |
831 | 705 |
832 } // namespace internal | 706 } // namespace internal |
833 } // namespace v8 | 707 } // namespace v8 |
834 | 708 |
835 #endif // V8_DEBUG_DEBUG_H_ | 709 #endif // V8_DEBUG_DEBUG_H_ |
OLD | NEW |