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

Side by Side Diff: src/debug/debug.cc

Issue 2909893002: [debug] Untangle DebugInfo from break point support (Closed)
Patch Set: Port arm,arm64,ia32 Created 3 years, 6 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
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 "src/debug/debug.h" 5 #include "src/debug/debug.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 DebugScope debug_scope(this); 504 DebugScope debug_scope(this);
505 if (debug_scope.failed()) return; 505 if (debug_scope.failed()) return;
506 506
507 // Postpone interrupt during breakpoint processing. 507 // Postpone interrupt during breakpoint processing.
508 PostponeInterruptsScope postpone(isolate_); 508 PostponeInterruptsScope postpone(isolate_);
509 DisableBreak no_recursive_break(this); 509 DisableBreak no_recursive_break(this);
510 510
511 // Return if we fail to retrieve debug info. 511 // Return if we fail to retrieve debug info.
512 Handle<JSFunction> function(frame->function()); 512 Handle<JSFunction> function(frame->function());
513 Handle<SharedFunctionInfo> shared(function->shared()); 513 Handle<SharedFunctionInfo> shared(function->shared());
514 if (!EnsureDebugInfo(shared)) return; 514 if (!EnsureBreakInfo(shared)) return;
515 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_); 515 Handle<DebugInfo> debug_info(shared->GetDebugInfo(), isolate_);
516 516
517 // Find the break location where execution has stopped. 517 // Find the break location where execution has stopped.
518 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 518 BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
519 519
520 // Find actual break points, if any, and trigger debug break event. 520 // Find actual break points, if any, and trigger debug break event.
521 MaybeHandle<FixedArray> break_points_hit = 521 MaybeHandle<FixedArray> break_points_hit =
522 CheckBreakPoints(debug_info, &location); 522 CheckBreakPoints(debug_info, &location);
523 if (!break_points_hit.is_null()) { 523 if (!break_points_hit.is_null()) {
524 // Clear all current stepping setup. 524 // Clear all current stepping setup.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 bool Debug::IsMutedAtCurrentLocation(JavaScriptFrame* frame) { 605 bool Debug::IsMutedAtCurrentLocation(JavaScriptFrame* frame) {
606 HandleScope scope(isolate_); 606 HandleScope scope(isolate_);
607 // A break location is considered muted if break locations on the current 607 // A break location is considered muted if break locations on the current
608 // statement have at least one break point, and all of these break points 608 // statement have at least one break point, and all of these break points
609 // evaluate to false. Aside from not triggering a debug break event at the 609 // evaluate to false. Aside from not triggering a debug break event at the
610 // break location, we also do not trigger one for debugger statements, nor 610 // break location, we also do not trigger one for debugger statements, nor
611 // an exception event on exception at this location. 611 // an exception event on exception at this location.
612 FrameSummary summary = FrameSummary::GetTop(frame); 612 FrameSummary summary = FrameSummary::GetTop(frame);
613 DCHECK(!summary.IsWasm()); 613 DCHECK(!summary.IsWasm());
614 Handle<JSFunction> function = summary.AsJavaScript().function(); 614 Handle<JSFunction> function = summary.AsJavaScript().function();
615 if (!function->shared()->HasDebugInfo()) return false; 615 if (!function->shared()->HasBreakInfo()) return false;
616 Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo()); 616 Handle<DebugInfo> debug_info(function->shared()->GetDebugInfo());
617 // Enter the debugger. 617 // Enter the debugger.
618 DebugScope debug_scope(this); 618 DebugScope debug_scope(this);
619 if (debug_scope.failed()) return false; 619 if (debug_scope.failed()) return false;
620 List<BreakLocation> break_locations; 620 List<BreakLocation> break_locations;
621 BreakLocation::AllAtCurrentStatement(debug_info, frame, &break_locations); 621 BreakLocation::AllAtCurrentStatement(debug_info, frame, &break_locations);
622 bool has_break_points_at_all = false; 622 bool has_break_points_at_all = false;
623 for (int i = 0; i < break_locations.length(); i++) { 623 for (int i = 0; i < break_locations.length(); i++) {
624 bool has_break_points; 624 bool has_break_points;
625 MaybeHandle<FixedArray> check_result = 625 MaybeHandle<FixedArray> check_result =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 } 671 }
672 672
673 673
674 bool Debug::SetBreakPoint(Handle<JSFunction> function, 674 bool Debug::SetBreakPoint(Handle<JSFunction> function,
675 Handle<Object> break_point_object, 675 Handle<Object> break_point_object,
676 int* source_position) { 676 int* source_position) {
677 HandleScope scope(isolate_); 677 HandleScope scope(isolate_);
678 678
679 // Make sure the function is compiled and has set up the debug info. 679 // Make sure the function is compiled and has set up the debug info.
680 Handle<SharedFunctionInfo> shared(function->shared()); 680 Handle<SharedFunctionInfo> shared(function->shared());
681 if (!EnsureDebugInfo(shared)) return true; 681 if (!EnsureBreakInfo(shared)) return true;
682 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 682 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
683 // Source positions starts with zero. 683 // Source positions starts with zero.
684 DCHECK(*source_position >= 0); 684 DCHECK(*source_position >= 0);
685 685
686 // Find the break point and change it. 686 // Find the break point and change it.
687 *source_position = 687 *source_position =
688 FindBreakablePosition(debug_info, *source_position, STATEMENT_ALIGNED); 688 FindBreakablePosition(debug_info, *source_position, STATEMENT_ALIGNED);
689 DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object); 689 DebugInfo::SetBreakPoint(debug_info, *source_position, break_point_object);
690 // At least one active break point now. 690 // At least one active break point now.
691 DCHECK(debug_info->GetBreakPointCount() > 0); 691 DCHECK(debug_info->GetBreakPointCount() > 0);
(...skipping 19 matching lines...) Expand all
711 711
712 HandleScope scope(isolate_); 712 HandleScope scope(isolate_);
713 713
714 // Obtain shared function info for the function. 714 // Obtain shared function info for the function.
715 Handle<Object> result = 715 Handle<Object> result =
716 FindSharedFunctionInfoInScript(script, *source_position); 716 FindSharedFunctionInfoInScript(script, *source_position);
717 if (result->IsUndefined(isolate_)) return false; 717 if (result->IsUndefined(isolate_)) return false;
718 718
719 // Make sure the function has set up the debug info. 719 // Make sure the function has set up the debug info.
720 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result); 720 Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(result);
721 if (!EnsureDebugInfo(shared)) return false; 721 if (!EnsureBreakInfo(shared)) return false;
722 722
723 // Find position within function. The script position might be before the 723 // Find position within function. The script position might be before the
724 // source position of the first function. 724 // source position of the first function.
725 if (shared->start_position() > *source_position) { 725 if (shared->start_position() > *source_position) {
726 *source_position = shared->start_position(); 726 *source_position = shared->start_position();
727 } 727 }
728 728
729 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 729 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
730 730
731 // Find the break point and change it. 731 // Find the break point and change it.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 802
803 for (DebugInfoListNode* node = debug_info_list_; node != NULL; 803 for (DebugInfoListNode* node = debug_info_list_; node != NULL;
804 node = node->next()) { 804 node = node->next()) {
805 Handle<Object> result = 805 Handle<Object> result =
806 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object); 806 DebugInfo::FindBreakPointInfo(node->debug_info(), break_point_object);
807 if (result->IsUndefined(isolate_)) continue; 807 if (result->IsUndefined(isolate_)) continue;
808 Handle<DebugInfo> debug_info = node->debug_info(); 808 Handle<DebugInfo> debug_info = node->debug_info();
809 if (DebugInfo::ClearBreakPoint(debug_info, break_point_object)) { 809 if (DebugInfo::ClearBreakPoint(debug_info, break_point_object)) {
810 ClearBreakPoints(debug_info); 810 ClearBreakPoints(debug_info);
811 if (debug_info->GetBreakPointCount() == 0) { 811 if (debug_info->GetBreakPointCount() == 0) {
812 RemoveDebugInfoAndClearFromShared(debug_info); 812 RemoveBreakInfoAndMaybeFree(debug_info);
813 } else { 813 } else {
814 ApplyBreakPoints(debug_info); 814 ApplyBreakPoints(debug_info);
815 } 815 }
816 return; 816 return;
817 } 817 }
818 } 818 }
819 } 819 }
820 820
821 // Clear out all the debug break code. This is ONLY supposed to be used when 821 // Clear out all the debug break code.
822 // shutting down the debugger as it will leave the break point information in
823 // DebugInfo even though the code is patched back to the non break point state.
824 void Debug::ClearAllBreakPoints() { 822 void Debug::ClearAllBreakPoints() {
825 for (DebugInfoListNode* node = debug_info_list_; node != NULL; 823 DebugInfoListNode* curr = debug_info_list_;
Michael Starzinger 2017/05/31 13:14:58 nit: s/curr/current/
jgruber 2017/05/31 13:46:45 Done.
826 node = node->next()) { 824 while (curr != nullptr) {
827 ClearBreakPoints(node->debug_info()); 825 DebugInfoListNode* next = curr->next();
828 } 826 Handle<DebugInfo> debug_info = curr->debug_info();
829 // Remove all debug info. 827 ClearBreakPoints(debug_info);
830 while (debug_info_list_ != NULL) { 828 RemoveBreakInfoAndMaybeFree(debug_info);
Michael Starzinger 2017/05/31 13:14:57 question: This seems like it could have quadratic
jgruber 2017/05/31 13:46:45 Changed this slightly to avoid the linked-list sea
831 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); 829 curr = next;
832 } 830 }
833 } 831 }
834 832
835 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared, 833 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared,
836 bool returns_only) { 834 bool returns_only) {
837 if (IsBlackboxed(shared)) return; 835 if (IsBlackboxed(shared)) return;
838 // Make sure the function is compiled and has set up the debug info. 836 // Make sure the function is compiled and has set up the debug info.
839 if (!EnsureDebugInfo(shared)) return; 837 if (!EnsureBreakInfo(shared)) return;
840 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 838 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
841 // Flood the function with break points. 839 // Flood the function with break points.
842 if (debug_info->HasDebugCode()) { 840 if (debug_info->HasDebugCode()) {
843 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) { 841 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) {
844 if (returns_only && !it.GetBreakLocation().IsReturn()) continue; 842 if (returns_only && !it.GetBreakLocation().IsReturn()) continue;
845 it.SetDebugBreak(); 843 it.SetDebugBreak();
846 } 844 }
847 } 845 }
848 if (debug_info->HasDebugBytecodeArray()) { 846 if (debug_info->HasDebugBytecodeArray()) {
849 for (BytecodeArrayBreakIterator it(debug_info); !it.Done(); it.Next()) { 847 for (BytecodeArrayBreakIterator it(debug_info); !it.Done(); it.Next()) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return; 1022 return;
1025 } 1023 }
1026 1024
1027 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 1025 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
1028 DCHECK(js_frame->function()->IsJSFunction()); 1026 DCHECK(js_frame->function()->IsJSFunction());
1029 1027
1030 // Get the debug info (create it if it does not exist). 1028 // Get the debug info (create it if it does not exist).
1031 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); 1029 auto summary = FrameSummary::GetTop(frame).AsJavaScript();
1032 Handle<JSFunction> function(summary.function()); 1030 Handle<JSFunction> function(summary.function());
1033 Handle<SharedFunctionInfo> shared(function->shared()); 1031 Handle<SharedFunctionInfo> shared(function->shared());
1034 if (!EnsureDebugInfo(shared)) return; 1032 if (!EnsureBreakInfo(shared)) return;
1035 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1033 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1036 1034
1037 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame); 1035 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame);
1038 1036
1039 // Any step at a return is a step-out and we need to schedule DebugOnFunction 1037 // Any step at a return is a step-out and we need to schedule DebugOnFunction
1040 // call callback. 1038 // call callback.
1041 if (location.IsReturn()) { 1039 if (location.IsReturn()) {
1042 // On StepOut we'll ignore our further calls to current function in 1040 // On StepOut we'll ignore our further calls to current function in
1043 // PrepareStepIn callback. 1041 // PrepareStepIn callback.
1044 if (last_step_action() == StepOut) { 1042 if (last_step_action() == StepOut) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 FloodWithOneShot(shared); 1112 FloodWithOneShot(shared);
1115 break; 1113 break;
1116 } 1114 }
1117 } 1115 }
1118 1116
1119 // Simple function for returning the source positions for active break points. 1117 // Simple function for returning the source positions for active break points.
1120 Handle<Object> Debug::GetSourceBreakLocations( 1118 Handle<Object> Debug::GetSourceBreakLocations(
1121 Handle<SharedFunctionInfo> shared, 1119 Handle<SharedFunctionInfo> shared,
1122 BreakPositionAlignment position_alignment) { 1120 BreakPositionAlignment position_alignment) {
1123 Isolate* isolate = shared->GetIsolate(); 1121 Isolate* isolate = shared->GetIsolate();
1124 if (!shared->HasDebugInfo()) { 1122 if (!shared->HasBreakInfo()) {
1125 return isolate->factory()->undefined_value(); 1123 return isolate->factory()->undefined_value();
1126 } 1124 }
1127 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1125 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1128 if (debug_info->GetBreakPointCount() == 0) { 1126 if (debug_info->GetBreakPointCount() == 0) {
1129 return isolate->factory()->undefined_value(); 1127 return isolate->factory()->undefined_value();
1130 } 1128 }
1131 Handle<FixedArray> locations = 1129 Handle<FixedArray> locations =
1132 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); 1130 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1133 int count = 0; 1131 int count = 0;
1134 for (int i = 0; i < debug_info->break_points()->length(); ++i) { 1132 for (int i = 0; i < debug_info->break_points()->length(); ++i) {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 int end_position, bool restrict_to_function, 1390 int end_position, bool restrict_to_function,
1393 std::vector<BreakLocation>* locations) { 1391 std::vector<BreakLocation>* locations) {
1394 if (restrict_to_function) { 1392 if (restrict_to_function) {
1395 Handle<Object> result = 1393 Handle<Object> result =
1396 FindSharedFunctionInfoInScript(script, start_position); 1394 FindSharedFunctionInfoInScript(script, start_position);
1397 if (result->IsUndefined(isolate_)) return false; 1395 if (result->IsUndefined(isolate_)) return false;
1398 1396
1399 // Make sure the function has set up the debug info. 1397 // Make sure the function has set up the debug info.
1400 Handle<SharedFunctionInfo> shared = 1398 Handle<SharedFunctionInfo> shared =
1401 Handle<SharedFunctionInfo>::cast(result); 1399 Handle<SharedFunctionInfo>::cast(result);
1402 if (!EnsureDebugInfo(shared)) return false; 1400 if (!EnsureBreakInfo(shared)) return false;
1403 1401
1404 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1402 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1405 FindBreakablePositions(debug_info, start_position, end_position, locations); 1403 FindBreakablePositions(debug_info, start_position, end_position, locations);
1406 return true; 1404 return true;
1407 } 1405 }
1408 1406
1409 while (true) { 1407 while (true) {
1410 HandleScope scope(isolate_); 1408 HandleScope scope(isolate_);
1411 List<Handle<SharedFunctionInfo>> candidates; 1409 List<Handle<SharedFunctionInfo>> candidates;
1412 SharedFunctionInfo::ScriptIterator iterator(script); 1410 SharedFunctionInfo::ScriptIterator iterator(script);
(...skipping 12 matching lines...) Expand all
1425 for (int i = 0; i < candidates.length(); ++i) { 1423 for (int i = 0; i < candidates.length(); ++i) {
1426 // Code that cannot be compiled lazily are internal and not debuggable. 1424 // Code that cannot be compiled lazily are internal and not debuggable.
1427 DCHECK(candidates[i]->allows_lazy_compilation()); 1425 DCHECK(candidates[i]->allows_lazy_compilation());
1428 if (!candidates[i]->HasDebugCode()) { 1426 if (!candidates[i]->HasDebugCode()) {
1429 if (!Compiler::CompileDebugCode(candidates[i])) { 1427 if (!Compiler::CompileDebugCode(candidates[i])) {
1430 return false; 1428 return false;
1431 } else { 1429 } else {
1432 was_compiled = true; 1430 was_compiled = true;
1433 } 1431 }
1434 } 1432 }
1435 if (!EnsureDebugInfo(candidates[i])) return false; 1433 if (!EnsureBreakInfo(candidates[i])) return false;
1436 } 1434 }
1437 if (was_compiled) continue; 1435 if (was_compiled) continue;
1438 1436
1439 for (int i = 0; i < candidates.length(); ++i) { 1437 for (int i = 0; i < candidates.length(); ++i) {
1440 CHECK(candidates[i]->HasDebugInfo()); 1438 CHECK(candidates[i]->HasBreakInfo());
1441 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo()); 1439 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo());
1442 FindBreakablePositions(debug_info, start_position, end_position, 1440 FindBreakablePositions(debug_info, start_position, end_position,
1443 locations); 1441 locations);
1444 } 1442 }
1445 return true; 1443 return true;
1446 } 1444 }
1447 UNREACHABLE(); 1445 UNREACHABLE();
1448 } 1446 }
1449 1447
1450 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) { 1448 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 if (shared == NULL) break; 1535 if (shared == NULL) break;
1538 // We found it if it's already compiled and has debug code. 1536 // We found it if it's already compiled and has debug code.
1539 if (shared->HasDebugCode()) { 1537 if (shared->HasDebugCode()) {
1540 Handle<SharedFunctionInfo> shared_handle(shared); 1538 Handle<SharedFunctionInfo> shared_handle(shared);
1541 // If the iteration count is larger than 1, we had to compile the outer 1539 // If the iteration count is larger than 1, we had to compile the outer
1542 // function in order to create this shared function info. So there can 1540 // function in order to create this shared function info. So there can
1543 // be no JSFunction referencing it. We can anticipate creating a debug 1541 // be no JSFunction referencing it. We can anticipate creating a debug
1544 // info while bypassing PrepareFunctionForBreakpoints. 1542 // info while bypassing PrepareFunctionForBreakpoints.
1545 if (iteration > 1) { 1543 if (iteration > 1) {
1546 AllowHeapAllocation allow_before_return; 1544 AllowHeapAllocation allow_before_return;
1547 CreateDebugInfo(shared_handle); 1545 CreateBreakInfo(shared_handle);
1548 } 1546 }
1549 return shared_handle; 1547 return shared_handle;
1550 } 1548 }
1551 } 1549 }
1552 // If not, compile to reveal inner functions. 1550 // If not, compile to reveal inner functions.
1553 HandleScope scope(isolate_); 1551 HandleScope scope(isolate_);
1554 // Code that cannot be compiled lazily are internal and not debuggable. 1552 // Code that cannot be compiled lazily are internal and not debuggable.
1555 DCHECK(shared->allows_lazy_compilation()); 1553 DCHECK(shared->allows_lazy_compilation());
1556 if (!Compiler::CompileDebugCode(handle(shared))) break; 1554 if (!Compiler::CompileDebugCode(handle(shared))) break;
1557 } 1555 }
1558 return isolate_->factory()->undefined_value(); 1556 return isolate_->factory()->undefined_value();
1559 } 1557 }
1560 1558
1561 1559
1562 // Ensures the debug information is present for shared. 1560 // Ensures the debug information is present for shared.
1563 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { 1561 bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) {
1564 // Return if we already have the debug info for shared. 1562 // Return if we already have the break info for shared.
1565 if (shared->HasDebugInfo()) return true; 1563 if (shared->HasBreakInfo()) return true;
1566 if (!shared->IsSubjectToDebugging()) return false; 1564 if (!shared->IsSubjectToDebugging()) return false;
1567 if (!shared->is_compiled() && !Compiler::CompileDebugCode(shared)) { 1565 if (!shared->is_compiled() && !Compiler::CompileDebugCode(shared)) {
1568 return false; 1566 return false;
1569 } 1567 }
1570 1568
1571 // To prepare bytecode for debugging, we already need to have the debug 1569 // To prepare bytecode for debugging, we already need to have the debug
1572 // info (containing the debug copy) upfront, but since we do not recompile, 1570 // info (containing the debug copy) upfront, but since we do not recompile,
1573 // preparing for break points cannot fail. 1571 // preparing for break points cannot fail.
1574 CreateDebugInfo(shared); 1572 CreateBreakInfo(shared);
1575 CHECK(PrepareFunctionForBreakPoints(shared)); 1573 CHECK(PrepareFunctionForBreakPoints(shared));
1576 return true; 1574 return true;
1577 } 1575 }
1578 1576
1577 void Debug::CreateBreakInfo(Handle<SharedFunctionInfo> shared) {
1578 HandleScope scope(isolate_);
1579 Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
1579 1580
1580 void Debug::CreateDebugInfo(Handle<SharedFunctionInfo> shared) { 1581 // Initialize with break information.
1581 // Create the debug info object. 1582
1583 DCHECK(!debug_info->HasBreakInfo());
1584
1585 Factory* factory = isolate_->factory();
1586 Handle<FixedArray> break_points(
1587 factory->NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction));
1588
1589 // Make a copy of the bytecode array if available.
1590 Handle<Object> maybe_debug_bytecode_array = factory->undefined_value();
1591 if (shared->HasBytecodeArray()) {
1592 Handle<BytecodeArray> original(shared->bytecode_array());
1593 maybe_debug_bytecode_array = factory->CopyBytecodeArray(original);
1594 }
1595
1596 debug_info->set_flags(debug_info->flags() | DebugInfo::kHasBreakInfo);
1597 debug_info->set_debug_bytecode_array(*maybe_debug_bytecode_array);
1598 debug_info->set_break_points(*break_points);
1599 }
1600
1601 Handle<DebugInfo> Debug::GetOrCreateDebugInfo(
1602 Handle<SharedFunctionInfo> shared) {
1603 if (shared->HasDebugInfo()) return handle(shared->GetDebugInfo());
1604
1605 // Create debug info and add it to the list.
1582 Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared); 1606 Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
1583
1584 // Add debug info to the list.
1585 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 1607 DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1586 node->set_next(debug_info_list_); 1608 node->set_next(debug_info_list_);
1587 debug_info_list_ = node; 1609 debug_info_list_ = node;
1610
1611 return debug_info;
1588 } 1612 }
1589 1613
1590 1614 void Debug::FindDebugInfo(Handle<DebugInfo> debug_info,
1591 void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) { 1615 DebugInfoListNode** prev, DebugInfoListNode** curr) {
1592 HandleScope scope(isolate_); 1616 HandleScope scope(isolate_);
1593 Handle<SharedFunctionInfo> shared(debug_info->shared()); 1617 *prev = nullptr;
1594 1618 *curr = debug_info_list_;
1595 DCHECK_NOT_NULL(debug_info_list_); 1619 while (*curr != nullptr) {
1596 // Run through the debug info objects to find this one and remove it. 1620 if ((*curr)->debug_info().is_identical_to(debug_info)) return;
1597 DebugInfoListNode* prev = NULL; 1621 *prev = *curr;
1598 DebugInfoListNode* current = debug_info_list_; 1622 *curr = (*curr)->next();
1599 while (current != NULL) {
1600 if (current->debug_info().is_identical_to(debug_info)) {
1601 // Unlink from list. If prev is NULL we are looking at the first element.
1602 if (prev == NULL) {
1603 debug_info_list_ = current->next();
1604 } else {
1605 prev->set_next(current->next());
1606 }
1607 shared->set_debug_info(Smi::FromInt(debug_info->debugger_hints()));
1608 delete current;
1609 return;
1610 }
1611 // Move to next in list.
1612 prev = current;
1613 current = current->next();
1614 } 1623 }
1615 1624
1616 UNREACHABLE(); 1625 UNREACHABLE();
1617 } 1626 }
1618 1627
1628 void Debug::RemoveBreakInfoAndMaybeFree(Handle<DebugInfo> debug_info) {
1629 HandleScope scope(isolate_);
1630 Handle<SharedFunctionInfo> shared(debug_info->shared());
1631
1632 bool should_unlink = debug_info->ClearBreakInfo();
1633 if (should_unlink) {
1634 // Unlink from list. If prev is NULL we are looking at the first element.
1635 DebugInfoListNode* prev;
1636 DebugInfoListNode* curr;
1637 FindDebugInfo(debug_info, &prev, &curr);
1638
1639 if (prev == nullptr) {
1640 debug_info_list_ = curr->next();
1641 } else {
1642 prev->set_next(curr->next());
1643 }
1644 shared->set_debug_info(Smi::FromInt(debug_info->debugger_hints()));
1645 delete curr;
1646 }
1647 }
1648
1619 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 1649 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1620 HandleScope scope(isolate_); 1650 HandleScope scope(isolate_);
1621 1651
1622 // Get the executing function in which the debug break occurred. 1652 // Get the executing function in which the debug break occurred.
1623 Handle<SharedFunctionInfo> shared(frame->function()->shared()); 1653 Handle<SharedFunctionInfo> shared(frame->function()->shared());
1624 1654
1625 // With no debug info there are no break points, so we can't be at a return. 1655 // With no debug info there are no break points, so we can't be at a return.
1626 if (!shared->HasDebugInfo()) return false; 1656 if (!shared->HasBreakInfo()) return false;
1627 1657
1628 DCHECK(!frame->is_optimized()); 1658 DCHECK(!frame->is_optimized());
1629 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1659 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1630 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 1660 BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
1631 return location.IsReturn() || location.IsTailCall(); 1661 return location.IsReturn() || location.IsTailCall();
1632 } 1662 }
1633 1663
1634 void Debug::ScheduleFrameRestart(StackFrame* frame) { 1664 void Debug::ScheduleFrameRestart(StackFrame* frame) {
1635 // Set a target FP for the FrameDropperTrampoline builtin to drop to once 1665 // Set a target FP for the FrameDropperTrampoline builtin to drop to once
1636 // we return from the debugger. 1666 // we return from the debugger.
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 isolate_->Throw(*isolate_->factory()->NewEvalError( 2478 isolate_->Throw(*isolate_->factory()->NewEvalError(
2449 MessageTemplate::kNoSideEffectDebugEvaluate)); 2479 MessageTemplate::kNoSideEffectDebugEvaluate));
2450 } 2480 }
2451 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); 2481 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_);
2452 isolate_->debug()->UpdateHookOnFunctionCall(); 2482 isolate_->debug()->UpdateHookOnFunctionCall();
2453 isolate_->debug()->side_effect_check_failed_ = false; 2483 isolate_->debug()->side_effect_check_failed_ = false;
2454 } 2484 }
2455 2485
2456 } // namespace internal 2486 } // namespace internal
2457 } // namespace v8 2487 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-scopes.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698