| 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 "src/debug/debug.h" | 5 #include "src/debug/debug.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 581 // Postpone interrupt during breakpoint processing. | 581 // Postpone interrupt during breakpoint processing. |
| 582 PostponeInterruptsScope postpone(isolate_); | 582 PostponeInterruptsScope postpone(isolate_); |
| 583 | 583 |
| 584 // Get the debug info (create it if it does not exist). | 584 // Get the debug info (create it if it does not exist). |
| 585 Handle<JSFunction> function(frame->function()); | 585 Handle<JSFunction> function(frame->function()); |
| 586 Handle<SharedFunctionInfo> shared(function->shared()); | 586 Handle<SharedFunctionInfo> shared(function->shared()); |
| 587 if (!EnsureDebugInfo(shared, function)) { | 587 if (!EnsureDebugInfo(shared, function)) { |
| 588 // Return if we failed to retrieve the debug info. | 588 // Return if we failed to retrieve the debug info. |
| 589 return; | 589 return; |
| 590 } | 590 } |
| 591 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 591 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_); |
| 592 | 592 |
| 593 // Find the break location where execution has stopped. | 593 // Find the break location where execution has stopped. |
| 594 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); | 594 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); |
| 595 | 595 |
| 596 // Find actual break points, if any, and trigger debug break event. | 596 // Find actual break points, if any, and trigger debug break event. |
| 597 Handle<Object> break_points_hit = CheckBreakPoints(&location); | 597 Handle<Object> break_points_hit = CheckBreakPoints(&location); |
| 598 if (!break_points_hit->IsUndefined()) { | 598 if (!break_points_hit->IsUndefined(isolate_)) { |
| 599 // Clear all current stepping setup. | 599 // Clear all current stepping setup. |
| 600 ClearStepping(); | 600 ClearStepping(); |
| 601 // Notify the debug event listeners. | 601 // Notify the debug event listeners. |
| 602 OnDebugBreak(break_points_hit, false); | 602 OnDebugBreak(break_points_hit, false); |
| 603 return; | 603 return; |
| 604 } | 604 } |
| 605 | 605 |
| 606 // No break point. Check for stepping. | 606 // No break point. Check for stepping. |
| 607 StepAction step_action = last_step_action(); | 607 StepAction step_action = last_step_action(); |
| 608 Address current_fp = frame->UnpaddedFP(); | 608 Address current_fp = frame->UnpaddedFP(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 659 bool has_break_points_to_check = | 659 bool has_break_points_to_check = |
| 660 break_points_active_ && location->HasBreakPoint(); | 660 break_points_active_ && location->HasBreakPoint(); |
| 661 if (has_break_points) *has_break_points = has_break_points_to_check; | 661 if (has_break_points) *has_break_points = has_break_points_to_check; |
| 662 if (!has_break_points_to_check) return factory->undefined_value(); | 662 if (!has_break_points_to_check) return factory->undefined_value(); |
| 663 | 663 |
| 664 Handle<Object> break_point_objects = location->BreakPointObjects(); | 664 Handle<Object> break_point_objects = location->BreakPointObjects(); |
| 665 // Count the number of break points hit. If there are multiple break points | 665 // Count the number of break points hit. If there are multiple break points |
| 666 // they are in a FixedArray. | 666 // they are in a FixedArray. |
| 667 Handle<FixedArray> break_points_hit; | 667 Handle<FixedArray> break_points_hit; |
| 668 int break_points_hit_count = 0; | 668 int break_points_hit_count = 0; |
| 669 DCHECK(!break_point_objects->IsUndefined()); | 669 DCHECK(!break_point_objects->IsUndefined(isolate_)); |
| 670 if (break_point_objects->IsFixedArray()) { | 670 if (break_point_objects->IsFixedArray()) { |
| 671 Handle<FixedArray> array(FixedArray::cast(*break_point_objects)); | 671 Handle<FixedArray> array(FixedArray::cast(*break_point_objects)); |
| 672 break_points_hit = factory->NewFixedArray(array->length()); | 672 break_points_hit = factory->NewFixedArray(array->length()); |
| 673 for (int i = 0; i < array->length(); i++) { | 673 for (int i = 0; i < array->length(); i++) { |
| 674 Handle<Object> break_point_object(array->get(i), isolate_); | 674 Handle<Object> break_point_object(array->get(i), isolate_); |
| 675 if (CheckBreakPoint(break_point_object)) { | 675 if (CheckBreakPoint(break_point_object)) { |
| 676 break_points_hit->set(break_points_hit_count++, *break_point_object); | 676 break_points_hit->set(break_points_hit_count++, *break_point_object); |
| 677 } | 677 } |
| 678 } | 678 } |
| 679 } else { | 679 } else { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 707 BreakLocation current_position = BreakLocation::FromFrame(debug_info, frame); | 707 BreakLocation current_position = BreakLocation::FromFrame(debug_info, frame); |
| 708 List<BreakLocation> break_locations; | 708 List<BreakLocation> break_locations; |
| 709 BreakLocation::AllForStatementPosition( | 709 BreakLocation::AllForStatementPosition( |
| 710 debug_info, current_position.statement_position(), &break_locations); | 710 debug_info, current_position.statement_position(), &break_locations); |
| 711 bool has_break_points_at_all = false; | 711 bool has_break_points_at_all = false; |
| 712 for (int i = 0; i < break_locations.length(); i++) { | 712 for (int i = 0; i < break_locations.length(); i++) { |
| 713 bool has_break_points; | 713 bool has_break_points; |
| 714 Handle<Object> check_result = | 714 Handle<Object> check_result = |
| 715 CheckBreakPoints(&break_locations[i], &has_break_points); | 715 CheckBreakPoints(&break_locations[i], &has_break_points); |
| 716 has_break_points_at_all |= has_break_points; | 716 has_break_points_at_all |= has_break_points; |
| 717 if (has_break_points && !check_result->IsUndefined()) return false; | 717 if (has_break_points && !check_result->IsUndefined(isolate_)) return false; |
| 718 } | 718 } |
| 719 return has_break_points_at_all; | 719 return has_break_points_at_all; |
| 720 } | 720 } |
| 721 | 721 |
| 722 | 722 |
| 723 MaybeHandle<Object> Debug::CallFunction(const char* name, int argc, | 723 MaybeHandle<Object> Debug::CallFunction(const char* name, int argc, |
| 724 Handle<Object> args[]) { | 724 Handle<Object> args[]) { |
| 725 PostponeInterruptsScope no_interrupts(isolate_); | 725 PostponeInterruptsScope no_interrupts(isolate_); |
| 726 AssertDebugContext(); | 726 AssertDebugContext(); |
| 727 Handle<JSReceiver> holder = | 727 Handle<JSReceiver> holder = |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 | 788 |
| 789 bool Debug::SetBreakPointForScript(Handle<Script> script, | 789 bool Debug::SetBreakPointForScript(Handle<Script> script, |
| 790 Handle<Object> break_point_object, | 790 Handle<Object> break_point_object, |
| 791 int* source_position, | 791 int* source_position, |
| 792 BreakPositionAlignment alignment) { | 792 BreakPositionAlignment alignment) { |
| 793 HandleScope scope(isolate_); | 793 HandleScope scope(isolate_); |
| 794 | 794 |
| 795 // Obtain shared function info for the function. | 795 // Obtain shared function info for the function. |
| 796 Handle<Object> result = | 796 Handle<Object> result = |
| 797 FindSharedFunctionInfoInScript(script, *source_position); | 797 FindSharedFunctionInfoInScript(script, *source_position); |
| 798 if (result->IsUndefined()) return false; | 798 if (result->IsUndefined(isolate_)) return false; |
| 799 | 799 |
| 800 // Make sure the function has set up the debug info. | 800 // Make sure the function has set up the debug info. |
| 801 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); | 801 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); |
| 802 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { | 802 if (!EnsureDebugInfo(shared, Handle<JSFunction>::null())) { |
| 803 // Return if retrieving debug info failed. | 803 // Return if retrieving debug info failed. |
| 804 return false; | 804 return false; |
| 805 } | 805 } |
| 806 | 806 |
| 807 // Find position within function. The script position might be before the | 807 // Find position within function. The script position might be before the |
| 808 // source position of the first function. | 808 // source position of the first function. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 835 } | 835 } |
| 836 | 836 |
| 837 | 837 |
| 838 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { | 838 void Debug::ClearBreakPoint(Handle<Object> break_point_object) { |
| 839 HandleScope scope(isolate_); | 839 HandleScope scope(isolate_); |
| 840 | 840 |
| 841 DebugInfoListNode* node = debug_info_list_; | 841 DebugInfoListNode* node = debug_info_list_; |
| 842 while (node != NULL) { | 842 while (node != NULL) { |
| 843 Handle<Object> result = | 843 Handle<Object> result = |
| 844 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object); | 844 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object); |
| 845 if (!result->IsUndefined()) { | 845 if (!result->IsUndefined(isolate_)) { |
| 846 // Get information in the break point. | 846 // Get information in the break point. |
| 847 Handle<BreakPointInfo> break_point_info = | 847 Handle<BreakPointInfo> break_point_info = |
| 848 Handle<BreakPointInfo>::cast(result); | 848 Handle<BreakPointInfo>::cast(result); |
| 849 Handle<DebugInfo> debug_info = node->debug_info(); | 849 Handle<DebugInfo> debug_info = node->debug_info(); |
| 850 | 850 |
| 851 BreakLocation location = BreakLocation::FromCodeOffset( | 851 BreakLocation location = BreakLocation::FromCodeOffset( |
| 852 debug_info, break_point_info->code_offset()); | 852 debug_info, break_point_info->code_offset()); |
| 853 location.ClearBreakPoint(break_point_object); | 853 location.ClearBreakPoint(break_point_object); |
| 854 | 854 |
| 855 // If there are no more break points left remove the debug info for this | 855 // If there are no more break points left remove the debug info for this |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 break; | 1098 break; |
| 1099 } | 1099 } |
| 1100 } | 1100 } |
| 1101 | 1101 |
| 1102 | 1102 |
| 1103 // Simple function for returning the source positions for active break points. | 1103 // Simple function for returning the source positions for active break points. |
| 1104 Handle<Object> Debug::GetSourceBreakLocations( | 1104 Handle<Object> Debug::GetSourceBreakLocations( |
| 1105 Handle<SharedFunctionInfo> shared, | 1105 Handle<SharedFunctionInfo> shared, |
| 1106 BreakPositionAlignment position_alignment) { | 1106 BreakPositionAlignment position_alignment) { |
| 1107 Isolate* isolate = shared->GetIsolate(); | 1107 Isolate* isolate = shared->GetIsolate(); |
| 1108 Heap* heap = isolate->heap(); | |
| 1109 if (!shared->HasDebugInfo()) { | 1108 if (!shared->HasDebugInfo()) { |
| 1110 return Handle<Object>(heap->undefined_value(), isolate); | 1109 return isolate->factory()->undefined_value(); |
| 1111 } | 1110 } |
| 1112 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); | 1111 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); |
| 1113 if (debug_info->GetBreakPointCount() == 0) { | 1112 if (debug_info->GetBreakPointCount() == 0) { |
| 1114 return Handle<Object>(heap->undefined_value(), isolate); | 1113 return isolate->factory()->undefined_value(); |
| 1115 } | 1114 } |
| 1116 Handle<FixedArray> locations = | 1115 Handle<FixedArray> locations = |
| 1117 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); | 1116 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); |
| 1118 int count = 0; | 1117 int count = 0; |
| 1119 for (int i = 0; i < debug_info->break_points()->length(); ++i) { | 1118 for (int i = 0; i < debug_info->break_points()->length(); ++i) { |
| 1120 if (!debug_info->break_points()->get(i)->IsUndefined()) { | 1119 if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) { |
| 1121 BreakPointInfo* break_point_info = | 1120 BreakPointInfo* break_point_info = |
| 1122 BreakPointInfo::cast(debug_info->break_points()->get(i)); | 1121 BreakPointInfo::cast(debug_info->break_points()->get(i)); |
| 1123 int break_points = break_point_info->GetBreakPointCount(); | 1122 int break_points = break_point_info->GetBreakPointCount(); |
| 1124 if (break_points == 0) continue; | 1123 if (break_points == 0) continue; |
| 1125 Smi* position = NULL; | 1124 Smi* position = NULL; |
| 1126 switch (position_alignment) { | 1125 switch (position_alignment) { |
| 1127 case STATEMENT_ALIGNED: | 1126 case STATEMENT_ALIGNED: |
| 1128 position = Smi::FromInt(break_point_info->statement_position()); | 1127 position = Smi::FromInt(break_point_info->statement_position()); |
| 1129 break; | 1128 break; |
| 1130 case BREAK_POSITION_ALIGNED: | 1129 case BREAK_POSITION_ALIGNED: |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1739 isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception; | 1738 isolate_->thread_local_top()->scheduled_exception_ = *scheduled_exception; |
| 1740 } | 1739 } |
| 1741 } | 1740 } |
| 1742 | 1741 |
| 1743 | 1742 |
| 1744 void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) { | 1743 void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) { |
| 1745 if (in_debug_scope() || ignore_events()) return; | 1744 if (in_debug_scope() || ignore_events()) return; |
| 1746 HandleScope scope(isolate_); | 1745 HandleScope scope(isolate_); |
| 1747 // Check whether the promise has been marked as having triggered a message. | 1746 // Check whether the promise has been marked as having triggered a message. |
| 1748 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol(); | 1747 Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol(); |
| 1749 if (JSReceiver::GetDataProperty(promise, key)->IsUndefined()) { | 1748 if (JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate_)) { |
| 1750 OnException(value, promise); | 1749 OnException(value, promise); |
| 1751 } | 1750 } |
| 1752 } | 1751 } |
| 1753 | 1752 |
| 1754 | 1753 |
| 1755 MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler( | 1754 MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler( |
| 1756 Handle<JSObject> promise) { | 1755 Handle<JSObject> promise) { |
| 1757 Handle<JSFunction> fun = isolate_->promise_has_user_defined_reject_handler(); | 1756 Handle<JSFunction> fun = isolate_->promise_has_user_defined_reject_handler(); |
| 1758 return Execution::Call(isolate_, fun, promise, 0, NULL); | 1757 return Execution::Call(isolate_, fun, promise, 0, NULL); |
| 1759 } | 1758 } |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2065 command_text).ToHandleChecked(); | 2064 command_text).ToHandleChecked(); |
| 2066 Handle<Object> request_args[] = { request_text }; | 2065 Handle<Object> request_args[] = { request_text }; |
| 2067 Handle<Object> answer_value; | 2066 Handle<Object> answer_value; |
| 2068 Handle<String> answer; | 2067 Handle<String> answer; |
| 2069 MaybeHandle<Object> maybe_exception; | 2068 MaybeHandle<Object> maybe_exception; |
| 2070 MaybeHandle<Object> maybe_result = | 2069 MaybeHandle<Object> maybe_result = |
| 2071 Execution::TryCall(isolate_, process_debug_request, cmd_processor, 1, | 2070 Execution::TryCall(isolate_, process_debug_request, cmd_processor, 1, |
| 2072 request_args, &maybe_exception); | 2071 request_args, &maybe_exception); |
| 2073 | 2072 |
| 2074 if (maybe_result.ToHandle(&answer_value)) { | 2073 if (maybe_result.ToHandle(&answer_value)) { |
| 2075 if (answer_value->IsUndefined()) { | 2074 if (answer_value->IsUndefined(isolate_)) { |
| 2076 answer = isolate_->factory()->empty_string(); | 2075 answer = isolate_->factory()->empty_string(); |
| 2077 } else { | 2076 } else { |
| 2078 answer = Handle<String>::cast(answer_value); | 2077 answer = Handle<String>::cast(answer_value); |
| 2079 } | 2078 } |
| 2080 | 2079 |
| 2081 // Log the JSON request/response. | 2080 // Log the JSON request/response. |
| 2082 if (FLAG_trace_debug_json) { | 2081 if (FLAG_trace_debug_json) { |
| 2083 PrintF("%s\n", request_text->ToCString().get()); | 2082 PrintF("%s\n", request_text->ToCString().get()); |
| 2084 PrintF("%s\n", answer->ToCString().get()); | 2083 PrintF("%s\n", answer->ToCString().get()); |
| 2085 } | 2084 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2116 Handle<Object> data) { | 2115 Handle<Object> data) { |
| 2117 GlobalHandles* global_handles = isolate_->global_handles(); | 2116 GlobalHandles* global_handles = isolate_->global_handles(); |
| 2118 | 2117 |
| 2119 // Remove existing entry. | 2118 // Remove existing entry. |
| 2120 GlobalHandles::Destroy(event_listener_.location()); | 2119 GlobalHandles::Destroy(event_listener_.location()); |
| 2121 event_listener_ = Handle<Object>(); | 2120 event_listener_ = Handle<Object>(); |
| 2122 GlobalHandles::Destroy(event_listener_data_.location()); | 2121 GlobalHandles::Destroy(event_listener_data_.location()); |
| 2123 event_listener_data_ = Handle<Object>(); | 2122 event_listener_data_ = Handle<Object>(); |
| 2124 | 2123 |
| 2125 // Set new entry. | 2124 // Set new entry. |
| 2126 if (!callback->IsUndefined() && !callback->IsNull()) { | 2125 if (!callback->IsUndefined(isolate_) && !callback->IsNull()) { |
| 2127 event_listener_ = global_handles->Create(*callback); | 2126 event_listener_ = global_handles->Create(*callback); |
| 2128 if (data.is_null()) data = isolate_->factory()->undefined_value(); | 2127 if (data.is_null()) data = isolate_->factory()->undefined_value(); |
| 2129 event_listener_data_ = global_handles->Create(*data); | 2128 event_listener_data_ = global_handles->Create(*data); |
| 2130 } | 2129 } |
| 2131 | 2130 |
| 2132 UpdateState(); | 2131 UpdateState(); |
| 2133 } | 2132 } |
| 2134 | 2133 |
| 2135 | 2134 |
| 2136 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { | 2135 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2607 } | 2606 } |
| 2608 | 2607 |
| 2609 | 2608 |
| 2610 void LockingCommandMessageQueue::Clear() { | 2609 void LockingCommandMessageQueue::Clear() { |
| 2611 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 2610 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
| 2612 queue_.Clear(); | 2611 queue_.Clear(); |
| 2613 } | 2612 } |
| 2614 | 2613 |
| 2615 } // namespace internal | 2614 } // namespace internal |
| 2616 } // namespace v8 | 2615 } // namespace v8 |
| OLD | NEW |