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

Side by Side Diff: src/debug.cc

Issue 300553008: Some debugger-related clean-ups and renamings. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 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/debug.h ('k') | src/execution.h » ('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 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 21 matching lines...) Expand all
32 32
33 Debug::Debug(Isolate* isolate) 33 Debug::Debug(Isolate* isolate)
34 : debug_context_(Handle<Context>()), 34 : debug_context_(Handle<Context>()),
35 event_listener_(Handle<Object>()), 35 event_listener_(Handle<Object>()),
36 event_listener_data_(Handle<Object>()), 36 event_listener_data_(Handle<Object>()),
37 message_handler_(NULL), 37 message_handler_(NULL),
38 command_received_(0), 38 command_received_(0),
39 command_queue_(isolate->logger(), kQueueInitialSize), 39 command_queue_(isolate->logger(), kQueueInitialSize),
40 event_command_queue_(isolate->logger(), kQueueInitialSize), 40 event_command_queue_(isolate->logger(), kQueueInitialSize),
41 is_active_(false), 41 is_active_(false),
42 ignore_debugger_(false), 42 is_suppressed_(false),
43 live_edit_enabled_(true), // TODO(yangguo): set to false by default. 43 live_edit_enabled_(true), // TODO(yangguo): set to false by default.
44 has_break_points_(false), 44 has_break_points_(false),
45 disable_break_(false), 45 break_disabled_(false),
46 break_on_exception_(false), 46 break_on_exception_(false),
47 break_on_uncaught_exception_(false), 47 break_on_uncaught_exception_(false),
48 script_cache_(NULL), 48 script_cache_(NULL),
49 debug_info_list_(NULL), 49 debug_info_list_(NULL),
50 isolate_(isolate) { 50 isolate_(isolate) {
51 ThreadInit(); 51 ThreadInit();
52 } 52 }
53 53
54 54
55 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { 55 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 250
251 251
252 bool BreakLocationIterator::Done() const { 252 bool BreakLocationIterator::Done() const {
253 return RinfoDone(); 253 return RinfoDone();
254 } 254 }
255 255
256 256
257 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) { 257 void BreakLocationIterator::SetBreakPoint(Handle<Object> break_point_object) {
258 // If there is not already a real break point here patch code with debug 258 // If there is not already a real break point here patch code with debug
259 // break. 259 // break.
260 if (!HasBreakPoint()) { 260 if (!HasBreakPoint()) SetDebugBreak();
261 SetDebugBreak();
262 }
263 ASSERT(IsDebugBreak() || IsDebuggerStatement()); 261 ASSERT(IsDebugBreak() || IsDebuggerStatement());
264 // Set the break point information. 262 // Set the break point information.
265 DebugInfo::SetBreakPoint(debug_info_, code_position(), 263 DebugInfo::SetBreakPoint(debug_info_, code_position(),
266 position(), statement_position(), 264 position(), statement_position(),
267 break_point_object); 265 break_point_object);
268 } 266 }
269 267
270 268
271 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) { 269 void BreakLocationIterator::ClearBreakPoint(Handle<Object> break_point_object) {
272 // Clear the break point information. 270 // Clear the break point information.
273 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object); 271 DebugInfo::ClearBreakPoint(debug_info_, code_position(), break_point_object);
274 // If there are no more break points here remove the debug break. 272 // If there are no more break points here remove the debug break.
275 if (!HasBreakPoint()) { 273 if (!HasBreakPoint()) {
276 ClearDebugBreak(); 274 ClearDebugBreak();
277 ASSERT(!IsDebugBreak()); 275 ASSERT(!IsDebugBreak());
278 } 276 }
279 } 277 }
280 278
281 279
282 void BreakLocationIterator::SetOneShot() { 280 void BreakLocationIterator::SetOneShot() {
283 // Debugger statement always calls debugger. No need to modify it. 281 // Debugger statement always calls debugger. No need to modify it.
284 if (IsDebuggerStatement()) { 282 if (IsDebuggerStatement()) return;
285 return;
286 }
287 283
288 // If there is a real break point here no more to do. 284 // If there is a real break point here no more to do.
289 if (HasBreakPoint()) { 285 if (HasBreakPoint()) {
290 ASSERT(IsDebugBreak()); 286 ASSERT(IsDebugBreak());
291 return; 287 return;
292 } 288 }
293 289
294 // Patch code with debug break. 290 // Patch code with debug break.
295 SetDebugBreak(); 291 SetDebugBreak();
296 } 292 }
297 293
298 294
299 void BreakLocationIterator::ClearOneShot() { 295 void BreakLocationIterator::ClearOneShot() {
300 // Debugger statement always calls debugger. No need to modify it. 296 // Debugger statement always calls debugger. No need to modify it.
301 if (IsDebuggerStatement()) { 297 if (IsDebuggerStatement()) return;
302 return;
303 }
304 298
305 // If there is a real break point here no more to do. 299 // If there is a real break point here no more to do.
306 if (HasBreakPoint()) { 300 if (HasBreakPoint()) {
307 ASSERT(IsDebugBreak()); 301 ASSERT(IsDebugBreak());
308 return; 302 return;
309 } 303 }
310 304
311 // Patch code removing debug break. 305 // Patch code removing debug break.
312 ClearDebugBreak(); 306 ClearDebugBreak();
313 ASSERT(!IsDebugBreak()); 307 ASSERT(!IsDebugBreak());
314 } 308 }
315 309
316 310
317 void BreakLocationIterator::SetDebugBreak() { 311 void BreakLocationIterator::SetDebugBreak() {
318 // Debugger statement always calls debugger. No need to modify it. 312 // Debugger statement always calls debugger. No need to modify it.
319 if (IsDebuggerStatement()) { 313 if (IsDebuggerStatement()) return;
320 return;
321 }
322 314
323 // If there is already a break point here just return. This might happen if 315 // If there is already a break point here just return. This might happen if
324 // the same code is flooded with break points twice. Flooding the same 316 // the same code is flooded with break points twice. Flooding the same
325 // function twice might happen when stepping in a function with an exception 317 // function twice might happen when stepping in a function with an exception
326 // handler as the handler and the function is the same. 318 // handler as the handler and the function is the same.
327 if (IsDebugBreak()) { 319 if (IsDebugBreak()) return;
328 return;
329 }
330 320
331 if (RelocInfo::IsJSReturn(rmode())) { 321 if (RelocInfo::IsJSReturn(rmode())) {
332 // Patch the frame exit code with a break point. 322 // Patch the frame exit code with a break point.
333 SetDebugBreakAtReturn(); 323 SetDebugBreakAtReturn();
334 } else if (IsDebugBreakSlot()) { 324 } else if (IsDebugBreakSlot()) {
335 // Patch the code in the break slot. 325 // Patch the code in the break slot.
336 SetDebugBreakAtSlot(); 326 SetDebugBreakAtSlot();
337 } else { 327 } else {
338 // Patch the IC call. 328 // Patch the IC call.
339 SetDebugBreakAtIC(); 329 SetDebugBreakAtIC();
340 } 330 }
341 ASSERT(IsDebugBreak()); 331 ASSERT(IsDebugBreak());
342 } 332 }
343 333
344 334
345 void BreakLocationIterator::ClearDebugBreak() { 335 void BreakLocationIterator::ClearDebugBreak() {
346 // Debugger statement always calls debugger. No need to modify it. 336 // Debugger statement always calls debugger. No need to modify it.
347 if (IsDebuggerStatement()) { 337 if (IsDebuggerStatement()) return;
348 return;
349 }
350 338
351 if (RelocInfo::IsJSReturn(rmode())) { 339 if (RelocInfo::IsJSReturn(rmode())) {
352 // Restore the frame exit code. 340 // Restore the frame exit code.
353 ClearDebugBreakAtReturn(); 341 ClearDebugBreakAtReturn();
354 } else if (IsDebugBreakSlot()) { 342 } else if (IsDebugBreakSlot()) {
355 // Restore the code in the break slot. 343 // Restore the code in the break slot.
356 ClearDebugBreakAtSlot(); 344 ClearDebugBreakAtSlot();
357 } else { 345 } else {
358 // Patch the IC call. 346 // Patch the IC call.
359 ClearDebugBreakAtIC(); 347 ClearDebugBreakAtIC();
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 709
722 // Mark this script as native and return successfully. 710 // Mark this script as native and return successfully.
723 Handle<Script> script(Script::cast(function->shared()->script())); 711 Handle<Script> script(Script::cast(function->shared()->script()));
724 script->set_type(Smi::FromInt(Script::TYPE_NATIVE)); 712 script->set_type(Smi::FromInt(Script::TYPE_NATIVE));
725 return true; 713 return true;
726 } 714 }
727 715
728 716
729 bool Debug::Load() { 717 bool Debug::Load() {
730 // Return if debugger is already loaded. 718 // Return if debugger is already loaded.
731 if (IsLoaded()) return true; 719 if (is_loaded()) return true;
732 720
733 // Bail out if we're already in the process of compiling the native 721 // Bail out if we're already in the process of compiling the native
734 // JavaScript source code for the debugger. 722 // JavaScript source code for the debugger.
735 if (isolate_->debug()->ignore_debugger()) return false; 723 if (is_suppressed_) return false;
736 Debug::IgnoreScope during_create(isolate_->debug()); 724 SuppressDebug while_loading(this);
737 725
738 // Disable breakpoints and interrupts while compiling and running the 726 // Disable breakpoints and interrupts while compiling and running the
739 // debugger scripts including the context creation code. 727 // debugger scripts including the context creation code.
740 DisableBreak disable(isolate_, true); 728 DisableBreak disable(this, true);
741 PostponeInterruptsScope postpone(isolate_); 729 PostponeInterruptsScope postpone(isolate_);
742 730
743 // Create the debugger context. 731 // Create the debugger context.
744 HandleScope scope(isolate_); 732 HandleScope scope(isolate_);
745 ExtensionConfiguration no_extensions; 733 ExtensionConfiguration no_extensions;
746 Handle<Context> context = 734 Handle<Context> context =
747 isolate_->bootstrapper()->CreateEnvironment( 735 isolate_->bootstrapper()->CreateEnvironment(
748 Handle<Object>::null(), 736 Handle<Object>::null(),
749 v8::Handle<ObjectTemplate>(), 737 v8::Handle<ObjectTemplate>(),
750 &no_extensions); 738 &no_extensions);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 775
788 776
789 void Debug::Unload() { 777 void Debug::Unload() {
790 ClearAllBreakPoints(); 778 ClearAllBreakPoints();
791 ClearStepping(); 779 ClearStepping();
792 780
793 // Match unmatched PromiseHandlePrologue calls. 781 // Match unmatched PromiseHandlePrologue calls.
794 while (thread_local_.promise_on_stack_) PromiseHandleEpilogue(); 782 while (thread_local_.promise_on_stack_) PromiseHandleEpilogue();
795 783
796 // Return debugger is not loaded. 784 // Return debugger is not loaded.
797 if (!IsLoaded()) return; 785 if (!is_loaded()) return;
798 786
799 // Clear the script cache. 787 // Clear the script cache.
800 DestroyScriptCache(); 788 DestroyScriptCache();
801 789
802 // Clear debugger context global handle. 790 // Clear debugger context global handle.
803 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location()); 791 GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
804 debug_context_ = Handle<Context>(); 792 debug_context_ = Handle<Context>();
805 } 793 }
806 794
807 795
808 void Debug::Break(Arguments args, JavaScriptFrame* frame) { 796 void Debug::Break(Arguments args, JavaScriptFrame* frame) {
809 Heap* heap = isolate_->heap(); 797 Heap* heap = isolate_->heap();
810 HandleScope scope(isolate_); 798 HandleScope scope(isolate_);
811 ASSERT(args.length() == 0); 799 ASSERT(args.length() == 0);
812 800
813 if (live_edit_enabled()) { 801 if (live_edit_enabled()) {
814 thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED; 802 thread_local_.frame_drop_mode_ = LiveEdit::FRAMES_UNTOUCHED;
815 } 803 }
816 804
817 // Just continue if breaks are disabled or debugger cannot be loaded. 805 // Just continue if breaks are disabled or debugger cannot be loaded.
818 if (disable_break()) return; 806 if (break_disabled_) return;
819 807
820 // Enter the debugger. 808 // Enter the debugger.
821 EnterDebugger debugger(isolate_); 809 EnterDebugger debugger(isolate_);
822 if (debugger.FailedToEnter()) return; 810 if (debugger.FailedToEnter()) return;
823 811
824 // Postpone interrupt during breakpoint processing. 812 // Postpone interrupt during breakpoint processing.
825 PostponeInterruptsScope postpone(isolate_); 813 PostponeInterruptsScope postpone(isolate_);
826 814
827 // Get the debug info (create it if it does not exist). 815 // Get the debug info (create it if it does not exist).
828 Handle<SharedFunctionInfo> shared = 816 Handle<SharedFunctionInfo> shared =
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 } 1252 }
1265 1253
1266 1254
1267 void Debug::PrepareStep(StepAction step_action, 1255 void Debug::PrepareStep(StepAction step_action,
1268 int step_count, 1256 int step_count,
1269 StackFrame::Id frame_id) { 1257 StackFrame::Id frame_id) {
1270 HandleScope scope(isolate_); 1258 HandleScope scope(isolate_);
1271 1259
1272 PrepareForBreakPoints(); 1260 PrepareForBreakPoints();
1273 1261
1274 ASSERT(Debug::InDebugger()); 1262 ASSERT(is_entered());
1275 1263
1276 // Remember this step action and count. 1264 // Remember this step action and count.
1277 thread_local_.last_step_action_ = step_action; 1265 thread_local_.last_step_action_ = step_action;
1278 if (step_action == StepOut) { 1266 if (step_action == StepOut) {
1279 // For step out target frame will be found on the stack so there is no need 1267 // For step out target frame will be found on the stack so there is no need
1280 // to set step counter for it. It's expected to always be 0 for StepOut. 1268 // to set step counter for it. It's expected to always be 0 for StepOut.
1281 thread_local_.step_count_ = 0; 1269 thread_local_.step_count_ = 0;
1282 } else { 1270 } else {
1283 thread_local_.step_count_ = step_count; 1271 thread_local_.step_count_ = step_count;
1284 } 1272 }
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 } 1628 }
1641 1629
1642 locations->set(count++, position); 1630 locations->set(count++, position);
1643 } 1631 }
1644 } 1632 }
1645 } 1633 }
1646 return locations; 1634 return locations;
1647 } 1635 }
1648 1636
1649 1637
1650 void Debug::NewBreak(StackFrame::Id break_frame_id) {
1651 thread_local_.break_frame_id_ = break_frame_id;
1652 thread_local_.break_id_ = ++thread_local_.break_count_;
1653 }
1654
1655
1656 void Debug::SetBreak(StackFrame::Id break_frame_id, int break_id) {
1657 thread_local_.break_frame_id_ = break_frame_id;
1658 thread_local_.break_id_ = break_id;
1659 }
1660
1661
1662 // Handle stepping into a function. 1638 // Handle stepping into a function.
1663 void Debug::HandleStepIn(Handle<JSFunction> function, 1639 void Debug::HandleStepIn(Handle<JSFunction> function,
1664 Handle<Object> holder, 1640 Handle<Object> holder,
1665 Address fp, 1641 Address fp,
1666 bool is_constructor) { 1642 bool is_constructor) {
1667 Isolate* isolate = function->GetIsolate(); 1643 Isolate* isolate = function->GetIsolate();
1668 // If the frame pointer is not supplied by the caller find it. 1644 // If the frame pointer is not supplied by the caller find it.
1669 if (fp == 0) { 1645 if (fp == 0) {
1670 StackFrameIterator it(isolate); 1646 StackFrameIterator it(isolate);
1671 it.Advance(); 1647 it.Advance();
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 if (mode != LiveEdit::CURRENTLY_SET_MODE) { 2415 if (mode != LiveEdit::CURRENTLY_SET_MODE) {
2440 thread_local_.frame_drop_mode_ = mode; 2416 thread_local_.frame_drop_mode_ = mode;
2441 } 2417 }
2442 thread_local_.break_frame_id_ = new_break_frame_id; 2418 thread_local_.break_frame_id_ = new_break_frame_id;
2443 thread_local_.restarter_frame_function_pointer_ = 2419 thread_local_.restarter_frame_function_pointer_ =
2444 restarter_frame_function_pointer; 2420 restarter_frame_function_pointer;
2445 } 2421 }
2446 2422
2447 2423
2448 bool Debug::IsDebugGlobal(GlobalObject* global) { 2424 bool Debug::IsDebugGlobal(GlobalObject* global) {
2449 return IsLoaded() && global == debug_context()->global_object(); 2425 return is_loaded() && global == debug_context()->global_object();
2450 } 2426 }
2451 2427
2452 2428
2453 void Debug::ClearMirrorCache() { 2429 void Debug::ClearMirrorCache() {
2454 PostponeInterruptsScope postpone(isolate_); 2430 PostponeInterruptsScope postpone(isolate_);
2455 HandleScope scope(isolate_); 2431 HandleScope scope(isolate_);
2456 ASSERT(isolate_->context() == *Debug::debug_context()); 2432 ASSERT(isolate_->context() == *Debug::debug_context());
2457 2433
2458 // Clear the mirror cache. 2434 // Clear the mirror cache.
2459 Handle<String> function_name = isolate_->factory()->InternalizeOneByteString(
2460 STATIC_ASCII_VECTOR("ClearMirrorCache"));
2461 Handle<Object> fun = Object::GetProperty( 2435 Handle<Object> fun = Object::GetProperty(
2462 isolate_->global_object(), function_name).ToHandleChecked(); 2436 isolate_,
2437 isolate_->global_object(),
2438 "ClearMirrorCache").ToHandleChecked();
2463 ASSERT(fun->IsJSFunction()); 2439 ASSERT(fun->IsJSFunction());
2464 Execution::TryCall( 2440 Execution::TryCall(Handle<JSFunction>::cast(fun),
2465 Handle<JSFunction>::cast(fun), 2441 Handle<JSObject>(Debug::debug_context()->global_object()),
2466 Handle<JSObject>(Debug::debug_context()->global_object()), 2442 0,
2467 0, 2443 NULL);
2468 NULL);
2469 } 2444 }
2470 2445
2471 2446
2472 void Debug::CreateScriptCache() { 2447 void Debug::CreateScriptCache() {
2473 Heap* heap = isolate_->heap(); 2448 Heap* heap = isolate_->heap();
2474 HandleScope scope(isolate_); 2449 HandleScope scope(isolate_);
2475 2450
2476 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets 2451 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
2477 // rid of all the cached script wrappers and the second gets rid of the 2452 // rid of all the cached script wrappers and the second gets rid of the
2478 // scripts which are no longer referenced. The second also sweeps precisely, 2453 // scripts which are no longer referenced. The second also sweeps precisely,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 2525
2551 2526
2552 void Debug::AfterGarbageCollection() { 2527 void Debug::AfterGarbageCollection() {
2553 // Generate events for collected scripts. 2528 // Generate events for collected scripts.
2554 if (script_cache_ != NULL) { 2529 if (script_cache_ != NULL) {
2555 script_cache_->ProcessCollectedScripts(); 2530 script_cache_->ProcessCollectedScripts();
2556 } 2531 }
2557 } 2532 }
2558 2533
2559 2534
2560 MaybeHandle<Object> Debug::MakeJSObject( 2535 MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
2561 Vector<const char> constructor_name, 2536 int argc,
2562 int argc, 2537 Handle<Object> argv[]) {
2563 Handle<Object> argv[]) { 2538 ASSERT(isolate_->context() == *debug_context());
2564 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
2565
2566 // Create the execution state object. 2539 // Create the execution state object.
2567 Handle<String> constructor_str =
2568 isolate_->factory()->InternalizeUtf8String(constructor_name);
2569 ASSERT(!constructor_str.is_null());
2570 Handle<Object> constructor = Object::GetProperty( 2540 Handle<Object> constructor = Object::GetProperty(
2571 isolate_->global_object(), constructor_str).ToHandleChecked(); 2541 isolate_, isolate_->global_object(), constructor_name).ToHandleChecked();
2572 ASSERT(constructor->IsJSFunction()); 2542 ASSERT(constructor->IsJSFunction());
2573 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); 2543 if (!constructor->IsJSFunction()) return MaybeHandle<Object>();
2574 return Execution::TryCall( 2544 return Execution::TryCall(Handle<JSFunction>::cast(constructor),
2575 Handle<JSFunction>::cast(constructor), 2545 Handle<JSObject>(debug_context()->global_object()),
2576 Handle<JSObject>(isolate_->debug()->debug_context()->global_object()), 2546 argc,
2577 argc, 2547 argv);
2578 argv);
2579 } 2548 }
2580 2549
2581 2550
2582 MaybeHandle<Object> Debug::MakeExecutionState() { 2551 MaybeHandle<Object> Debug::MakeExecutionState() {
2583 // Create the execution state object. 2552 // Create the execution state object.
2584 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( 2553 Handle<Object> argv[] = { isolate_->factory()->NewNumberFromInt(break_id()) };
2585 isolate_->debug()->break_id()); 2554 return MakeJSObject("MakeExecutionState", ARRAY_SIZE(argv), argv);
2586 Handle<Object> argv[] = { break_id };
2587 return MakeJSObject(CStrVector("MakeExecutionState"), ARRAY_SIZE(argv), argv);
2588 } 2555 }
2589 2556
2590 2557
2591 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) { 2558 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) {
2592 Handle<Object> exec_state; 2559 Handle<Object> exec_state;
2593 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2560 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2594 // Create the new break event object. 2561 // Create the new break event object.
2595 Handle<Object> argv[] = { exec_state, break_points_hit }; 2562 Handle<Object> argv[] = { exec_state, break_points_hit };
2596 return MakeJSObject(CStrVector("MakeBreakEvent"), ARRAY_SIZE(argv), argv); 2563 return MakeJSObject("MakeBreakEvent", ARRAY_SIZE(argv), argv);
2597 } 2564 }
2598 2565
2599 2566
2600 MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception, 2567 MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception,
2601 bool uncaught, 2568 bool uncaught,
2602 Handle<Object> promise) { 2569 Handle<Object> promise) {
2603 Handle<Object> exec_state; 2570 Handle<Object> exec_state;
2604 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2571 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2605 // Create the new exception event object. 2572 // Create the new exception event object.
2606 Handle<Object> argv[] = { exec_state, 2573 Handle<Object> argv[] = { exec_state,
2607 exception, 2574 exception,
2608 isolate_->factory()->ToBoolean(uncaught), 2575 isolate_->factory()->ToBoolean(uncaught),
2609 promise }; 2576 promise };
2610 return MakeJSObject(CStrVector("MakeExceptionEvent"), ARRAY_SIZE(argv), argv); 2577 return MakeJSObject("MakeExceptionEvent", ARRAY_SIZE(argv), argv);
2611 } 2578 }
2612 2579
2613 2580
2614 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script, 2581 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
2615 bool before) { 2582 bool before) {
2616 Handle<Object> exec_state; 2583 Handle<Object> exec_state;
2617 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2584 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2618 // Create the compile event object. 2585 // Create the compile event object.
2619 Handle<Object> script_wrapper = Script::GetWrapper(script); 2586 Handle<Object> script_wrapper = Script::GetWrapper(script);
2620 Handle<Object> argv[] = { exec_state, 2587 Handle<Object> argv[] = { exec_state,
2621 script_wrapper, 2588 script_wrapper,
2622 isolate_->factory()->ToBoolean(before) }; 2589 isolate_->factory()->ToBoolean(before) };
2623 return MakeJSObject(CStrVector("MakeCompileEvent"), ARRAY_SIZE(argv), argv); 2590 return MakeJSObject("MakeCompileEvent", ARRAY_SIZE(argv), argv);
2624 } 2591 }
2625 2592
2626 2593
2627 MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) { 2594 MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) {
2628 Handle<Object> exec_state; 2595 Handle<Object> exec_state;
2629 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2596 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2630 // Create the script collected event object. 2597 // Create the script collected event object.
2631 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2598 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2632 Handle<Object> argv[] = { exec_state, id_object }; 2599 Handle<Object> argv[] = { exec_state, id_object };
2633 2600 return MakeJSObject("MakeScriptCollectedEvent", ARRAY_SIZE(argv), argv);
2634 return MakeJSObject(
2635 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv);
2636 } 2601 }
2637 2602
2638 2603
2639 void Debug::OnException(Handle<Object> exception, bool uncaught) { 2604 void Debug::OnException(Handle<Object> exception, bool uncaught) {
2640 HandleScope scope(isolate_); 2605 HandleScope scope(isolate_);
2641 Debug* debug = isolate_->debug();
2642 2606
2643 // Bail out based on state or if there is no listener for this event 2607 // Bail out based on state or if there is no listener for this event
2644 if (debug->InDebugger()) return; 2608 if (is_entered()) return;
2645 if (!EventActive()) return; 2609 if (!EventActive()) return;
2646 2610
2647 Handle<Object> promise = debug->GetPromiseForUncaughtException(); 2611 Handle<Object> promise = GetPromiseForUncaughtException();
2648 uncaught |= !promise->IsUndefined(); 2612 uncaught |= !promise->IsUndefined();
2649 2613
2650 // Bail out if exception breaks are not active 2614 // Bail out if exception breaks are not active
2651 if (uncaught) { 2615 if (uncaught) {
2652 // Uncaught exceptions are reported by either flags. 2616 // Uncaught exceptions are reported by either flags.
2653 if (!(debug->break_on_uncaught_exception() || 2617 if (!(break_on_uncaught_exception() || break_on_exception())) return;
2654 debug->break_on_exception())) return;
2655 } else { 2618 } else {
2656 // Caught exceptions are reported is activated. 2619 // Caught exceptions are reported is activated.
2657 if (!debug->break_on_exception()) return; 2620 if (!break_on_exception()) return;
2658 } 2621 }
2659 2622
2660 // Enter the debugger. 2623 // Enter the debugger.
2661 EnterDebugger debugger(isolate_); 2624 EnterDebugger debugger(isolate_);
2662 if (debugger.FailedToEnter()) return; 2625 if (debugger.FailedToEnter()) return;
2663 2626
2664 // Clear all current stepping setup. 2627 // Clear all current stepping setup.
2665 debug->ClearStepping(); 2628 ClearStepping();
2666 2629
2667 // Create the event data object. 2630 // Create the event data object.
2668 Handle<Object> event_data; 2631 Handle<Object> event_data;
2669 // Bail out and don't call debugger if exception. 2632 // Bail out and don't call debugger if exception.
2670 if (!MakeExceptionEvent( 2633 if (!MakeExceptionEvent(
2671 exception, uncaught, promise).ToHandle(&event_data)) { 2634 exception, uncaught, promise).ToHandle(&event_data)) {
2672 return; 2635 return;
2673 } 2636 }
2674 2637
2675 // Process debug event. 2638 // Process debug event.
(...skipping 21 matching lines...) Expand all
2697 ProcessDebugEvent(v8::Break, 2660 ProcessDebugEvent(v8::Break,
2698 Handle<JSObject>::cast(event_data), 2661 Handle<JSObject>::cast(event_data),
2699 auto_continue); 2662 auto_continue);
2700 } 2663 }
2701 2664
2702 2665
2703 void Debug::OnBeforeCompile(Handle<Script> script) { 2666 void Debug::OnBeforeCompile(Handle<Script> script) {
2704 HandleScope scope(isolate_); 2667 HandleScope scope(isolate_);
2705 2668
2706 // Bail out based on state or if there is no listener for this event 2669 // Bail out based on state or if there is no listener for this event
2707 if (InDebugger()) return; 2670 if (is_entered()) return;
2708 if (!EventActive()) return; 2671 if (!EventActive()) return;
2709 2672
2710 // Enter the debugger. 2673 // Enter the debugger.
2711 EnterDebugger debugger(isolate_); 2674 EnterDebugger debugger(isolate_);
2712 if (debugger.FailedToEnter()) return; 2675 if (debugger.FailedToEnter()) return;
2713 2676
2714 // Create the event data object. 2677 // Create the event data object.
2715 Handle<Object> event_data; 2678 Handle<Object> event_data;
2716 // Bail out and don't call debugger if exception. 2679 // Bail out and don't call debugger if exception.
2717 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; 2680 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return;
(...skipping 10 matching lines...) Expand all
2728 AfterCompileFlags after_compile_flags) { 2691 AfterCompileFlags after_compile_flags) {
2729 HandleScope scope(isolate_); 2692 HandleScope scope(isolate_);
2730 2693
2731 // Add the newly compiled script to the script cache. 2694 // Add the newly compiled script to the script cache.
2732 AddScriptToScriptCache(script); 2695 AddScriptToScriptCache(script);
2733 2696
2734 // No more to do if not debugging. 2697 // No more to do if not debugging.
2735 if (!EventActive()) return; 2698 if (!EventActive()) return;
2736 2699
2737 // Store whether in debugger before entering debugger. 2700 // Store whether in debugger before entering debugger.
2738 bool in_debugger = InDebugger(); 2701 bool in_debugger = is_entered();
2739 2702
2740 // Enter the debugger. 2703 // Enter the debugger.
2741 EnterDebugger debugger(isolate_); 2704 EnterDebugger debugger(isolate_);
2742 if (debugger.FailedToEnter()) return; 2705 if (debugger.FailedToEnter()) return;
2743 2706
2744 // If debugging there might be script break points registered for this 2707 // If debugging there might be script break points registered for this
2745 // script. Make sure that these break points are set. 2708 // script. Make sure that these break points are set.
2746 2709
2747 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). 2710 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js).
2748 Handle<String> update_script_break_points_string = 2711 Handle<String> update_script_break_points_string =
(...skipping 30 matching lines...) Expand all
2779 2742
2780 // Process debug event. 2743 // Process debug event.
2781 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); 2744 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true);
2782 } 2745 }
2783 2746
2784 2747
2785 void Debug::OnScriptCollected(int id) { 2748 void Debug::OnScriptCollected(int id) {
2786 HandleScope scope(isolate_); 2749 HandleScope scope(isolate_);
2787 2750
2788 // No more to do if not debugging. 2751 // No more to do if not debugging.
2789 if (InDebugger()) return; 2752 if (is_entered()) return;
2790 if (!EventActive()) return; 2753 if (!EventActive()) return;
2791 2754
2792 // Enter the debugger. 2755 // Enter the debugger.
2793 EnterDebugger debugger(isolate_); 2756 EnterDebugger debugger(isolate_);
2794 if (debugger.FailedToEnter()) return; 2757 if (debugger.FailedToEnter()) return;
2795 2758
2796 // Create the script collected state object. 2759 // Create the script collected state object.
2797 Handle<Object> event_data; 2760 Handle<Object> event_data;
2798 // Bail out and don't call debugger if exception. 2761 // Bail out and don't call debugger if exception.
2799 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; 2762 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return;
2800 2763
2801 // Process debug event. 2764 // Process debug event.
2802 ProcessDebugEvent(v8::ScriptCollected, 2765 ProcessDebugEvent(v8::ScriptCollected,
2803 Handle<JSObject>::cast(event_data), 2766 Handle<JSObject>::cast(event_data),
2804 true); 2767 true);
2805 } 2768 }
2806 2769
2807 2770
2808 void Debug::ProcessDebugEvent(v8::DebugEvent event, 2771 void Debug::ProcessDebugEvent(v8::DebugEvent event,
2809 Handle<JSObject> event_data, 2772 Handle<JSObject> event_data,
2810 bool auto_continue) { 2773 bool auto_continue) {
2811 HandleScope scope(isolate_); 2774 HandleScope scope(isolate_);
2812 2775
2813 // Clear any pending debug break if this is a real break. 2776 // Clear any pending debug break if this is a real break.
2814 if (!auto_continue) set_has_pending_interrupt(false); 2777 if (!auto_continue) thread_local_.has_pending_interrupt_ = false;
2815 2778
2816 // Create the execution state. 2779 // Create the execution state.
2817 Handle<Object> exec_state; 2780 Handle<Object> exec_state;
2818 // Bail out and don't call debugger if exception. 2781 // Bail out and don't call debugger if exception.
2819 if (!MakeExecutionState().ToHandle(&exec_state)) return; 2782 if (!MakeExecutionState().ToHandle(&exec_state)) return;
2820 2783
2821 // First notify the message handler if any. 2784 // First notify the message handler if any.
2822 if (message_handler_ != NULL) { 2785 if (message_handler_ != NULL) {
2823 NotifyMessageHandler(event, 2786 NotifyMessageHandler(event,
2824 Handle<JSObject>::cast(exec_state), 2787 Handle<JSObject>::cast(exec_state),
(...skipping 20 matching lines...) Expand all
2845 } 2808 }
2846 } 2809 }
2847 } 2810 }
2848 2811
2849 2812
2850 void Debug::CallEventCallback(v8::DebugEvent event, 2813 void Debug::CallEventCallback(v8::DebugEvent event,
2851 Handle<Object> exec_state, 2814 Handle<Object> exec_state,
2852 Handle<Object> event_data, 2815 Handle<Object> event_data,
2853 v8::Debug::ClientData* client_data) { 2816 v8::Debug::ClientData* client_data) {
2854 if (event_listener_->IsForeign()) { 2817 if (event_listener_->IsForeign()) {
2855 CallCEventCallback(event, exec_state, event_data, client_data); 2818 // Invoke the C debug event listener.
2819 v8::Debug::EventCallback2 callback =
2820 FUNCTION_CAST<v8::Debug::EventCallback2>(
2821 Handle<Foreign>::cast(event_listener_)->foreign_address());
2822 EventDetailsImpl event_details(event,
2823 Handle<JSObject>::cast(exec_state),
2824 Handle<JSObject>::cast(event_data),
2825 event_listener_data_,
2826 client_data);
2827 callback(event_details);
2828 ASSERT(!isolate_->has_scheduled_exception());
2856 } else { 2829 } else {
2857 CallJSEventCallback(event, exec_state, event_data); 2830 // Invoke the JavaScript debug event listener.
2831 ASSERT(event_listener_->IsJSFunction());
2832 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
2833 exec_state,
2834 event_data,
2835 event_listener_data_ };
2836 Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
2837 isolate_->global_object(),
2838 ARRAY_SIZE(argv),
2839 argv);
2858 } 2840 }
2859 } 2841 }
2860 2842
2861 2843
2862 void Debug::CallCEventCallback(v8::DebugEvent event,
2863 Handle<Object> exec_state,
2864 Handle<Object> event_data,
2865 v8::Debug::ClientData* client_data) {
2866 Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_));
2867 v8::Debug::EventCallback2 callback =
2868 FUNCTION_CAST<v8::Debug::EventCallback2>(
2869 callback_obj->foreign_address());
2870 EventDetailsImpl event_details(
2871 event,
2872 Handle<JSObject>::cast(exec_state),
2873 Handle<JSObject>::cast(event_data),
2874 event_listener_data_,
2875 client_data);
2876 callback(event_details);
2877 }
2878
2879
2880 void Debug::CallJSEventCallback(v8::DebugEvent event,
2881 Handle<Object> exec_state,
2882 Handle<Object> event_data) {
2883 ASSERT(event_listener_->IsJSFunction());
2884 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
2885
2886 // Invoke the JavaScript debug event listener.
2887 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_),
2888 exec_state,
2889 event_data,
2890 event_listener_data_ };
2891 Execution::TryCall(fun,
2892 isolate_->global_object(),
2893 ARRAY_SIZE(argv),
2894 argv);
2895 // Silently ignore exceptions from debug event listeners.
2896 }
2897
2898
2899 Handle<Context> Debug::GetDebugContext() { 2844 Handle<Context> Debug::GetDebugContext() {
2900 EnterDebugger debugger(isolate_); 2845 EnterDebugger debugger(isolate_);
2901 // The global handle may be destroyed soon after. Return it reboxed. 2846 // The global handle may be destroyed soon after. Return it reboxed.
2902 return handle(*debug_context(), isolate_); 2847 return handle(*debug_context(), isolate_);
2903 } 2848 }
2904 2849
2905 2850
2906 void Debug::NotifyMessageHandler(v8::DebugEvent event, 2851 void Debug::NotifyMessageHandler(v8::DebugEvent event,
2907 Handle<JSObject> exec_state, 2852 Handle<JSObject> exec_state,
2908 Handle<JSObject> event_data, 2853 Handle<JSObject> event_data,
(...skipping 20 matching lines...) Expand all
2929 break; 2874 break;
2930 case v8::NewFunction: 2875 case v8::NewFunction:
2931 break; 2876 break;
2932 default: 2877 default:
2933 UNREACHABLE(); 2878 UNREACHABLE();
2934 } 2879 }
2935 2880
2936 // The debug command interrupt flag might have been set when the command was 2881 // The debug command interrupt flag might have been set when the command was
2937 // added. It should be enough to clear the flag only once while we are in the 2882 // added. It should be enough to clear the flag only once while we are in the
2938 // debugger. 2883 // debugger.
2939 ASSERT(InDebugger()); 2884 ASSERT(is_entered());
2940 isolate_->stack_guard()->ClearDebugCommand(); 2885 isolate_->stack_guard()->ClearDebugCommand();
2941 2886
2942 // Notify the debugger that a debug event has occurred unless auto continue is 2887 // Notify the debugger that a debug event has occurred unless auto continue is
2943 // active in which case no event is send. 2888 // active in which case no event is send.
2944 if (sendEventMessage) { 2889 if (sendEventMessage) {
2945 MessageImpl message = MessageImpl::NewEvent( 2890 MessageImpl message = MessageImpl::NewEvent(
2946 event, 2891 event,
2947 auto_continue, 2892 auto_continue,
2948 Handle<JSObject>::cast(exec_state), 2893 Handle<JSObject>::cast(exec_state),
2949 Handle<JSObject>::cast(event_data)); 2894 Handle<JSObject>::cast(event_data));
2950 InvokeMessageHandler(message); 2895 InvokeMessageHandler(message);
2951 } 2896 }
2952 2897
2953 // If auto continue don't make the event cause a break, but process messages 2898 // If auto continue don't make the event cause a break, but process messages
2954 // in the queue if any. For script collected events don't even process 2899 // in the queue if any. For script collected events don't even process
2955 // messages in the queue as the execution state might not be what is expected 2900 // messages in the queue as the execution state might not be what is expected
2956 // by the client. 2901 // by the client.
2957 if ((auto_continue && !HasCommands()) || event == v8::ScriptCollected) { 2902 if ((auto_continue && !has_commands()) || event == v8::ScriptCollected) {
2958 return; 2903 return;
2959 } 2904 }
2960 2905
2961 // DebugCommandProcessor goes here. 2906 // DebugCommandProcessor goes here.
2962 bool running = auto_continue; 2907 bool running = auto_continue;
2963 2908
2964 Handle<Object> cmd_processor_ctor = Object::GetProperty( 2909 Handle<Object> cmd_processor_ctor = Object::GetProperty(
2965 isolate_, exec_state, "debugCommandProcessor").ToHandleChecked(); 2910 isolate_, exec_state, "debugCommandProcessor").ToHandleChecked();
2966 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) }; 2911 Handle<Object> ctor_args[] = { isolate_->factory()->ToBoolean(running) };
2967 Handle<Object> cmd_processor = Execution::Call( 2912 Handle<Object> cmd_processor = Execution::Call(
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 2968
3024 // Return the result. 2969 // Return the result.
3025 MessageImpl message = MessageImpl::NewResponse( 2970 MessageImpl message = MessageImpl::NewResponse(
3026 event, running, exec_state, event_data, answer, command.client_data()); 2971 event, running, exec_state, event_data, answer, command.client_data());
3027 InvokeMessageHandler(message); 2972 InvokeMessageHandler(message);
3028 command.Dispose(); 2973 command.Dispose();
3029 2974
3030 // Return from debug event processing if either the VM is put into the 2975 // Return from debug event processing if either the VM is put into the
3031 // running state (through a continue command) or auto continue is active 2976 // running state (through a continue command) or auto continue is active
3032 // and there are no more commands queued. 2977 // and there are no more commands queued.
3033 } while (!running || HasCommands()); 2978 } while (!running || has_commands());
3034 } 2979 }
3035 2980
3036 2981
3037 void Debug::SetEventListener(Handle<Object> callback, 2982 void Debug::SetEventListener(Handle<Object> callback,
3038 Handle<Object> data) { 2983 Handle<Object> data) {
3039 GlobalHandles* global_handles = isolate_->global_handles(); 2984 GlobalHandles* global_handles = isolate_->global_handles();
3040 2985
3041 // Remove existing entry. 2986 // Remove existing entry.
3042 GlobalHandles::Destroy(event_listener_.location()); 2987 GlobalHandles::Destroy(event_listener_.location());
3043 event_listener_ = Handle<Object>(); 2988 event_listener_ = Handle<Object>();
3044 GlobalHandles::Destroy(event_listener_data_.location()); 2989 GlobalHandles::Destroy(event_listener_data_.location());
3045 event_listener_data_ = Handle<Object>(); 2990 event_listener_data_ = Handle<Object>();
3046 2991
3047 // Set new entry. 2992 // Set new entry.
3048 if (!callback->IsUndefined() && !callback->IsNull()) { 2993 if (!callback->IsUndefined() && !callback->IsNull()) {
3049 event_listener_ = global_handles->Create(*callback); 2994 event_listener_ = global_handles->Create(*callback);
3050 if (data.is_null()) data = isolate_->factory()->undefined_value(); 2995 if (data.is_null()) data = isolate_->factory()->undefined_value();
3051 event_listener_data_ = global_handles->Create(*data); 2996 event_listener_data_ = global_handles->Create(*data);
3052 } 2997 }
3053 2998
3054 UpdateState(); 2999 UpdateState();
3055 } 3000 }
3056 3001
3057 3002
3058 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { 3003 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
3059 message_handler_ = handler; 3004 message_handler_ = handler;
3060 UpdateState(); 3005 UpdateState();
3061 if (handler == NULL && InDebugger()) { 3006 if (handler == NULL && is_entered()) {
3062 // Send an empty command to the debugger if in a break to make JavaScript 3007 // Send an empty command to the debugger if in a break to make JavaScript
3063 // run again if the debugger is closed. 3008 // run again if the debugger is closed.
3064 EnqueueCommandMessage(Vector<const uint16_t>::empty()); 3009 EnqueueCommandMessage(Vector<const uint16_t>::empty());
3065 } 3010 }
3066 } 3011 }
3067 3012
3068 3013
3069 3014
3070 void Debug::UpdateState() { 3015 void Debug::UpdateState() {
3071 bool activate = message_handler_ != NULL || 3016 bool activate = message_handler_ != NULL ||
3072 !event_listener_.is_null() || 3017 !event_listener_.is_null() ||
3073 InDebugger(); 3018 is_entered();
3074 if (!is_active_ && activate) { 3019 if (!is_active_ && activate) {
3075 // Note that the debug context could have already been loaded to 3020 // Note that the debug context could have already been loaded to
3076 // bootstrap test cases. 3021 // bootstrap test cases.
3077 isolate_->compilation_cache()->Disable(); 3022 isolate_->compilation_cache()->Disable();
3078 activate = Load(); 3023 activate = Load();
3079 } else if (IsLoaded() && !activate) { 3024 } else if (is_loaded() && !activate) {
3080 isolate_->compilation_cache()->Enable(); 3025 isolate_->compilation_cache()->Enable();
3081 Unload(); 3026 Unload();
3082 } 3027 }
3083 is_active_ = activate; 3028 is_active_ = activate;
3084 // At this point the debug context is loaded iff the debugger is active. 3029 // At this point the debug context is loaded iff the debugger is active.
3085 ASSERT(IsLoaded() == is_active_); 3030 ASSERT(is_loaded() == is_active());
3086 } 3031 }
3087 3032
3088 3033
3089 // Calls the registered debug message handler. This callback is part of the 3034 // Calls the registered debug message handler. This callback is part of the
3090 // public API. 3035 // public API.
3091 void Debug::InvokeMessageHandler(MessageImpl message) { 3036 void Debug::InvokeMessageHandler(MessageImpl message) {
3092 if (message_handler_ != NULL) message_handler_(message); 3037 if (message_handler_ != NULL) message_handler_(message);
3093 } 3038 }
3094 3039
3095 3040
3096 // Puts a command coming from the public API on the queue. Creates 3041 // Puts a command coming from the public API on the queue. Creates
3097 // a copy of the command string managed by the debugger. Up to this 3042 // a copy of the command string managed by the debugger. Up to this
3098 // point, the command data was managed by the API client. Called 3043 // point, the command data was managed by the API client. Called
3099 // by the API client thread. 3044 // by the API client thread.
3100 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command, 3045 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command,
3101 v8::Debug::ClientData* client_data) { 3046 v8::Debug::ClientData* client_data) {
3102 // Need to cast away const. 3047 // Need to cast away const.
3103 CommandMessage message = CommandMessage::New( 3048 CommandMessage message = CommandMessage::New(
3104 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), 3049 Vector<uint16_t>(const_cast<uint16_t*>(command.start()),
3105 command.length()), 3050 command.length()),
3106 client_data); 3051 client_data);
3107 isolate_->logger()->DebugTag("Put command on command_queue."); 3052 isolate_->logger()->DebugTag("Put command on command_queue.");
3108 command_queue_.Put(message); 3053 command_queue_.Put(message);
3109 command_received_.Signal(); 3054 command_received_.Signal();
3110 3055
3111 // Set the debug command break flag to have the command processed. 3056 // Set the debug command break flag to have the command processed.
3112 if (!isolate_->debug()->InDebugger()) { 3057 if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand();
3113 isolate_->stack_guard()->RequestDebugCommand();
3114 }
3115 } 3058 }
3116 3059
3117 3060
3118 bool Debug::HasCommands() {
3119 return !command_queue_.IsEmpty();
3120 }
3121
3122
3123 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { 3061 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) {
3124 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); 3062 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data);
3125 event_command_queue_.Put(message); 3063 event_command_queue_.Put(message);
3126 3064
3127 // Set the debug command break flag to have the command processed. 3065 // Set the debug command break flag to have the command processed.
3128 if (!InDebugger()) isolate_->stack_guard()->RequestDebugCommand(); 3066 if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand();
3129 } 3067 }
3130 3068
3131 3069
3132 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) { 3070 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
3133 // Enter the debugger. 3071 // Enter the debugger.
3134 EnterDebugger debugger(isolate_); 3072 EnterDebugger debugger(isolate_);
3135 if (debugger.FailedToEnter()) { 3073 if (debugger.FailedToEnter()) {
3136 return isolate_->factory()->undefined_value(); 3074 return isolate_->factory()->undefined_value();
3137 } 3075 }
3138 3076
3139 // Create the execution state. 3077 // Create the execution state.
3140 Handle<Object> exec_state; 3078 Handle<Object> exec_state;
3141 if (!MakeExecutionState().ToHandle(&exec_state)) { 3079 if (!MakeExecutionState().ToHandle(&exec_state)) {
3142 return isolate_->factory()->undefined_value(); 3080 return isolate_->factory()->undefined_value();
3143 } 3081 }
3144 3082
3145 Handle<Object> argv[] = { exec_state, data }; 3083 Handle<Object> argv[] = { exec_state, data };
3146 return Execution::Call( 3084 return Execution::Call(
3147 isolate_, 3085 isolate_,
3148 fun, 3086 fun,
3149 Handle<Object>(debug_context()->global_proxy(), isolate_), 3087 Handle<Object>(debug_context()->global_proxy(), isolate_),
3150 ARRAY_SIZE(argv), 3088 ARRAY_SIZE(argv),
3151 argv); 3089 argv);
3152 } 3090 }
3153 3091
3154 3092
3093 void Debug::DebugBreakHelper() {
3094 // Ignore debug break during bootstrapping.
3095 if (isolate_->bootstrapper()->IsActive()) return;
3096 // Just continue if breaks are disabled.
3097 if (break_disabled_) return;
3098 // Ignore debug break if debugger is not active.
3099 if (!is_active()) return;
3100
3101 StackLimitCheck check(isolate_);
3102 if (check.HasOverflowed()) return;
3103
3104 { JavaScriptFrameIterator it(isolate_);
3105 ASSERT(!it.done());
3106 Object* fun = it.frame()->function();
3107 if (fun && fun->IsJSFunction()) {
3108 // Don't stop in builtin functions.
3109 if (JSFunction::cast(fun)->IsBuiltin()) return;
3110 GlobalObject* global = JSFunction::cast(fun)->context()->global_object();
3111 // Don't stop in debugger functions.
3112 if (IsDebugGlobal(global)) return;
3113 }
3114 }
3115
3116 // Collect the break state before clearing the flags.
3117 bool debug_command_only = isolate_->stack_guard()->CheckDebugCommand() &&
3118 !isolate_->stack_guard()->CheckDebugBreak();
3119
3120 isolate_->stack_guard()->ClearDebugBreak();
3121
3122 ProcessDebugMessages(debug_command_only);
3123 }
3124
3125
3126 void Debug::ProcessDebugMessages(bool debug_command_only) {
3127 isolate_->stack_guard()->ClearDebugCommand();
3128
3129 StackLimitCheck check(isolate_);
3130 if (check.HasOverflowed()) return;
3131
3132 HandleScope scope(isolate_);
3133 // Enter the debugger. Just continue if we fail to enter the debugger.
3134 EnterDebugger debugger(isolate_);
3135 if (debugger.FailedToEnter()) return;
3136
3137 // Notify the debug event listeners. Indicate auto continue if the break was
3138 // a debug command break.
3139 OnDebugBreak(isolate_->factory()->undefined_value(), debug_command_only);
3140 }
3141
3142
3155 EnterDebugger::EnterDebugger(Isolate* isolate) 3143 EnterDebugger::EnterDebugger(Isolate* isolate)
3156 : isolate_(isolate), 3144 : isolate_(isolate),
3157 prev_(isolate_->debug()->debugger_entry()), 3145 prev_(isolate_->debug()->debugger_entry()),
3158 save_(isolate_) { 3146 save_(isolate_) {
3159 Debug* debug = isolate_->debug(); 3147 Debug* debug = isolate_->debug();
3160 3148
3161 // Link recursive debugger entry. 3149 // Link recursive debugger entry.
3162 debug->set_debugger_entry(this); 3150 debug->thread_local_.debugger_entry_ = this;
3163 3151
3164 // Store the previous break id and frame id. 3152 // Store the previous break id and frame id.
3165 break_id_ = debug->break_id(); 3153 break_id_ = debug->break_id();
3166 break_frame_id_ = debug->break_frame_id(); 3154 break_frame_id_ = debug->break_frame_id();
3167 3155
3168 // Create the new break info. If there is no JavaScript frames there is no 3156 // Create the new break info. If there is no JavaScript frames there is no
3169 // break frame id. 3157 // break frame id.
3170 JavaScriptFrameIterator it(isolate_); 3158 JavaScriptFrameIterator it(isolate_);
3171 has_js_frames_ = !it.done(); 3159 has_js_frames_ = !it.done();
3172 debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID); 3160 debug->thread_local_.break_frame_id_ = has_js_frames_ ? it.frame()->id()
3161 : StackFrame::NO_ID;
3162 debug->SetNextBreakId();
3173 3163
3174 debug->UpdateState(); 3164 debug->UpdateState();
3175 // Make sure that debugger is loaded and enter the debugger context. 3165 // Make sure that debugger is loaded and enter the debugger context.
3176 // The previous context is kept in save_. 3166 // The previous context is kept in save_.
3177 load_failed_ = !debug->IsLoaded(); 3167 load_failed_ = !debug->is_loaded();
3178 if (!load_failed_) isolate_->set_context(*debug->debug_context()); 3168 if (!load_failed_) isolate_->set_context(*debug->debug_context());
3179 } 3169 }
3180 3170
3181 3171
3182 EnterDebugger::~EnterDebugger() { 3172 EnterDebugger::~EnterDebugger() {
3183 Debug* debug = isolate_->debug(); 3173 Debug* debug = isolate_->debug();
3184 3174
3185 // Restore to the previous break state. 3175 // Restore to the previous break state.
3186 debug->SetBreak(break_frame_id_, break_id_); 3176 debug->thread_local_.break_frame_id_ = break_frame_id_;
3177 debug->thread_local_.break_id_ = break_id_;
3187 3178
3188 // Check for leaving the debugger. 3179 // Check for leaving the debugger.
3189 if (!load_failed_ && prev_ == NULL) { 3180 if (!load_failed_ && prev_ == NULL) {
3190 // Clear mirror cache when leaving the debugger. Skip this if there is a 3181 // Clear mirror cache when leaving the debugger. Skip this if there is a
3191 // pending exception as clearing the mirror cache calls back into 3182 // pending exception as clearing the mirror cache calls back into
3192 // JavaScript. This can happen if the v8::Debug::Call is used in which 3183 // JavaScript. This can happen if the v8::Debug::Call is used in which
3193 // case the exception should end up in the calling code. 3184 // case the exception should end up in the calling code.
3194 if (!isolate_->has_pending_exception()) { 3185 if (!isolate_->has_pending_exception()) {
3195 debug->ClearMirrorCache(); 3186 debug->ClearMirrorCache();
3196 } 3187 }
3197 3188
3198 // If there are commands in the queue when leaving the debugger request 3189 // If there are commands in the queue when leaving the debugger request
3199 // that these commands are processed. 3190 // that these commands are processed.
3200 if (debug->HasCommands()) { 3191 if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand();
3201 isolate_->stack_guard()->RequestDebugCommand();
3202 }
3203 } 3192 }
3204 3193
3205 // Leaving this debugger entry. 3194 // Leaving this debugger entry.
3206 debug->set_debugger_entry(prev_); 3195 debug->thread_local_.debugger_entry_ = prev_;
3207 3196
3208 debug->UpdateState(); 3197 debug->UpdateState();
3209 } 3198 }
3210 3199
3211 3200
3212 MessageImpl MessageImpl::NewEvent(DebugEvent event, 3201 MessageImpl MessageImpl::NewEvent(DebugEvent event,
3213 bool running, 3202 bool running,
3214 Handle<JSObject> exec_state, 3203 Handle<JSObject> exec_state,
3215 Handle<JSObject> event_data) { 3204 Handle<JSObject> event_data) {
3216 MessageImpl message(true, event, running, 3205 MessageImpl message(true, event, running,
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
3462 logger_->DebugEvent("Put", message.text()); 3451 logger_->DebugEvent("Put", message.text());
3463 } 3452 }
3464 3453
3465 3454
3466 void LockingCommandMessageQueue::Clear() { 3455 void LockingCommandMessageQueue::Clear() {
3467 LockGuard<Mutex> lock_guard(&mutex_); 3456 LockGuard<Mutex> lock_guard(&mutex_);
3468 queue_.Clear(); 3457 queue_.Clear();
3469 } 3458 }
3470 3459
3471 } } // namespace v8::internal 3460 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/execution.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698