| 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 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "api.h" | 7 #include "api.h" |
| 8 #include "arguments.h" | 8 #include "arguments.h" |
| 9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
| 10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 thread_local_.break_id_ = 0; | 558 thread_local_.break_id_ = 0; |
| 559 thread_local_.break_frame_id_ = StackFrame::NO_ID; | 559 thread_local_.break_frame_id_ = StackFrame::NO_ID; |
| 560 thread_local_.last_step_action_ = StepNone; | 560 thread_local_.last_step_action_ = StepNone; |
| 561 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; | 561 thread_local_.last_statement_position_ = RelocInfo::kNoPosition; |
| 562 thread_local_.step_count_ = 0; | 562 thread_local_.step_count_ = 0; |
| 563 thread_local_.last_fp_ = 0; | 563 thread_local_.last_fp_ = 0; |
| 564 thread_local_.queued_step_count_ = 0; | 564 thread_local_.queued_step_count_ = 0; |
| 565 thread_local_.step_into_fp_ = 0; | 565 thread_local_.step_into_fp_ = 0; |
| 566 thread_local_.step_out_fp_ = 0; | 566 thread_local_.step_out_fp_ = 0; |
| 567 // TODO(isolates): frames_are_dropped_? | 567 // TODO(isolates): frames_are_dropped_? |
| 568 thread_local_.debugger_entry_ = NULL; | 568 thread_local_.current_debug_scope_ = NULL; |
| 569 thread_local_.restarter_frame_function_pointer_ = NULL; | 569 thread_local_.restarter_frame_function_pointer_ = NULL; |
| 570 thread_local_.promise_on_stack_ = NULL; | 570 thread_local_.promise_on_stack_ = NULL; |
| 571 } | 571 } |
| 572 | 572 |
| 573 | 573 |
| 574 char* Debug::ArchiveDebug(char* storage) { | 574 char* Debug::ArchiveDebug(char* storage) { |
| 575 char* to = storage; | 575 char* to = storage; |
| 576 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); | 576 MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); |
| 577 ThreadInit(); | 577 ThreadInit(); |
| 578 return storage + ArchiveSpacePerThread(); | 578 return storage + ArchiveSpacePerThread(); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 ASSERT(args.length() == 0); | 887 ASSERT(args.length() == 0); |
| 888 | 888 |
| 889 if (live_edit_enabled()) { | 889 if (live_edit_enabled()) { |
| 890 thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED; | 890 thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED; |
| 891 } | 891 } |
| 892 | 892 |
| 893 // Just continue if breaks are disabled or debugger cannot be loaded. | 893 // Just continue if breaks are disabled or debugger cannot be loaded. |
| 894 if (break_disabled_) return; | 894 if (break_disabled_) return; |
| 895 | 895 |
| 896 // Enter the debugger. | 896 // Enter the debugger. |
| 897 EnterDebugger debugger(isolate_); | 897 DebugScope debug_scope(this); |
| 898 if (debugger.FailedToEnter()) return; | 898 if (debug_scope.failed()) return; |
| 899 | 899 |
| 900 // Postpone interrupt during breakpoint processing. | 900 // Postpone interrupt during breakpoint processing. |
| 901 PostponeInterruptsScope postpone(isolate_); | 901 PostponeInterruptsScope postpone(isolate_); |
| 902 | 902 |
| 903 // Get the debug info (create it if it does not exist). | 903 // Get the debug info (create it if it does not exist). |
| 904 Handle<SharedFunctionInfo> shared = | 904 Handle<SharedFunctionInfo> shared = |
| 905 Handle<SharedFunctionInfo>(frame->function()->shared()); | 905 Handle<SharedFunctionInfo>(frame->function()->shared()); |
| 906 Handle<DebugInfo> debug_info = GetDebugInfo(shared); | 906 Handle<DebugInfo> debug_info = GetDebugInfo(shared); |
| 907 | 907 |
| 908 // Find the break point where execution has stopped. | 908 // Find the break point where execution has stopped. |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 } | 1341 } |
| 1342 | 1342 |
| 1343 | 1343 |
| 1344 void Debug::PrepareStep(StepAction step_action, | 1344 void Debug::PrepareStep(StepAction step_action, |
| 1345 int step_count, | 1345 int step_count, |
| 1346 StackFrame::Id frame_id) { | 1346 StackFrame::Id frame_id) { |
| 1347 HandleScope scope(isolate_); | 1347 HandleScope scope(isolate_); |
| 1348 | 1348 |
| 1349 PrepareForBreakPoints(); | 1349 PrepareForBreakPoints(); |
| 1350 | 1350 |
| 1351 ASSERT(is_entered()); | 1351 ASSERT(in_debug_scope()); |
| 1352 | 1352 |
| 1353 // Remember this step action and count. | 1353 // Remember this step action and count. |
| 1354 thread_local_.last_step_action_ = step_action; | 1354 thread_local_.last_step_action_ = step_action; |
| 1355 if (step_action == StepOut) { | 1355 if (step_action == StepOut) { |
| 1356 // For step out target frame will be found on the stack so there is no need | 1356 // For step out target frame will be found on the stack so there is no need |
| 1357 // to set step counter for it. It's expected to always be 0 for StepOut. | 1357 // to set step counter for it. It's expected to always be 0 for StepOut. |
| 1358 thread_local_.step_count_ = 0; | 1358 thread_local_.step_count_ = 0; |
| 1359 } else { | 1359 } else { |
| 1360 thread_local_.step_count_ = step_count; | 1360 thread_local_.step_count_ = step_count; |
| 1361 } | 1361 } |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2451 | 2451 |
| 2452 | 2452 |
| 2453 bool Debug::IsDebugGlobal(GlobalObject* global) { | 2453 bool Debug::IsDebugGlobal(GlobalObject* global) { |
| 2454 return is_loaded() && global == debug_context()->global_object(); | 2454 return is_loaded() && global == debug_context()->global_object(); |
| 2455 } | 2455 } |
| 2456 | 2456 |
| 2457 | 2457 |
| 2458 void Debug::ClearMirrorCache() { | 2458 void Debug::ClearMirrorCache() { |
| 2459 PostponeInterruptsScope postpone(isolate_); | 2459 PostponeInterruptsScope postpone(isolate_); |
| 2460 HandleScope scope(isolate_); | 2460 HandleScope scope(isolate_); |
| 2461 ASSERT(isolate_->context() == *Debug::debug_context()); | 2461 AssertDebugContext(); |
| 2462 | 2462 |
| 2463 // Clear the mirror cache. | 2463 // Clear the mirror cache. |
| 2464 Handle<Object> fun = Object::GetProperty( | 2464 Handle<Object> fun = Object::GetProperty( |
| 2465 isolate_, | 2465 isolate_, |
| 2466 isolate_->global_object(), | 2466 isolate_->global_object(), |
| 2467 "ClearMirrorCache").ToHandleChecked(); | 2467 "ClearMirrorCache").ToHandleChecked(); |
| 2468 ASSERT(fun->IsJSFunction()); | 2468 ASSERT(fun->IsJSFunction()); |
| 2469 Execution::TryCall(Handle<JSFunction>::cast(fun), | 2469 Execution::TryCall(Handle<JSFunction>::cast(fun), |
| 2470 Handle<JSObject>(Debug::debug_context()->global_object()), | 2470 Handle<JSObject>(Debug::debug_context()->global_object()), |
| 2471 0, | 2471 0, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2507 // Generate events for collected scripts. | 2507 // Generate events for collected scripts. |
| 2508 if (script_cache_ != NULL) { | 2508 if (script_cache_ != NULL) { |
| 2509 script_cache_->ProcessCollectedScripts(); | 2509 script_cache_->ProcessCollectedScripts(); |
| 2510 } | 2510 } |
| 2511 } | 2511 } |
| 2512 | 2512 |
| 2513 | 2513 |
| 2514 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name, | 2514 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name, |
| 2515 int argc, | 2515 int argc, |
| 2516 Handle<Object> argv[]) { | 2516 Handle<Object> argv[]) { |
| 2517 ASSERT(isolate_->context() == *debug_context()); | 2517 AssertDebugContext(); |
| 2518 // Create the execution state object. | 2518 // Create the execution state object. |
| 2519 Handle<Object> constructor = Object::GetProperty( | 2519 Handle<Object> constructor = Object::GetProperty( |
| 2520 isolate_, isolate_->global_object(), constructor_name).ToHandleChecked(); | 2520 isolate_, isolate_->global_object(), constructor_name).ToHandleChecked(); |
| 2521 ASSERT(constructor->IsJSFunction()); | 2521 ASSERT(constructor->IsJSFunction()); |
| 2522 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); | 2522 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); |
| 2523 return Execution::TryCall(Handle<JSFunction>::cast(constructor), | 2523 return Execution::TryCall(Handle<JSFunction>::cast(constructor), |
| 2524 Handle<JSObject>(debug_context()->global_object()), | 2524 Handle<JSObject>(debug_context()->global_object()), |
| 2525 argc, | 2525 argc, |
| 2526 argv); | 2526 argv); |
| 2527 } | 2527 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2574 Handle<Object> exec_state; | 2574 Handle<Object> exec_state; |
| 2575 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); | 2575 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); |
| 2576 // Create the script collected event object. | 2576 // Create the script collected event object. |
| 2577 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); | 2577 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); |
| 2578 Handle<Object> argv[] = { exec_state, id_object }; | 2578 Handle<Object> argv[] = { exec_state, id_object }; |
| 2579 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv); | 2579 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv); |
| 2580 } | 2580 } |
| 2581 | 2581 |
| 2582 | 2582 |
| 2583 void Debug::OnException(Handle<Object> exception, bool uncaught) { | 2583 void Debug::OnException(Handle<Object> exception, bool uncaught) { |
| 2584 if (is_entered() || ignore_events()) return; | 2584 if (in_debug_scope() || ignore_events()) return; |
| 2585 | 2585 |
| 2586 HandleScope scope(isolate_); | 2586 HandleScope scope(isolate_); |
| 2587 Handle<Object> promise = GetPromiseForUncaughtException(); | 2587 Handle<Object> promise = GetPromiseForUncaughtException(); |
| 2588 uncaught |= !promise->IsUndefined(); | 2588 uncaught |= !promise->IsUndefined(); |
| 2589 | 2589 |
| 2590 // Bail out if exception breaks are not active | 2590 // Bail out if exception breaks are not active |
| 2591 if (uncaught) { | 2591 if (uncaught) { |
| 2592 // Uncaught exceptions are reported by either flags. | 2592 // Uncaught exceptions are reported by either flags. |
| 2593 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; | 2593 if (!(break_on_uncaught_exception_ || break_on_exception_)) return; |
| 2594 } else { | 2594 } else { |
| 2595 // Caught exceptions are reported is activated. | 2595 // Caught exceptions are reported is activated. |
| 2596 if (!break_on_exception_) return; | 2596 if (!break_on_exception_) return; |
| 2597 } | 2597 } |
| 2598 | 2598 |
| 2599 // Enter the debugger. | 2599 DebugScope debug_scope(this); |
| 2600 EnterDebugger debugger(isolate_); | 2600 if (debug_scope.failed()) return; |
| 2601 if (debugger.FailedToEnter()) return; | |
| 2602 | 2601 |
| 2603 // Clear all current stepping setup. | 2602 // Clear all current stepping setup. |
| 2604 ClearStepping(); | 2603 ClearStepping(); |
| 2605 | 2604 |
| 2606 // Create the event data object. | 2605 // Create the event data object. |
| 2607 Handle<Object> event_data; | 2606 Handle<Object> event_data; |
| 2608 // Bail out and don't call debugger if exception. | 2607 // Bail out and don't call debugger if exception. |
| 2609 if (!MakeExceptionEvent( | 2608 if (!MakeExceptionEvent( |
| 2610 exception, uncaught, promise).ToHandle(&event_data)) { | 2609 exception, uncaught, promise).ToHandle(&event_data)) { |
| 2611 return; | 2610 return; |
| 2612 } | 2611 } |
| 2613 | 2612 |
| 2614 // Process debug event. | 2613 // Process debug event. |
| 2615 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); | 2614 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); |
| 2616 // Return to continue execution from where the exception was thrown. | 2615 // Return to continue execution from where the exception was thrown. |
| 2617 } | 2616 } |
| 2618 | 2617 |
| 2619 | 2618 |
| 2620 void Debug::OnDebugBreak(Handle<Object> break_points_hit, | 2619 void Debug::OnDebugBreak(Handle<Object> break_points_hit, |
| 2621 bool auto_continue) { | 2620 bool auto_continue) { |
| 2622 // Debugger has already been entered by caller. | 2621 // The caller provided for DebugScope. |
| 2623 ASSERT(isolate_->context() == *debug_context()); | 2622 AssertDebugContext(); |
| 2624 // Bail out if there is no listener for this event | 2623 // Bail out if there is no listener for this event |
| 2625 if (ignore_events()) return; | 2624 if (ignore_events()) return; |
| 2626 | 2625 |
| 2627 HandleScope scope(isolate_); | 2626 HandleScope scope(isolate_); |
| 2628 // Create the event data object. | 2627 // Create the event data object. |
| 2629 Handle<Object> event_data; | 2628 Handle<Object> event_data; |
| 2630 // Bail out and don't call debugger if exception. | 2629 // Bail out and don't call debugger if exception. |
| 2631 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; | 2630 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; |
| 2632 | 2631 |
| 2633 // Process debug event. | 2632 // Process debug event. |
| 2634 ProcessDebugEvent(v8::Break, | 2633 ProcessDebugEvent(v8::Break, |
| 2635 Handle<JSObject>::cast(event_data), | 2634 Handle<JSObject>::cast(event_data), |
| 2636 auto_continue); | 2635 auto_continue); |
| 2637 } | 2636 } |
| 2638 | 2637 |
| 2639 | 2638 |
| 2640 void Debug::OnBeforeCompile(Handle<Script> script) { | 2639 void Debug::OnBeforeCompile(Handle<Script> script) { |
| 2641 if (is_entered() || ignore_events()) return; | 2640 if (in_debug_scope() || ignore_events()) return; |
| 2642 | 2641 |
| 2643 HandleScope scope(isolate_); | 2642 HandleScope scope(isolate_); |
| 2644 // Enter the debugger. | 2643 DebugScope debug_scope(this); |
| 2645 EnterDebugger debugger(isolate_); | 2644 if (debug_scope.failed()) return; |
| 2646 if (debugger.FailedToEnter()) return; | |
| 2647 | 2645 |
| 2648 // Create the event data object. | 2646 // Create the event data object. |
| 2649 Handle<Object> event_data; | 2647 Handle<Object> event_data; |
| 2650 // Bail out and don't call debugger if exception. | 2648 // Bail out and don't call debugger if exception. |
| 2651 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; | 2649 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; |
| 2652 | 2650 |
| 2653 // Process debug event. | 2651 // Process debug event. |
| 2654 ProcessDebugEvent(v8::BeforeCompile, | 2652 ProcessDebugEvent(v8::BeforeCompile, |
| 2655 Handle<JSObject>::cast(event_data), | 2653 Handle<JSObject>::cast(event_data), |
| 2656 true); | 2654 true); |
| 2657 } | 2655 } |
| 2658 | 2656 |
| 2659 | 2657 |
| 2660 // Handle debugger actions when a new script is compiled. | 2658 // Handle debugger actions when a new script is compiled. |
| 2661 void Debug::OnAfterCompile(Handle<Script> script, | 2659 void Debug::OnAfterCompile(Handle<Script> script, |
| 2662 AfterCompileFlags after_compile_flags) { | 2660 AfterCompileFlags after_compile_flags) { |
| 2663 // Add the newly compiled script to the script cache. | 2661 // Add the newly compiled script to the script cache. |
| 2664 if (script_cache_ != NULL) script_cache_->Add(script); | 2662 if (script_cache_ != NULL) script_cache_->Add(script); |
| 2665 | 2663 |
| 2666 // No more to do if not debugging. | 2664 // No more to do if not debugging. |
| 2667 if (is_entered() || ignore_events()) return; | 2665 if (in_debug_scope() || ignore_events()) return; |
| 2668 | 2666 |
| 2669 HandleScope scope(isolate_); | 2667 HandleScope scope(isolate_); |
| 2670 // Store whether in debugger before entering debugger. | 2668 // Store whether in debugger before entering debugger. |
| 2671 bool in_debugger = is_entered(); | 2669 bool was_in_scope = in_debug_scope(); |
| 2672 | 2670 |
| 2673 // Enter the debugger. | 2671 DebugScope debug_scope(this); |
| 2674 EnterDebugger debugger(isolate_); | 2672 if (debug_scope.failed()) return; |
| 2675 if (debugger.FailedToEnter()) return; | |
| 2676 | 2673 |
| 2677 // If debugging there might be script break points registered for this | 2674 // If debugging there might be script break points registered for this |
| 2678 // script. Make sure that these break points are set. | 2675 // script. Make sure that these break points are set. |
| 2679 | 2676 |
| 2680 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). | 2677 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). |
| 2681 Handle<String> update_script_break_points_string = | 2678 Handle<String> update_script_break_points_string = |
| 2682 isolate_->factory()->InternalizeOneByteString( | 2679 isolate_->factory()->InternalizeOneByteString( |
| 2683 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); | 2680 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); |
| 2684 Handle<GlobalObject> debug_global(debug_context()->global_object()); | 2681 Handle<GlobalObject> debug_global(debug_context()->global_object()); |
| 2685 Handle<Object> update_script_break_points = | 2682 Handle<Object> update_script_break_points = |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2696 | 2693 |
| 2697 // Call UpdateScriptBreakPoints expect no exceptions. | 2694 // Call UpdateScriptBreakPoints expect no exceptions. |
| 2698 Handle<Object> argv[] = { wrapper }; | 2695 Handle<Object> argv[] = { wrapper }; |
| 2699 if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), | 2696 if (Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), |
| 2700 isolate_->js_builtins_object(), | 2697 isolate_->js_builtins_object(), |
| 2701 ARRAY_SIZE(argv), | 2698 ARRAY_SIZE(argv), |
| 2702 argv).is_null()) { | 2699 argv).is_null()) { |
| 2703 return; | 2700 return; |
| 2704 } | 2701 } |
| 2705 // Bail out based on state or if there is no listener for this event | 2702 // Bail out based on state or if there is no listener for this event |
| 2706 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; | 2703 if (was_in_scope && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; |
| 2707 | 2704 |
| 2708 // Create the compile state object. | 2705 // Create the compile state object. |
| 2709 Handle<Object> event_data; | 2706 Handle<Object> event_data; |
| 2710 // Bail out and don't call debugger if exception. | 2707 // Bail out and don't call debugger if exception. |
| 2711 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; | 2708 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; |
| 2712 | 2709 |
| 2713 // Process debug event. | 2710 // Process debug event. |
| 2714 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); | 2711 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); |
| 2715 } | 2712 } |
| 2716 | 2713 |
| 2717 | 2714 |
| 2718 void Debug::OnScriptCollected(int id) { | 2715 void Debug::OnScriptCollected(int id) { |
| 2719 if (is_entered() || ignore_events()) return; | 2716 if (in_debug_scope() || ignore_events()) return; |
| 2720 | 2717 |
| 2721 HandleScope scope(isolate_); | 2718 HandleScope scope(isolate_); |
| 2722 // Enter the debugger. | 2719 DebugScope debug_scope(this); |
| 2723 EnterDebugger debugger(isolate_); | 2720 if (debug_scope.failed()) return; |
| 2724 if (debugger.FailedToEnter()) return; | |
| 2725 | 2721 |
| 2726 // Create the script collected state object. | 2722 // Create the script collected state object. |
| 2727 Handle<Object> event_data; | 2723 Handle<Object> event_data; |
| 2728 // Bail out and don't call debugger if exception. | 2724 // Bail out and don't call debugger if exception. |
| 2729 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; | 2725 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; |
| 2730 | 2726 |
| 2731 // Process debug event. | 2727 // Process debug event. |
| 2732 ProcessDebugEvent(v8::ScriptCollected, | 2728 ProcessDebugEvent(v8::ScriptCollected, |
| 2733 Handle<JSObject>::cast(event_data), | 2729 Handle<JSObject>::cast(event_data), |
| 2734 true); | 2730 true); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2799 event_listener_data_ }; | 2795 event_listener_data_ }; |
| 2800 Execution::TryCall(Handle<JSFunction>::cast(event_listener_), | 2796 Execution::TryCall(Handle<JSFunction>::cast(event_listener_), |
| 2801 isolate_->global_object(), | 2797 isolate_->global_object(), |
| 2802 ARRAY_SIZE(argv), | 2798 ARRAY_SIZE(argv), |
| 2803 argv); | 2799 argv); |
| 2804 } | 2800 } |
| 2805 } | 2801 } |
| 2806 | 2802 |
| 2807 | 2803 |
| 2808 Handle<Context> Debug::GetDebugContext() { | 2804 Handle<Context> Debug::GetDebugContext() { |
| 2809 EnterDebugger debugger(isolate_); | 2805 DebugScope debug_scope(this); |
| 2810 // The global handle may be destroyed soon after. Return it reboxed. | 2806 // The global handle may be destroyed soon after. Return it reboxed. |
| 2811 return handle(*debug_context(), isolate_); | 2807 return handle(*debug_context(), isolate_); |
| 2812 } | 2808 } |
| 2813 | 2809 |
| 2814 | 2810 |
| 2815 void Debug::NotifyMessageHandler(v8::DebugEvent event, | 2811 void Debug::NotifyMessageHandler(v8::DebugEvent event, |
| 2816 Handle<JSObject> exec_state, | 2812 Handle<JSObject> exec_state, |
| 2817 Handle<JSObject> event_data, | 2813 Handle<JSObject> event_data, |
| 2818 bool auto_continue) { | 2814 bool auto_continue) { |
| 2819 ASSERT(is_active_); | 2815 ASSERT(is_active_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2838 break; | 2834 break; |
| 2839 case v8::NewFunction: | 2835 case v8::NewFunction: |
| 2840 break; | 2836 break; |
| 2841 default: | 2837 default: |
| 2842 UNREACHABLE(); | 2838 UNREACHABLE(); |
| 2843 } | 2839 } |
| 2844 | 2840 |
| 2845 // The debug command interrupt flag might have been set when the command was | 2841 // The debug command interrupt flag might have been set when the command was |
| 2846 // added. It should be enough to clear the flag only once while we are in the | 2842 // added. It should be enough to clear the flag only once while we are in the |
| 2847 // debugger. | 2843 // debugger. |
| 2848 ASSERT(is_entered()); | 2844 ASSERT(in_debug_scope()); |
| 2849 isolate_->stack_guard()->ClearDebugCommand(); | 2845 isolate_->stack_guard()->ClearDebugCommand(); |
| 2850 | 2846 |
| 2851 // Notify the debugger that a debug event has occurred unless auto continue is | 2847 // Notify the debugger that a debug event has occurred unless auto continue is |
| 2852 // active in which case no event is send. | 2848 // active in which case no event is send. |
| 2853 if (sendEventMessage) { | 2849 if (sendEventMessage) { |
| 2854 MessageImpl message = MessageImpl::NewEvent( | 2850 MessageImpl message = MessageImpl::NewEvent( |
| 2855 event, | 2851 event, |
| 2856 auto_continue, | 2852 auto_continue, |
| 2857 Handle<JSObject>::cast(exec_state), | 2853 Handle<JSObject>::cast(exec_state), |
| 2858 Handle<JSObject>::cast(event_data)); | 2854 Handle<JSObject>::cast(event_data)); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2960 event_listener_data_ = global_handles->Create(*data); | 2956 event_listener_data_ = global_handles->Create(*data); |
| 2961 } | 2957 } |
| 2962 | 2958 |
| 2963 UpdateState(); | 2959 UpdateState(); |
| 2964 } | 2960 } |
| 2965 | 2961 |
| 2966 | 2962 |
| 2967 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { | 2963 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { |
| 2968 message_handler_ = handler; | 2964 message_handler_ = handler; |
| 2969 UpdateState(); | 2965 UpdateState(); |
| 2970 if (handler == NULL && is_entered()) { | 2966 if (handler == NULL && in_debug_scope()) { |
| 2971 // Send an empty command to the debugger if in a break to make JavaScript | 2967 // Send an empty command to the debugger if in a break to make JavaScript |
| 2972 // run again if the debugger is closed. | 2968 // run again if the debugger is closed. |
| 2973 EnqueueCommandMessage(Vector<const uint16_t>::empty()); | 2969 EnqueueCommandMessage(Vector<const uint16_t>::empty()); |
| 2974 } | 2970 } |
| 2975 } | 2971 } |
| 2976 | 2972 |
| 2977 | 2973 |
| 2978 | 2974 |
| 2979 void Debug::UpdateState() { | 2975 void Debug::UpdateState() { |
| 2980 is_active_ = message_handler_ != NULL || !event_listener_.is_null(); | 2976 is_active_ = message_handler_ != NULL || !event_listener_.is_null(); |
| 2981 if (is_active_ || is_entered()) { | 2977 if (is_active_ || in_debug_scope()) { |
| 2982 // Note that the debug context could have already been loaded to | 2978 // Note that the debug context could have already been loaded to |
| 2983 // bootstrap test cases. | 2979 // bootstrap test cases. |
| 2984 isolate_->compilation_cache()->Disable(); | 2980 isolate_->compilation_cache()->Disable(); |
| 2985 is_active_ = Load(); | 2981 is_active_ = Load(); |
| 2986 } else if (is_loaded() && !is_active_) { | 2982 } else if (is_loaded()) { |
| 2987 isolate_->compilation_cache()->Enable(); | 2983 isolate_->compilation_cache()->Enable(); |
| 2988 Unload(); | 2984 Unload(); |
| 2989 } | 2985 } |
| 2990 } | 2986 } |
| 2991 | 2987 |
| 2992 | 2988 |
| 2993 // Calls the registered debug message handler. This callback is part of the | 2989 // Calls the registered debug message handler. This callback is part of the |
| 2994 // public API. | 2990 // public API. |
| 2995 void Debug::InvokeMessageHandler(MessageImpl message) { | 2991 void Debug::InvokeMessageHandler(MessageImpl message) { |
| 2996 if (message_handler_ != NULL) message_handler_(message); | 2992 if (message_handler_ != NULL) message_handler_(message); |
| 2997 } | 2993 } |
| 2998 | 2994 |
| 2999 | 2995 |
| 3000 // Puts a command coming from the public API on the queue. Creates | 2996 // Puts a command coming from the public API on the queue. Creates |
| 3001 // a copy of the command string managed by the debugger. Up to this | 2997 // a copy of the command string managed by the debugger. Up to this |
| 3002 // point, the command data was managed by the API client. Called | 2998 // point, the command data was managed by the API client. Called |
| 3003 // by the API client thread. | 2999 // by the API client thread. |
| 3004 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command, | 3000 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command, |
| 3005 v8::Debug::ClientData* client_data) { | 3001 v8::Debug::ClientData* client_data) { |
| 3006 // Need to cast away const. | 3002 // Need to cast away const. |
| 3007 CommandMessage message = CommandMessage::New( | 3003 CommandMessage message = CommandMessage::New( |
| 3008 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 3004 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), |
| 3009 command.length()), | 3005 command.length()), |
| 3010 client_data); | 3006 client_data); |
| 3011 isolate_->logger()->DebugTag("Put command on command_queue."); | 3007 isolate_->logger()->DebugTag("Put command on command_queue."); |
| 3012 command_queue_.Put(message); | 3008 command_queue_.Put(message); |
| 3013 command_received_.Signal(); | 3009 command_received_.Signal(); |
| 3014 | 3010 |
| 3015 // Set the debug command break flag to have the command processed. | 3011 // Set the debug command break flag to have the command processed. |
| 3016 if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand(); | 3012 if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand(); |
| 3017 } | 3013 } |
| 3018 | 3014 |
| 3019 | 3015 |
| 3020 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { | 3016 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { |
| 3021 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); | 3017 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); |
| 3022 event_command_queue_.Put(message); | 3018 event_command_queue_.Put(message); |
| 3023 | 3019 |
| 3024 // Set the debug command break flag to have the command processed. | 3020 // Set the debug command break flag to have the command processed. |
| 3025 if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand(); | 3021 if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand(); |
| 3026 } | 3022 } |
| 3027 | 3023 |
| 3028 | 3024 |
| 3029 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) { | 3025 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) { |
| 3030 // Enter the debugger. | 3026 DebugScope debug_scope(this); |
| 3031 EnterDebugger debugger(isolate_); | 3027 if (debug_scope.failed()) return isolate_->factory()->undefined_value(); |
| 3032 if (debugger.FailedToEnter()) { | |
| 3033 return isolate_->factory()->undefined_value(); | |
| 3034 } | |
| 3035 | 3028 |
| 3036 // Create the execution state. | 3029 // Create the execution state. |
| 3037 Handle<Object> exec_state; | 3030 Handle<Object> exec_state; |
| 3038 if (!MakeExecutionState().ToHandle(&exec_state)) { | 3031 if (!MakeExecutionState().ToHandle(&exec_state)) { |
| 3039 return isolate_->factory()->undefined_value(); | 3032 return isolate_->factory()->undefined_value(); |
| 3040 } | 3033 } |
| 3041 | 3034 |
| 3042 Handle<Object> argv[] = { exec_state, data }; | 3035 Handle<Object> argv[] = { exec_state, data }; |
| 3043 return Execution::Call( | 3036 return Execution::Call( |
| 3044 isolate_, | 3037 isolate_, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3082 } | 3075 } |
| 3083 | 3076 |
| 3084 | 3077 |
| 3085 void Debug::ProcessDebugMessages(bool debug_command_only) { | 3078 void Debug::ProcessDebugMessages(bool debug_command_only) { |
| 3086 isolate_->stack_guard()->ClearDebugCommand(); | 3079 isolate_->stack_guard()->ClearDebugCommand(); |
| 3087 | 3080 |
| 3088 StackLimitCheck check(isolate_); | 3081 StackLimitCheck check(isolate_); |
| 3089 if (check.HasOverflowed()) return; | 3082 if (check.HasOverflowed()) return; |
| 3090 | 3083 |
| 3091 HandleScope scope(isolate_); | 3084 HandleScope scope(isolate_); |
| 3092 // Enter the debugger. Just continue if we fail to enter the debugger. | 3085 DebugScope debug_scope(this); |
| 3093 EnterDebugger debugger(isolate_); | 3086 if (debug_scope.failed()) return; |
| 3094 if (debugger.FailedToEnter()) return; | |
| 3095 | 3087 |
| 3096 // Notify the debug event listeners. Indicate auto continue if the break was | 3088 // Notify the debug event listeners. Indicate auto continue if the break was |
| 3097 // a debug command break. | 3089 // a debug command break. |
| 3098 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); | 3090 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only); |
| 3099 } | 3091 } |
| 3100 | 3092 |
| 3101 | 3093 |
| 3102 EnterDebugger::EnterDebugger(Isolate* isolate) | 3094 DebugScope::DebugScope(Debug* debug) : debug_(debug), |
| 3103 : isolate_(isolate), | 3095 prev_(debug->debugger_entry()), |
| 3104 prev_(isolate_->debug()->debugger_entry()), | 3096 save_(debug_->isolate_) { |
| 3105 save_(isolate_) { | |
| 3106 Debug* debug = isolate_->debug(); | |
| 3107 | |
| 3108 // Link recursive debugger entry. | 3097 // Link recursive debugger entry. |
| 3109 debug->thread_local_.debugger_entry_ = this; | 3098 debug_->thread_local_.current_debug_scope_ = this; |
| 3110 | 3099 |
| 3111 // Store the previous break id and frame id. | 3100 // Store the previous break id and frame id. |
| 3112 break_id_ = debug->break_id(); | 3101 break_id_ = debug_->break_id(); |
| 3113 break_frame_id_ = debug->break_frame_id(); | 3102 break_frame_id_ = debug_->break_frame_id(); |
| 3114 | 3103 |
| 3115 // Create the new break info. If there is no JavaScript frames there is no | 3104 // Create the new break info. If there is no JavaScript frames there is no |
| 3116 // break frame id. | 3105 // break frame id. |
| 3117 JavaScriptFrameIterator it(isolate_); | 3106 JavaScriptFrameIterator it(isolate()); |
| 3118 bool has_js_frames = !it.done(); | 3107 bool has_js_frames = !it.done(); |
| 3119 debug->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id() | 3108 debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id() |
| 3120 : StackFrame::NO_ID; | 3109 : StackFrame::NO_ID; |
| 3121 debug->SetNextBreakId(); | 3110 debug_->SetNextBreakId(); |
| 3122 | 3111 |
| 3123 debug->UpdateState(); | 3112 debug_->UpdateState(); |
| 3124 // Make sure that debugger is loaded and enter the debugger context. | 3113 // Make sure that debugger is loaded and enter the debugger context. |
| 3125 // The previous context is kept in save_. | 3114 // The previous context is kept in save_. |
| 3126 load_failed_ = !debug->is_loaded(); | 3115 failed_ = !debug_->is_loaded(); |
| 3127 if (!load_failed_) isolate_->set_context(*debug->debug_context()); | 3116 if (!failed_) isolate()->set_context(*debug->debug_context()); |
| 3128 } | 3117 } |
| 3129 | 3118 |
| 3130 | 3119 |
| 3131 EnterDebugger::~EnterDebugger() { | |
| 3132 Debug* debug = isolate_->debug(); | |
| 3133 | 3120 |
| 3134 // Restore to the previous break state. | 3121 DebugScope::~DebugScope() { |
| 3135 debug->thread_local_.break_frame_id_ = break_frame_id_; | 3122 if (!failed_ && prev_ == NULL) { |
| 3136 debug->thread_local_.break_id_ = break_id_; | |
| 3137 | |
| 3138 // Check for leaving the debugger. | |
| 3139 if (!load_failed_ && prev_ == NULL) { | |
| 3140 // Clear mirror cache when leaving the debugger. Skip this if there is a | 3123 // Clear mirror cache when leaving the debugger. Skip this if there is a |
| 3141 // pending exception as clearing the mirror cache calls back into | 3124 // pending exception as clearing the mirror cache calls back into |
| 3142 // JavaScript. This can happen if the v8::Debug::Call is used in which | 3125 // JavaScript. This can happen if the v8::Debug::Call is used in which |
| 3143 // case the exception should end up in the calling code. | 3126 // case the exception should end up in the calling code. |
| 3144 if (!isolate_->has_pending_exception()) debug->ClearMirrorCache(); | 3127 if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache(); |
| 3145 | 3128 |
| 3146 // If there are commands in the queue when leaving the debugger request | 3129 // If there are commands in the queue when leaving the debugger request |
| 3147 // that these commands are processed. | 3130 // that these commands are processed. |
| 3148 if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand(); | 3131 if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand(); |
| 3149 } | 3132 } |
| 3150 | 3133 |
| 3151 // Leaving this debugger entry. | 3134 // Leaving this debugger entry. |
| 3152 debug->thread_local_.debugger_entry_ = prev_; | 3135 debug_->thread_local_.current_debug_scope_ = prev_; |
| 3153 | 3136 |
| 3154 debug->UpdateState(); | 3137 // Restore to the previous break state. |
| 3138 debug_->thread_local_.break_frame_id_ = break_frame_id_; |
| 3139 debug_->thread_local_.break_id_ = break_id_; |
| 3140 |
| 3141 debug_->UpdateState(); |
| 3155 } | 3142 } |
| 3156 | 3143 |
| 3157 | 3144 |
| 3158 MessageImpl MessageImpl::NewEvent(DebugEvent event, | 3145 MessageImpl MessageImpl::NewEvent(DebugEvent event, |
| 3159 bool running, | 3146 bool running, |
| 3160 Handle<JSObject> exec_state, | 3147 Handle<JSObject> exec_state, |
| 3161 Handle<JSObject> event_data) { | 3148 Handle<JSObject> event_data) { |
| 3162 MessageImpl message(true, event, running, | 3149 MessageImpl message(true, event, running, |
| 3163 exec_state, event_data, Handle<String>(), NULL); | 3150 exec_state, event_data, Handle<String>(), NULL); |
| 3164 return message; | 3151 return message; |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3401 logger_->DebugEvent("Put", message.text()); | 3388 logger_->DebugEvent("Put", message.text()); |
| 3402 } | 3389 } |
| 3403 | 3390 |
| 3404 | 3391 |
| 3405 void LockingCommandMessageQueue::Clear() { | 3392 void LockingCommandMessageQueue::Clear() { |
| 3406 LockGuard<Mutex> lock_guard(&mutex_); | 3393 LockGuard<Mutex> lock_guard(&mutex_); |
| 3407 queue_.Clear(); | 3394 queue_.Clear(); |
| 3408 } | 3395 } |
| 3409 | 3396 |
| 3410 } } // namespace v8::internal | 3397 } } // namespace v8::internal |
| OLD | NEW |