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

Side by Side Diff: src/debug.h

Issue 40290: Experimental: Merge 1395:1441 from bleeding_edge branch to the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/global/
Patch Set: Created 11 years, 9 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/d8-debug.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_V8_DEBUG_H_ 28 #ifndef V8_V8_DEBUG_H_
29 #define V8_V8_DEBUG_H_ 29 #define V8_V8_DEBUG_H_
30 30
31 #include "../include/v8-debug.h" 31 #include "../include/v8-debug.h"
32 #include "assembler.h" 32 #include "assembler.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "debug-agent.h"
34 #include "execution.h" 35 #include "execution.h"
35 #include "factory.h" 36 #include "factory.h"
36 #include "platform.h" 37 #include "platform.h"
37 #include "string-stream.h" 38 #include "string-stream.h"
39 #include "v8threads.h"
38 40
39 41
40 namespace v8 { namespace internal { 42 namespace v8 { namespace internal {
41 43
44
45 // Forward declarations.
46 class EnterDebugger;
47
48
42 // Step actions. NOTE: These values are in macros.py as well. 49 // Step actions. NOTE: These values are in macros.py as well.
43 enum StepAction { 50 enum StepAction {
44 StepNone = -1, // Stepping not prepared. 51 StepNone = -1, // Stepping not prepared.
45 StepOut = 0, // Step out of the current function. 52 StepOut = 0, // Step out of the current function.
46 StepNext = 1, // Step to the next statement in the current function. 53 StepNext = 1, // Step to the next statement in the current function.
47 StepIn = 2, // Step into new functions invoked or the next statement 54 StepIn = 2, // Step into new functions invoked or the next statement
48 // in the current function. 55 // in the current function.
49 StepMin = 3, // Perform a minimum step in the current function. 56 StepMin = 3, // Perform a minimum step in the current function.
50 StepInMin = 4 // Step into new functions invoked or perform a minimum step 57 StepInMin = 4 // Step into new functions invoked or perform a minimum step
51 // in the current function. 58 // in the current function.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 // This class controls the debug info for all functions which currently have 165 // This class controls the debug info for all functions which currently have
159 // active breakpoints in them. This debug info is held in the heap root object 166 // active breakpoints in them. This debug info is held in the heap root object
160 // debug_info which is a FixedArray. Each entry in this list is of class 167 // debug_info which is a FixedArray. Each entry in this list is of class
161 // DebugInfo. 168 // DebugInfo.
162 class Debug { 169 class Debug {
163 public: 170 public:
164 static void Setup(bool create_heap_objects); 171 static void Setup(bool create_heap_objects);
165 static bool Load(); 172 static bool Load();
166 static void Unload(); 173 static void Unload();
167 static bool IsLoaded() { return !debug_context_.is_null(); } 174 static bool IsLoaded() { return !debug_context_.is_null(); }
168 static bool InDebugger() { return Top::is_break(); } 175 static bool InDebugger() { return thread_local_.debugger_entry_ != NULL; }
176 static void PreemptionWhileInDebugger();
169 static void Iterate(ObjectVisitor* v); 177 static void Iterate(ObjectVisitor* v);
170 178
171 static Object* Break(Arguments args); 179 static Object* Break(Arguments args);
172 static void SetBreakPoint(Handle<SharedFunctionInfo> shared, 180 static void SetBreakPoint(Handle<SharedFunctionInfo> shared,
173 int source_position, 181 int source_position,
174 Handle<Object> break_point_object); 182 Handle<Object> break_point_object);
175 static void ClearBreakPoint(Handle<Object> break_point_object); 183 static void ClearBreakPoint(Handle<Object> break_point_object);
176 static void ClearAllBreakPoints(); 184 static void ClearAllBreakPoints();
177 static void FloodWithOneShot(Handle<SharedFunctionInfo> shared); 185 static void FloodWithOneShot(Handle<SharedFunctionInfo> shared);
178 static void FloodHandlerWithOneShot(); 186 static void FloodHandlerWithOneShot();
(...skipping 24 matching lines...) Expand all
203 211
204 // Getter for the debug_context. 212 // Getter for the debug_context.
205 inline static Handle<Context> debug_context() { return debug_context_; } 213 inline static Handle<Context> debug_context() { return debug_context_; }
206 214
207 // Check whether a global object is the debug global object. 215 // Check whether a global object is the debug global object.
208 static bool IsDebugGlobal(GlobalObject* global); 216 static bool IsDebugGlobal(GlobalObject* global);
209 217
210 // Fast check to see if any break points are active. 218 // Fast check to see if any break points are active.
211 inline static bool has_break_points() { return has_break_points_; } 219 inline static bool has_break_points() { return has_break_points_; }
212 220
221 static void NewBreak(StackFrame::Id break_frame_id);
222 static void SetBreak(StackFrame::Id break_frame_id, int break_id);
223 static StackFrame::Id break_frame_id() {
224 return thread_local_.break_frame_id_;
225 }
226 static int break_id() { return thread_local_.break_id_; }
227
228
229
230
213 static bool StepInActive() { return thread_local_.step_into_fp_ != 0; } 231 static bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
214 static void HandleStepIn(Handle<JSFunction> function, 232 static void HandleStepIn(Handle<JSFunction> function,
215 Address fp, 233 Address fp,
216 bool is_constructor); 234 bool is_constructor);
217 static Address step_in_fp() { return thread_local_.step_into_fp_; } 235 static Address step_in_fp() { return thread_local_.step_into_fp_; }
218 static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; } 236 static Address* step_in_fp_addr() { return &thread_local_.step_into_fp_; }
219 237
238 static EnterDebugger* debugger_entry() {
239 return thread_local_.debugger_entry_;
240 }
241 static void set_debugger_entry(EnterDebugger* entry) {
242 thread_local_.debugger_entry_ = entry;
243 }
244
245 static bool preemption_pending() {
246 return thread_local_.preemption_pending_;
247 }
248 static void set_preemption_pending(bool preemption_pending) {
249 thread_local_.preemption_pending_ = preemption_pending;
250 }
251
220 // Getter and setter for the disable break state. 252 // Getter and setter for the disable break state.
221 static bool disable_break() { return disable_break_; } 253 static bool disable_break() { return disable_break_; }
222 static void set_disable_break(bool disable_break) { 254 static void set_disable_break(bool disable_break) {
223 disable_break_ = disable_break; 255 disable_break_ = disable_break;
224 } 256 }
225 257
226 // Getters for the current exception break state. 258 // Getters for the current exception break state.
227 static bool break_on_exception() { return break_on_exception_; } 259 static bool break_on_exception() { return break_on_exception_; }
228 static bool break_on_uncaught_exception() { 260 static bool break_on_uncaught_exception() {
229 return break_on_uncaught_exception_; 261 return break_on_uncaught_exception_;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 static Handle<Context> debug_context_; 337 static Handle<Context> debug_context_;
306 338
307 // Boolean state indicating whether any break points are set. 339 // Boolean state indicating whether any break points are set.
308 static bool has_break_points_; 340 static bool has_break_points_;
309 static DebugInfoListNode* debug_info_list_; 341 static DebugInfoListNode* debug_info_list_;
310 342
311 static bool disable_break_; 343 static bool disable_break_;
312 static bool break_on_exception_; 344 static bool break_on_exception_;
313 static bool break_on_uncaught_exception_; 345 static bool break_on_uncaught_exception_;
314 346
315 // Per-thread: 347 // Per-thread data.
316 class ThreadLocal { 348 class ThreadLocal {
317 public: 349 public:
350 // Counter for generating next break id.
351 int break_count_;
352
353 // Current break id.
354 int break_id_;
355
356 // Frame id for the frame of the current break.
357 StackFrame::Id break_frame_id_;
358
318 // Step action for last step performed. 359 // Step action for last step performed.
319 StepAction last_step_action_; 360 StepAction last_step_action_;
320 361
321 // Source statement position from last step next action. 362 // Source statement position from last step next action.
322 int last_statement_position_; 363 int last_statement_position_;
323 364
324 // Number of steps left to perform before debug event. 365 // Number of steps left to perform before debug event.
325 int step_count_; 366 int step_count_;
326 367
327 // Frame pointer from last step next action. 368 // Frame pointer from last step next action.
328 Address last_fp_; 369 Address last_fp_;
329 370
330 // Frame pointer for frame from which step in was performed. 371 // Frame pointer for frame from which step in was performed.
331 Address step_into_fp_; 372 Address step_into_fp_;
332 373
333 // Storage location for jump when exiting debug break calls. 374 // Storage location for jump when exiting debug break calls.
334 Address after_break_target_; 375 Address after_break_target_;
376
377 // Top debugger entry.
378 EnterDebugger* debugger_entry_;
379
380 // Preemption happened while debugging.
381 bool preemption_pending_;
335 }; 382 };
336 383
337 // Storage location for registers when handling debug break calls 384 // Storage location for registers when handling debug break calls
338 static JSCallerSavedBuffer registers_; 385 static JSCallerSavedBuffer registers_;
339 static ThreadLocal thread_local_; 386 static ThreadLocal thread_local_;
340 static void ThreadInit(); 387 static void ThreadInit();
341 388
342 // Code object for debug break return entry code. 389 // Code object for debug break return entry code.
343 static Code* debug_break_return_entry_; 390 static Code* debug_break_return_entry_;
344 391
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 static void SetHostDispatchHandler(v8::DebugHostDispatchHandler handler, 431 static void SetHostDispatchHandler(v8::DebugHostDispatchHandler handler,
385 void* data); 432 void* data);
386 static void SendMessage(Vector<uint16_t> message); 433 static void SendMessage(Vector<uint16_t> message);
387 static void ProcessCommand(Vector<const uint16_t> command); 434 static void ProcessCommand(Vector<const uint16_t> command);
388 static void ProcessHostDispatch(void* dispatch); 435 static void ProcessHostDispatch(void* dispatch);
389 static void UpdateActiveDebugger(); 436 static void UpdateActiveDebugger();
390 static Handle<Object> Call(Handle<JSFunction> fun, 437 static Handle<Object> Call(Handle<JSFunction> fun,
391 Handle<Object> data, 438 Handle<Object> data,
392 bool* pending_exception); 439 bool* pending_exception);
393 440
441 // Start the debugger agent listening on the provided port.
442 static bool StartAgent(int port);
443
394 inline static bool EventActive(v8::DebugEvent event) { 444 inline static bool EventActive(v8::DebugEvent event) {
395 // Currently argument event is not used. 445 // Currently argument event is not used.
396 return !Debugger::compiling_natives_ && Debugger::debugger_active_; 446 return !Debugger::compiling_natives_ && Debugger::debugger_active_;
397 } 447 }
398 448
399 static void set_debugger_active(bool debugger_active) { 449 static void set_debugger_active(bool debugger_active) {
400 Debugger::debugger_active_ = debugger_active; 450 Debugger::debugger_active_ = debugger_active;
401 } 451 }
402 static bool debugger_active() { return Debugger::debugger_active_; } 452 static bool debugger_active() { return Debugger::debugger_active_; }
403 static void set_compiling_natives(bool compiling_natives) { 453 static void set_compiling_natives(bool compiling_natives) {
404 Debugger::compiling_natives_ = compiling_natives; 454 Debugger::compiling_natives_ = compiling_natives;
405 } 455 }
406 static bool compiling_natives() { return Debugger::compiling_natives_; } 456 static bool compiling_natives() { return Debugger::compiling_natives_; }
407 static void set_loading_debugger(bool v) { is_loading_debugger_ = v; } 457 static void set_loading_debugger(bool v) { is_loading_debugger_ = v; }
408 static bool is_loading_debugger() { return Debugger::is_loading_debugger_; } 458 static bool is_loading_debugger() { return Debugger::is_loading_debugger_; }
409 459
410 private: 460 private:
411 static Handle<Object> event_listener_; // Global handle to listener 461 static Handle<Object> event_listener_; // Global handle to listener
412 static Handle<Object> event_listener_data_; 462 static Handle<Object> event_listener_data_;
413 static bool debugger_active_; // Are there any active debugger? 463 static bool debugger_active_; // Are there any active debugger?
414 static bool compiling_natives_; // Are we compiling natives? 464 static bool compiling_natives_; // Are we compiling natives?
415 static bool is_loading_debugger_; // Are we loading the debugger? 465 static bool is_loading_debugger_; // Are we loading the debugger?
416 static DebugMessageThread* message_thread_; 466 static DebugMessageThread* message_thread_;
417 static v8::DebugMessageHandler message_handler_; 467 static v8::DebugMessageHandler message_handler_;
418 static void* message_handler_data_; 468 static void* message_handler_data_;
419 static v8::DebugHostDispatchHandler host_dispatch_handler_; 469 static v8::DebugHostDispatchHandler host_dispatch_handler_;
420 static void* host_dispatch_handler_data_; 470 static void* host_dispatch_handler_data_;
421 471
472 static DebuggerAgent* agent_;
473
422 friend class DebugMessageThread; 474 friend class DebugMessageThread;
423 }; 475 };
424 476
425 477
426 // A Queue of Vector<uint16_t> objects. A thread-safe version is 478 // A Queue of Vector<uint16_t> objects. A thread-safe version is
427 // LockingMessageQueue, based on this class. 479 // LockingMessageQueue, based on this class.
428 class MessageQueue BASE_EMBEDDED { 480 class MessageQueue BASE_EMBEDDED {
429 public: 481 public:
430 explicit MessageQueue(int size); 482 explicit MessageQueue(int size);
431 ~MessageQueue(); 483 ~MessageQueue();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 DISALLOW_COPY_AND_ASSIGN(DebugMessageThread); 558 DISALLOW_COPY_AND_ASSIGN(DebugMessageThread);
507 }; 559 };
508 560
509 561
510 // This class is used for entering the debugger. Create an instance in the stack 562 // This class is used for entering the debugger. Create an instance in the stack
511 // to enter the debugger. This will set the current break state, make sure the 563 // to enter the debugger. This will set the current break state, make sure the
512 // debugger is loaded and switch to the debugger context. If the debugger for 564 // debugger is loaded and switch to the debugger context. If the debugger for
513 // some reason could not be entered FailedToEnter will return true. 565 // some reason could not be entered FailedToEnter will return true.
514 class EnterDebugger BASE_EMBEDDED { 566 class EnterDebugger BASE_EMBEDDED {
515 public: 567 public:
516 EnterDebugger() : has_js_frames_(!it_.done()) { 568 EnterDebugger()
569 : prev_(Debug::debugger_entry()),
570 has_js_frames_(!it_.done()) {
571 ASSERT(!Debug::preemption_pending());
572
573 // Link recursive debugger entry.
574 Debug::set_debugger_entry(this);
575
576 // If a preemption is pending when first entering the debugger clear it as
577 // we don't want preemption happening while executing JavaScript in the
578 // debugger. When recursively entering the debugger the preemption flag
579 // cannot be set as this is disabled while in the debugger (see
580 // RuntimePreempt).
581 if (prev_ == NULL && StackGuard::IsPreempted()) {
582 StackGuard::Continue(PREEMPT);
583 }
584 ASSERT(!StackGuard::IsPreempted());
585
517 // Store the previous break id and frame id. 586 // Store the previous break id and frame id.
518 break_id_ = Top::break_id(); 587 break_id_ = Debug::break_id();
519 break_frame_id_ = Top::break_frame_id(); 588 break_frame_id_ = Debug::break_frame_id();
520 589
521 // Create the new break info. If there is no JavaScript frames there is no 590 // Create the new break info. If there is no JavaScript frames there is no
522 // break frame id. 591 // break frame id.
523 if (has_js_frames_) { 592 if (has_js_frames_) {
524 Top::new_break(it_.frame()->id()); 593 Debug::NewBreak(it_.frame()->id());
525 } else { 594 } else {
526 Top::new_break(StackFrame::NO_ID); 595 Debug::NewBreak(StackFrame::NO_ID);
527 } 596 }
528 597
529 // Make sure that debugger is loaded and enter the debugger context. 598 // Make sure that debugger is loaded and enter the debugger context.
530 load_failed_ = !Debug::Load(); 599 load_failed_ = !Debug::Load();
531 if (!load_failed_) { 600 if (!load_failed_) {
532 // NOTE the member variable save which saves the previous context before 601 // NOTE the member variable save which saves the previous context before
533 // this change. 602 // this change.
534 Top::set_context(*Debug::debug_context()); 603 Top::set_context(*Debug::debug_context());
535 } 604 }
536 } 605 }
537 606
538 ~EnterDebugger() { 607 ~EnterDebugger() {
539 // Restore to the previous break state. 608 // Restore to the previous break state.
540 Top::set_break(break_frame_id_, break_id_); 609 Debug::SetBreak(break_frame_id_, break_id_);
610
611 // Request preemption when leaving the last debugger entry and a preemption
612 // had been recorded while debugging. This is to avoid starvation in some
613 // debugging scenarios.
614 if (prev_ == NULL && Debug::preemption_pending()) {
615 StackGuard::Preempt();
616 Debug::set_preemption_pending(false);
617 }
618
619 // Leaving this debugger entry.
620 Debug::set_debugger_entry(prev_);
541 } 621 }
542 622
543 // Check whether the debugger could be entered. 623 // Check whether the debugger could be entered.
544 inline bool FailedToEnter() { return load_failed_; } 624 inline bool FailedToEnter() { return load_failed_; }
545 625
546 // Check whether there are any JavaScript frames on the stack. 626 // Check whether there are any JavaScript frames on the stack.
547 inline bool HasJavaScriptFrames() { return has_js_frames_; } 627 inline bool HasJavaScriptFrames() { return has_js_frames_; }
548 628
549 private: 629 private:
630 EnterDebugger* prev_; // Previous debugger entry if entered recursively.
550 JavaScriptFrameIterator it_; 631 JavaScriptFrameIterator it_;
551 const bool has_js_frames_; // Were there any JavaScript frames? 632 const bool has_js_frames_; // Were there any JavaScript frames?
552 StackFrame::Id break_frame_id_; // Previous break frame id. 633 StackFrame::Id break_frame_id_; // Previous break frame id.
553 int break_id_; // Previous break id. 634 int break_id_; // Previous break id.
554 bool load_failed_; // Did the debugger fail to load? 635 bool load_failed_; // Did the debugger fail to load?
555 SaveContext save_; // Saves previous context. 636 SaveContext save_; // Saves previous context.
556 }; 637 };
557 638
558 639
559 // Stack allocated class for disabling break. 640 // Stack allocated class for disabling break.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 } 693 }
613 private: 694 private:
614 Debug::AddressId id_; 695 Debug::AddressId id_;
615 int reg_; 696 int reg_;
616 }; 697 };
617 698
618 699
619 } } // namespace v8::internal 700 } } // namespace v8::internal
620 701
621 #endif // V8_V8_DEBUG_H_ 702 #endif // V8_V8_DEBUG_H_
OLDNEW
« no previous file with comments | « src/d8-debug.cc ('k') | src/debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698