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

Side by Side Diff: src/debug.cc

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 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/deoptimizer.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 22 matching lines...) Expand all
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "codegen.h" 34 #include "codegen.h"
35 #include "compilation-cache.h" 35 #include "compilation-cache.h"
36 #include "compiler.h" 36 #include "compiler.h"
37 #include "debug.h" 37 #include "debug.h"
38 #include "deoptimizer.h" 38 #include "deoptimizer.h"
39 #include "execution.h" 39 #include "execution.h"
40 #include "global-handles.h" 40 #include "global-handles.h"
41 #include "ic.h" 41 #include "ic.h"
42 #include "ic-inl.h" 42 #include "ic-inl.h"
43 #include "isolate-inl.h"
43 #include "list.h" 44 #include "list.h"
44 #include "messages.h" 45 #include "messages.h"
45 #include "natives.h" 46 #include "natives.h"
46 #include "stub-cache.h" 47 #include "stub-cache.h"
47 #include "log.h" 48 #include "log.h"
48 49
49 #include "../include/v8-debug.h" 50 #include "../include/v8-debug.h"
50 51
51 namespace v8 { 52 namespace v8 {
52 namespace internal { 53 namespace internal {
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 ASSERT(!IsDebugBreak()); 395 ASSERT(!IsDebugBreak());
395 } 396 }
396 397
397 398
398 void BreakLocationIterator::PrepareStepIn() { 399 void BreakLocationIterator::PrepareStepIn() {
399 HandleScope scope; 400 HandleScope scope;
400 401
401 // Step in can only be prepared if currently positioned on an IC call, 402 // Step in can only be prepared if currently positioned on an IC call,
402 // construct call or CallFunction stub call. 403 // construct call or CallFunction stub call.
403 Address target = rinfo()->target_address(); 404 Address target = rinfo()->target_address();
404 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); 405 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
405 if (code->is_call_stub() || code->is_keyed_call_stub()) { 406 if (target_code->is_call_stub() || target_code->is_keyed_call_stub()) {
406 // Step in through IC call is handled by the runtime system. Therefore make 407 // Step in through IC call is handled by the runtime system. Therefore make
407 // sure that the any current IC is cleared and the runtime system is 408 // sure that the any current IC is cleared and the runtime system is
408 // called. If the executing code has a debug break at the location change 409 // called. If the executing code has a debug break at the location change
409 // the call in the original code as it is the code there that will be 410 // the call in the original code as it is the code there that will be
410 // executed in place of the debug break call. 411 // executed in place of the debug break call.
411 Handle<Code> stub = ComputeCallDebugPrepareStepIn(code->arguments_count(), 412 Handle<Code> stub = ComputeCallDebugPrepareStepIn(
412 code->kind()); 413 target_code->arguments_count(), target_code->kind());
413 if (IsDebugBreak()) { 414 if (IsDebugBreak()) {
414 original_rinfo()->set_target_address(stub->entry()); 415 original_rinfo()->set_target_address(stub->entry());
415 } else { 416 } else {
416 rinfo()->set_target_address(stub->entry()); 417 rinfo()->set_target_address(stub->entry());
417 } 418 }
418 } else { 419 } else {
419 #ifdef DEBUG 420 #ifdef DEBUG
420 // All the following stuff is needed only for assertion checks so the code 421 // All the following stuff is needed only for assertion checks so the code
421 // is wrapped in ifdef. 422 // is wrapped in ifdef.
422 Handle<Code> maybe_call_function_stub = code; 423 Handle<Code> maybe_call_function_stub = target_code;
423 if (IsDebugBreak()) { 424 if (IsDebugBreak()) {
424 Address original_target = original_rinfo()->target_address(); 425 Address original_target = original_rinfo()->target_address();
425 maybe_call_function_stub = 426 maybe_call_function_stub =
426 Handle<Code>(Code::GetCodeFromTargetAddress(original_target)); 427 Handle<Code>(Code::GetCodeFromTargetAddress(original_target));
427 } 428 }
428 bool is_call_function_stub = 429 bool is_call_function_stub =
429 (maybe_call_function_stub->kind() == Code::STUB && 430 (maybe_call_function_stub->kind() == Code::STUB &&
430 maybe_call_function_stub->major_key() == CodeStub::CallFunction); 431 maybe_call_function_stub->major_key() == CodeStub::CallFunction);
431 432
432 // Step in through construct call requires no changes to the running code. 433 // Step in through construct call requires no changes to the running code.
433 // Step in through getters/setters should already be prepared as well 434 // Step in through getters/setters should already be prepared as well
434 // because caller of this function (Debug::PrepareStep) is expected to 435 // because caller of this function (Debug::PrepareStep) is expected to
435 // flood the top frame's function with one shot breakpoints. 436 // flood the top frame's function with one shot breakpoints.
436 // Step in through CallFunction stub should also be prepared by caller of 437 // Step in through CallFunction stub should also be prepared by caller of
437 // this function (Debug::PrepareStep) which should flood target function 438 // this function (Debug::PrepareStep) which should flood target function
438 // with breakpoints. 439 // with breakpoints.
439 ASSERT(RelocInfo::IsConstructCall(rmode()) || code->is_inline_cache_stub() 440 ASSERT(RelocInfo::IsConstructCall(rmode()) ||
440 || is_call_function_stub); 441 target_code->is_inline_cache_stub() ||
442 is_call_function_stub);
441 #endif 443 #endif
442 } 444 }
443 } 445 }
444 446
445 447
446 // Check whether the break point is at a position which will exit the function. 448 // Check whether the break point is at a position which will exit the function.
447 bool BreakLocationIterator::IsExit() const { 449 bool BreakLocationIterator::IsExit() const {
448 return (RelocInfo::IsJSReturn(rmode())); 450 return (RelocInfo::IsJSReturn(rmode()));
449 } 451 }
450 452
(...skipping 16 matching lines...) Expand all
467 469
468 470
469 void BreakLocationIterator::SetDebugBreakAtIC() { 471 void BreakLocationIterator::SetDebugBreakAtIC() {
470 // Patch the original code with the current address as the current address 472 // Patch the original code with the current address as the current address
471 // might have changed by the inline caching since the code was copied. 473 // might have changed by the inline caching since the code was copied.
472 original_rinfo()->set_target_address(rinfo()->target_address()); 474 original_rinfo()->set_target_address(rinfo()->target_address());
473 475
474 RelocInfo::Mode mode = rmode(); 476 RelocInfo::Mode mode = rmode();
475 if (RelocInfo::IsCodeTarget(mode)) { 477 if (RelocInfo::IsCodeTarget(mode)) {
476 Address target = rinfo()->target_address(); 478 Address target = rinfo()->target_address();
477 Handle<Code> code(Code::GetCodeFromTargetAddress(target)); 479 Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
478 480
479 // Patch the code to invoke the builtin debug break function matching the 481 // Patch the code to invoke the builtin debug break function matching the
480 // calling convention used by the call site. 482 // calling convention used by the call site.
481 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode)); 483 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(target_code, mode));
482 rinfo()->set_target_address(dbgbrk_code->entry()); 484 rinfo()->set_target_address(dbgbrk_code->entry());
483 } 485 }
484 } 486 }
485 487
486 488
487 void BreakLocationIterator::ClearDebugBreakAtIC() { 489 void BreakLocationIterator::ClearDebugBreakAtIC() {
488 // Patch the code to the original invoke. 490 // Patch the code to the original invoke.
489 rinfo()->set_target_address(original_rinfo()->target_address()); 491 rinfo()->set_target_address(original_rinfo()->target_address());
490 } 492 }
491 493
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 767
766 // Silently ignore stack overflows during compilation. 768 // Silently ignore stack overflows during compilation.
767 if (function_info.is_null()) { 769 if (function_info.is_null()) {
768 ASSERT(isolate->has_pending_exception()); 770 ASSERT(isolate->has_pending_exception());
769 isolate->clear_pending_exception(); 771 isolate->clear_pending_exception();
770 return false; 772 return false;
771 } 773 }
772 774
773 // Execute the shared function in the debugger context. 775 // Execute the shared function in the debugger context.
774 Handle<Context> context = isolate->global_context(); 776 Handle<Context> context = isolate->global_context();
775 bool caught_exception = false; 777 bool caught_exception;
776 Handle<JSFunction> function = 778 Handle<JSFunction> function =
777 factory->NewFunctionFromSharedFunctionInfo(function_info, context); 779 factory->NewFunctionFromSharedFunctionInfo(function_info, context);
778 780
779 Execution::TryCall(function, Handle<Object>(context->global()), 781 Execution::TryCall(function, Handle<Object>(context->global()),
780 0, NULL, &caught_exception); 782 0, NULL, &caught_exception);
781 783
782 // Check for caught exceptions. 784 // Check for caught exceptions.
783 if (caught_exception) { 785 if (caught_exception) {
784 Handle<Object> message = MessageHandler::MakeMessageObject( 786 Handle<Object> message = MessageHandler::MakeMessageObject(
785 "error_loading_debugger", NULL, Vector<Handle<Object> >::empty(), 787 "error_loading_debugger", NULL, Vector<Handle<Object> >::empty(),
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 factory->LookupAsciiSymbol("IsBreakPointTriggered"); 1098 factory->LookupAsciiSymbol("IsBreakPointTriggered");
1097 Handle<JSFunction> check_break_point = 1099 Handle<JSFunction> check_break_point =
1098 Handle<JSFunction>(JSFunction::cast( 1100 Handle<JSFunction>(JSFunction::cast(
1099 debug_context()->global()->GetPropertyNoExceptionThrown( 1101 debug_context()->global()->GetPropertyNoExceptionThrown(
1100 *is_break_point_triggered_symbol))); 1102 *is_break_point_triggered_symbol)));
1101 1103
1102 // Get the break id as an object. 1104 // Get the break id as an object.
1103 Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id()); 1105 Handle<Object> break_id = factory->NewNumberFromInt(Debug::break_id());
1104 1106
1105 // Call HandleBreakPointx. 1107 // Call HandleBreakPointx.
1106 bool caught_exception = false; 1108 bool caught_exception;
1107 const int argc = 2; 1109 const int argc = 2;
1108 Object** argv[argc] = { 1110 Object** argv[argc] = {
1109 break_id.location(), 1111 break_id.location(),
1110 reinterpret_cast<Object**>(break_point_object.location()) 1112 reinterpret_cast<Object**>(break_point_object.location())
1111 }; 1113 };
1112 Handle<Object> result = Execution::TryCall(check_break_point, 1114 Handle<Object> result = Execution::TryCall(check_break_point,
1113 isolate_->js_builtins_object(), argc, argv, &caught_exception); 1115 isolate_->js_builtins_object(), argc, argv, &caught_exception);
1114 1116
1115 // If exception or non boolean result handle as not triggered 1117 // If exception or non boolean result handle as not triggered
1116 if (caught_exception || !result->IsBoolean()) { 1118 if (caught_exception || !result->IsBoolean()) {
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 thread_local_.last_fp_ = 0; 1727 thread_local_.last_fp_ = 0;
1726 } 1728 }
1727 1729
1728 1730
1729 void Debug::PrepareForBreakPoints() { 1731 void Debug::PrepareForBreakPoints() {
1730 // If preparing for the first break point make sure to deoptimize all 1732 // If preparing for the first break point make sure to deoptimize all
1731 // functions as debugging does not work with optimized code. 1733 // functions as debugging does not work with optimized code.
1732 if (!has_break_points_) { 1734 if (!has_break_points_) {
1733 Deoptimizer::DeoptimizeAll(); 1735 Deoptimizer::DeoptimizeAll();
1734 1736
1737 // We are going to iterate heap to find all functions without
1738 // debug break slots.
1739 isolate_->heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask);
1740
1735 AssertNoAllocation no_allocation; 1741 AssertNoAllocation no_allocation;
1736 Builtins* builtins = isolate_->builtins(); 1742 Builtins* builtins = isolate_->builtins();
1737 Code* lazy_compile = builtins->builtin(Builtins::kLazyCompile); 1743 Code* lazy_compile = builtins->builtin(Builtins::kLazyCompile);
1738 1744
1739 // Find all non-optimized code functions with activation frames on 1745 // Find all non-optimized code functions with activation frames on
1740 // the stack. 1746 // the stack.
1741 List<JSFunction*> active_functions(100); 1747 List<JSFunction*> active_functions(100);
1742 for (JavaScriptFrameIterator it(isolate_); !it.done(); it.Advance()) { 1748 for (JavaScriptFrameIterator it(isolate_); !it.done(); it.Advance()) {
1743 JavaScriptFrame* frame = it.frame(); 1749 JavaScriptFrame* frame = it.frame();
1744 if (frame->function()->IsJSFunction()) { 1750 if (frame->function()->IsJSFunction()) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1990 0, NULL, &caught_exception); 1996 0, NULL, &caught_exception);
1991 } 1997 }
1992 1998
1993 1999
1994 void Debug::CreateScriptCache() { 2000 void Debug::CreateScriptCache() {
1995 Heap* heap = isolate_->heap(); 2001 Heap* heap = isolate_->heap();
1996 HandleScope scope(isolate_); 2002 HandleScope scope(isolate_);
1997 2003
1998 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets 2004 // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
1999 // rid of all the cached script wrappers and the second gets rid of the 2005 // rid of all the cached script wrappers and the second gets rid of the
2000 // scripts which are no longer referenced. 2006 // scripts which are no longer referenced. The second also sweeps precisely,
2001 heap->CollectAllGarbage(false); 2007 // which saves us doing yet another GC to make the heap iterable.
2002 heap->CollectAllGarbage(false); 2008 heap->CollectAllGarbage(Heap::kNoGCFlags);
2009 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask);
2003 2010
2004 ASSERT(script_cache_ == NULL); 2011 ASSERT(script_cache_ == NULL);
2005 script_cache_ = new ScriptCache(); 2012 script_cache_ = new ScriptCache();
2006 2013
2007 // Scan heap for Script objects. 2014 // Scan heap for Script objects.
2008 int count = 0; 2015 int count = 0;
2009 HeapIterator iterator; 2016 HeapIterator iterator;
2017 AssertNoAllocation no_allocation;
2018
2010 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 2019 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
2011 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { 2020 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
2012 script_cache_->Add(Handle<Script>(Script::cast(obj))); 2021 script_cache_->Add(Handle<Script>(Script::cast(obj)));
2013 count++; 2022 count++;
2014 } 2023 }
2015 } 2024 }
2016 } 2025 }
2017 2026
2018 2027
2019 void Debug::DestroyScriptCache() { 2028 void Debug::DestroyScriptCache() {
(...skipping 20 matching lines...) Expand all
2040 } 2049 }
2041 2050
2042 // If the script cache is not active just return an empty array. 2051 // If the script cache is not active just return an empty array.
2043 ASSERT(script_cache_ != NULL); 2052 ASSERT(script_cache_ != NULL);
2044 if (script_cache_ == NULL) { 2053 if (script_cache_ == NULL) {
2045 isolate_->factory()->NewFixedArray(0); 2054 isolate_->factory()->NewFixedArray(0);
2046 } 2055 }
2047 2056
2048 // Perform GC to get unreferenced scripts evicted from the cache before 2057 // Perform GC to get unreferenced scripts evicted from the cache before
2049 // returning the content. 2058 // returning the content.
2050 isolate_->heap()->CollectAllGarbage(false); 2059 isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags);
2051 2060
2052 // Get the scripts from the cache. 2061 // Get the scripts from the cache.
2053 return script_cache_->GetScripts(); 2062 return script_cache_->GetScripts();
2054 } 2063 }
2055 2064
2056 2065
2057 void Debug::AfterGarbageCollection() { 2066 void Debug::AfterGarbageCollection() {
2058 // Generate events for collected scripts. 2067 // Generate events for collected scripts.
2059 if (script_cache_ != NULL) { 2068 if (script_cache_ != NULL) {
2060 script_cache_->ProcessCollectedScripts(); 2069 script_cache_->ProcessCollectedScripts();
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 if (!update_script_break_points->IsJSFunction()) { 2347 if (!update_script_break_points->IsJSFunction()) {
2339 return; 2348 return;
2340 } 2349 }
2341 ASSERT(update_script_break_points->IsJSFunction()); 2350 ASSERT(update_script_break_points->IsJSFunction());
2342 2351
2343 // Wrap the script object in a proper JS object before passing it 2352 // Wrap the script object in a proper JS object before passing it
2344 // to JavaScript. 2353 // to JavaScript.
2345 Handle<JSValue> wrapper = GetScriptWrapper(script); 2354 Handle<JSValue> wrapper = GetScriptWrapper(script);
2346 2355
2347 // Call UpdateScriptBreakPoints expect no exceptions. 2356 // Call UpdateScriptBreakPoints expect no exceptions.
2348 bool caught_exception = false; 2357 bool caught_exception;
2349 const int argc = 1; 2358 const int argc = 1;
2350 Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) }; 2359 Object** argv[argc] = { reinterpret_cast<Object**>(wrapper.location()) };
2351 Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points), 2360 Execution::TryCall(Handle<JSFunction>::cast(update_script_break_points),
2352 Isolate::Current()->js_builtins_object(), argc, argv, 2361 Isolate::Current()->js_builtins_object(), argc, argv,
2353 &caught_exception); 2362 &caught_exception);
2354 if (caught_exception) { 2363 if (caught_exception) {
2355 return; 2364 return;
2356 } 2365 }
2357 // Bail out based on state or if there is no listener for this event 2366 // Bail out based on state or if there is no listener for this event
2358 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return; 2367 if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
2479 Handle<Object> event_data) { 2488 Handle<Object> event_data) {
2480 ASSERT(event_listener_->IsJSFunction()); 2489 ASSERT(event_listener_->IsJSFunction());
2481 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); 2490 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_));
2482 2491
2483 // Invoke the JavaScript debug event listener. 2492 // Invoke the JavaScript debug event listener.
2484 const int argc = 4; 2493 const int argc = 4;
2485 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), 2494 Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(),
2486 exec_state.location(), 2495 exec_state.location(),
2487 Handle<Object>::cast(event_data).location(), 2496 Handle<Object>::cast(event_data).location(),
2488 event_listener_data_.location() }; 2497 event_listener_data_.location() };
2489 bool caught_exception = false; 2498 bool caught_exception;
2490 Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception); 2499 Execution::TryCall(fun, isolate_->global(), argc, argv, &caught_exception);
2491 // Silently ignore exceptions from debug event listeners. 2500 // Silently ignore exceptions from debug event listeners.
2492 } 2501 }
2493 2502
2494 2503
2495 Handle<Context> Debugger::GetDebugContext() { 2504 Handle<Context> Debugger::GetDebugContext() {
2496 never_unload_debugger_ = true; 2505 never_unload_debugger_ = true;
2497 EnterDebugger debugger; 2506 EnterDebugger debugger;
2498 return isolate_->debug()->debug_context(); 2507 return isolate_->debug()->debug_context();
2499 } 2508 }
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 { 2931 {
2923 ScopedLock with(dispatch_handler_access_); 2932 ScopedLock with(dispatch_handler_access_);
2924 handler = Debugger::debug_message_dispatch_handler_; 2933 handler = Debugger::debug_message_dispatch_handler_;
2925 } 2934 }
2926 if (handler != NULL) { 2935 if (handler != NULL) {
2927 handler(); 2936 handler();
2928 } 2937 }
2929 } 2938 }
2930 2939
2931 2940
2941 EnterDebugger::EnterDebugger()
2942 : isolate_(Isolate::Current()),
2943 prev_(isolate_->debug()->debugger_entry()),
2944 it_(isolate_),
2945 has_js_frames_(!it_.done()),
2946 save_(isolate_) {
2947 Debug* debug = isolate_->debug();
2948 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(PREEMPT));
2949 ASSERT(prev_ != NULL || !debug->is_interrupt_pending(DEBUGBREAK));
2950
2951 // Link recursive debugger entry.
2952 debug->set_debugger_entry(this);
2953
2954 // Store the previous break id and frame id.
2955 break_id_ = debug->break_id();
2956 break_frame_id_ = debug->break_frame_id();
2957
2958 // Create the new break info. If there is no JavaScript frames there is no
2959 // break frame id.
2960 if (has_js_frames_) {
2961 debug->NewBreak(it_.frame()->id());
2962 } else {
2963 debug->NewBreak(StackFrame::NO_ID);
2964 }
2965
2966 // Make sure that debugger is loaded and enter the debugger context.
2967 load_failed_ = !debug->Load();
2968 if (!load_failed_) {
2969 // NOTE the member variable save which saves the previous context before
2970 // this change.
2971 isolate_->set_context(*debug->debug_context());
2972 }
2973 }
2974
2975
2976 EnterDebugger::~EnterDebugger() {
2977 ASSERT(Isolate::Current() == isolate_);
2978 Debug* debug = isolate_->debug();
2979
2980 // Restore to the previous break state.
2981 debug->SetBreak(break_frame_id_, break_id_);
2982
2983 // Check for leaving the debugger.
2984 if (prev_ == NULL) {
2985 // Clear mirror cache when leaving the debugger. Skip this if there is a
2986 // pending exception as clearing the mirror cache calls back into
2987 // JavaScript. This can happen if the v8::Debug::Call is used in which
2988 // case the exception should end up in the calling code.
2989 if (!isolate_->has_pending_exception()) {
2990 // Try to avoid any pending debug break breaking in the clear mirror
2991 // cache JavaScript code.
2992 if (isolate_->stack_guard()->IsDebugBreak()) {
2993 debug->set_interrupts_pending(DEBUGBREAK);
2994 isolate_->stack_guard()->Continue(DEBUGBREAK);
2995 }
2996 debug->ClearMirrorCache();
2997 }
2998
2999 // Request preemption and debug break when leaving the last debugger entry
3000 // if any of these where recorded while debugging.
3001 if (debug->is_interrupt_pending(PREEMPT)) {
3002 // This re-scheduling of preemption is to avoid starvation in some
3003 // debugging scenarios.
3004 debug->clear_interrupt_pending(PREEMPT);
3005 isolate_->stack_guard()->Preempt();
3006 }
3007 if (debug->is_interrupt_pending(DEBUGBREAK)) {
3008 debug->clear_interrupt_pending(DEBUGBREAK);
3009 isolate_->stack_guard()->DebugBreak();
3010 }
3011
3012 // If there are commands in the queue when leaving the debugger request
3013 // that these commands are processed.
3014 if (isolate_->debugger()->HasCommands()) {
3015 isolate_->stack_guard()->DebugCommand();
3016 }
3017
3018 // If leaving the debugger with the debugger no longer active unload it.
3019 if (!isolate_->debugger()->IsDebuggerActive()) {
3020 isolate_->debugger()->UnloadDebugger();
3021 }
3022 }
3023
3024 // Leaving this debugger entry.
3025 debug->set_debugger_entry(prev_);
3026 }
3027
3028
2932 MessageImpl MessageImpl::NewEvent(DebugEvent event, 3029 MessageImpl MessageImpl::NewEvent(DebugEvent event,
2933 bool running, 3030 bool running,
2934 Handle<JSObject> exec_state, 3031 Handle<JSObject> exec_state,
2935 Handle<JSObject> event_data) { 3032 Handle<JSObject> event_data) {
2936 MessageImpl message(true, event, running, 3033 MessageImpl message(true, event, running,
2937 exec_state, event_data, Handle<String>(), NULL); 3034 exec_state, event_data, Handle<String>(), NULL);
2938 return message; 3035 return message;
2939 } 3036 }
2940 3037
2941 3038
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
3224 { 3321 {
3225 Locker locker; 3322 Locker locker;
3226 Isolate::Current()->debugger()->CallMessageDispatchHandler(); 3323 Isolate::Current()->debugger()->CallMessageDispatchHandler();
3227 } 3324 }
3228 } 3325 }
3229 } 3326 }
3230 3327
3231 #endif // ENABLE_DEBUGGER_SUPPORT 3328 #endif // ENABLE_DEBUGGER_SUPPORT
3232 3329
3233 } } // namespace v8::internal 3330 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/deoptimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698