| 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 |