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

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

Issue 2909893002: [debug] Untangle DebugInfo from break point support (Closed)
Patch Set: Address comments 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
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-scopes.cc » ('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 "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* prev = nullptr;
826 node = node->next()) { 824 DebugInfoListNode* current = debug_info_list_;
827 ClearBreakPoints(node->debug_info()); 825 while (current != nullptr) {
828 } 826 DebugInfoListNode* next = current->next();
829 // Remove all debug info. 827 Handle<DebugInfo> debug_info = current->debug_info();
830 while (debug_info_list_ != NULL) { 828 ClearBreakPoints(debug_info);
831 RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info()); 829 if (debug_info->ClearBreakInfo()) {
830 FreeDebugInfoListNode(prev, current);
831 current = next;
832 } else {
833 prev = current;
834 current = next;
835 }
832 } 836 }
833 } 837 }
834 838
835 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared, 839 void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared,
836 bool returns_only) { 840 bool returns_only) {
837 if (IsBlackboxed(shared)) return; 841 if (IsBlackboxed(shared)) return;
838 // Make sure the function is compiled and has set up the debug info. 842 // Make sure the function is compiled and has set up the debug info.
839 if (!EnsureDebugInfo(shared)) return; 843 if (!EnsureBreakInfo(shared)) return;
840 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 844 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
841 // Flood the function with break points. 845 // Flood the function with break points.
842 if (debug_info->HasDebugCode()) { 846 if (debug_info->HasDebugCode()) {
843 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) { 847 for (CodeBreakIterator it(debug_info); !it.Done(); it.Next()) {
844 if (returns_only && !it.GetBreakLocation().IsReturn()) continue; 848 if (returns_only && !it.GetBreakLocation().IsReturn()) continue;
845 it.SetDebugBreak(); 849 it.SetDebugBreak();
846 } 850 }
847 } 851 }
848 if (debug_info->HasDebugBytecodeArray()) { 852 if (debug_info->HasDebugBytecodeArray()) {
849 for (BytecodeArrayBreakIterator it(debug_info); !it.Done(); it.Next()) { 853 for (BytecodeArrayBreakIterator it(debug_info); !it.Done(); it.Next()) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 return; 1028 return;
1025 } 1029 }
1026 1030
1027 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame); 1031 JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
1028 DCHECK(js_frame->function()->IsJSFunction()); 1032 DCHECK(js_frame->function()->IsJSFunction());
1029 1033
1030 // Get the debug info (create it if it does not exist). 1034 // Get the debug info (create it if it does not exist).
1031 auto summary = FrameSummary::GetTop(frame).AsJavaScript(); 1035 auto summary = FrameSummary::GetTop(frame).AsJavaScript();
1032 Handle<JSFunction> function(summary.function()); 1036 Handle<JSFunction> function(summary.function());
1033 Handle<SharedFunctionInfo> shared(function->shared()); 1037 Handle<SharedFunctionInfo> shared(function->shared());
1034 if (!EnsureDebugInfo(shared)) return; 1038 if (!EnsureBreakInfo(shared)) return;
1035 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1039 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1036 1040
1037 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame); 1041 BreakLocation location = BreakLocation::FromFrame(debug_info, js_frame);
1038 1042
1039 // Any step at a return is a step-out and we need to schedule DebugOnFunction 1043 // Any step at a return is a step-out and we need to schedule DebugOnFunction
1040 // call callback. 1044 // call callback.
1041 if (location.IsReturn()) { 1045 if (location.IsReturn()) {
1042 // On StepOut we'll ignore our further calls to current function in 1046 // On StepOut we'll ignore our further calls to current function in
1043 // PrepareStepIn callback. 1047 // PrepareStepIn callback.
1044 if (last_step_action() == StepOut) { 1048 if (last_step_action() == StepOut) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 FloodWithOneShot(shared); 1118 FloodWithOneShot(shared);
1115 break; 1119 break;
1116 } 1120 }
1117 } 1121 }
1118 1122
1119 // Simple function for returning the source positions for active break points. 1123 // Simple function for returning the source positions for active break points.
1120 Handle<Object> Debug::GetSourceBreakLocations( 1124 Handle<Object> Debug::GetSourceBreakLocations(
1121 Handle<SharedFunctionInfo> shared, 1125 Handle<SharedFunctionInfo> shared,
1122 BreakPositionAlignment position_alignment) { 1126 BreakPositionAlignment position_alignment) {
1123 Isolate* isolate = shared->GetIsolate(); 1127 Isolate* isolate = shared->GetIsolate();
1124 if (!shared->HasDebugInfo()) { 1128 if (!shared->HasBreakInfo()) {
1125 return isolate->factory()->undefined_value(); 1129 return isolate->factory()->undefined_value();
1126 } 1130 }
1127 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1131 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1128 if (debug_info->GetBreakPointCount() == 0) { 1132 if (debug_info->GetBreakPointCount() == 0) {
1129 return isolate->factory()->undefined_value(); 1133 return isolate->factory()->undefined_value();
1130 } 1134 }
1131 Handle<FixedArray> locations = 1135 Handle<FixedArray> locations =
1132 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount()); 1136 isolate->factory()->NewFixedArray(debug_info->GetBreakPointCount());
1133 int count = 0; 1137 int count = 0;
1134 for (int i = 0; i < debug_info->break_points()->length(); ++i) { 1138 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, 1396 int end_position, bool restrict_to_function,
1393 std::vector<BreakLocation>* locations) { 1397 std::vector<BreakLocation>* locations) {
1394 if (restrict_to_function) { 1398 if (restrict_to_function) {
1395 Handle<Object> result = 1399 Handle<Object> result =
1396 FindSharedFunctionInfoInScript(script, start_position); 1400 FindSharedFunctionInfoInScript(script, start_position);
1397 if (result->IsUndefined(isolate_)) return false; 1401 if (result->IsUndefined(isolate_)) return false;
1398 1402
1399 // Make sure the function has set up the debug info. 1403 // Make sure the function has set up the debug info.
1400 Handle<SharedFunctionInfo> shared = 1404 Handle<SharedFunctionInfo> shared =
1401 Handle<SharedFunctionInfo>::cast(result); 1405 Handle<SharedFunctionInfo>::cast(result);
1402 if (!EnsureDebugInfo(shared)) return false; 1406 if (!EnsureBreakInfo(shared)) return false;
1403 1407
1404 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1408 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1405 FindBreakablePositions(debug_info, start_position, end_position, locations); 1409 FindBreakablePositions(debug_info, start_position, end_position, locations);
1406 return true; 1410 return true;
1407 } 1411 }
1408 1412
1409 while (true) { 1413 while (true) {
1410 HandleScope scope(isolate_); 1414 HandleScope scope(isolate_);
1411 List<Handle<SharedFunctionInfo>> candidates; 1415 List<Handle<SharedFunctionInfo>> candidates;
1412 SharedFunctionInfo::ScriptIterator iterator(script); 1416 SharedFunctionInfo::ScriptIterator iterator(script);
(...skipping 12 matching lines...) Expand all
1425 for (int i = 0; i < candidates.length(); ++i) { 1429 for (int i = 0; i < candidates.length(); ++i) {
1426 // Code that cannot be compiled lazily are internal and not debuggable. 1430 // Code that cannot be compiled lazily are internal and not debuggable.
1427 DCHECK(candidates[i]->allows_lazy_compilation()); 1431 DCHECK(candidates[i]->allows_lazy_compilation());
1428 if (!candidates[i]->HasDebugCode()) { 1432 if (!candidates[i]->HasDebugCode()) {
1429 if (!Compiler::CompileDebugCode(candidates[i])) { 1433 if (!Compiler::CompileDebugCode(candidates[i])) {
1430 return false; 1434 return false;
1431 } else { 1435 } else {
1432 was_compiled = true; 1436 was_compiled = true;
1433 } 1437 }
1434 } 1438 }
1435 if (!EnsureDebugInfo(candidates[i])) return false; 1439 if (!EnsureBreakInfo(candidates[i])) return false;
1436 } 1440 }
1437 if (was_compiled) continue; 1441 if (was_compiled) continue;
1438 1442
1439 for (int i = 0; i < candidates.length(); ++i) { 1443 for (int i = 0; i < candidates.length(); ++i) {
1440 CHECK(candidates[i]->HasDebugInfo()); 1444 CHECK(candidates[i]->HasBreakInfo());
1441 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo()); 1445 Handle<DebugInfo> debug_info(candidates[i]->GetDebugInfo());
1442 FindBreakablePositions(debug_info, start_position, end_position, 1446 FindBreakablePositions(debug_info, start_position, end_position,
1443 locations); 1447 locations);
1444 } 1448 }
1445 return true; 1449 return true;
1446 } 1450 }
1447 UNREACHABLE(); 1451 UNREACHABLE();
1448 } 1452 }
1449 1453
1450 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) { 1454 void Debug::RecordGenerator(Handle<JSGeneratorObject> generator_object) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 if (shared == NULL) break; 1541 if (shared == NULL) break;
1538 // We found it if it's already compiled and has debug code. 1542 // We found it if it's already compiled and has debug code.
1539 if (shared->HasDebugCode()) { 1543 if (shared->HasDebugCode()) {
1540 Handle<SharedFunctionInfo> shared_handle(shared); 1544 Handle<SharedFunctionInfo> shared_handle(shared);
1541 // If the iteration count is larger than 1, we had to compile the outer 1545 // 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 1546 // function in order to create this shared function info. So there can
1543 // be no JSFunction referencing it. We can anticipate creating a debug 1547 // be no JSFunction referencing it. We can anticipate creating a debug
1544 // info while bypassing PrepareFunctionForBreakpoints. 1548 // info while bypassing PrepareFunctionForBreakpoints.
1545 if (iteration > 1) { 1549 if (iteration > 1) {
1546 AllowHeapAllocation allow_before_return; 1550 AllowHeapAllocation allow_before_return;
1547 CreateDebugInfo(shared_handle); 1551 CreateBreakInfo(shared_handle);
1548 } 1552 }
1549 return shared_handle; 1553 return shared_handle;
1550 } 1554 }
1551 } 1555 }
1552 // If not, compile to reveal inner functions. 1556 // If not, compile to reveal inner functions.
1553 HandleScope scope(isolate_); 1557 HandleScope scope(isolate_);
1554 // Code that cannot be compiled lazily are internal and not debuggable. 1558 // Code that cannot be compiled lazily are internal and not debuggable.
1555 DCHECK(shared->allows_lazy_compilation()); 1559 DCHECK(shared->allows_lazy_compilation());
1556 if (!Compiler::CompileDebugCode(handle(shared))) break; 1560 if (!Compiler::CompileDebugCode(handle(shared))) break;
1557 } 1561 }
1558 return isolate_->factory()->undefined_value(); 1562 return isolate_->factory()->undefined_value();
1559 } 1563 }
1560 1564
1561 1565
1562 // Ensures the debug information is present for shared. 1566 // Ensures the debug information is present for shared.
1563 bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { 1567 bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) {
1564 // Return if we already have the debug info for shared. 1568 // Return if we already have the break info for shared.
1565 if (shared->HasDebugInfo()) return true; 1569 if (shared->HasBreakInfo()) return true;
1566 if (!shared->IsSubjectToDebugging()) return false; 1570 if (!shared->IsSubjectToDebugging()) return false;
1567 if (!shared->is_compiled() && !Compiler::CompileDebugCode(shared)) { 1571 if (!shared->is_compiled() && !Compiler::CompileDebugCode(shared)) {
1568 return false; 1572 return false;
1569 } 1573 }
1570 1574
1571 // To prepare bytecode for debugging, we already need to have the debug 1575 // 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, 1576 // info (containing the debug copy) upfront, but since we do not recompile,
1573 // preparing for break points cannot fail. 1577 // preparing for break points cannot fail.
1574 CreateDebugInfo(shared); 1578 CreateBreakInfo(shared);
1575 CHECK(PrepareFunctionForBreakPoints(shared)); 1579 CHECK(PrepareFunctionForBreakPoints(shared));
1576 return true; 1580 return true;
1577 } 1581 }
1578 1582
1583 void Debug::CreateBreakInfo(Handle<SharedFunctionInfo> shared) {
1584 HandleScope scope(isolate_);
1585 Handle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
1579 1586
1580 void Debug::CreateDebugInfo(Handle<SharedFunctionInfo> shared) { 1587 // Initialize with break information.
1581 // Create the debug info object. 1588
1589 DCHECK(!debug_info->HasBreakInfo());
1590
1591 Factory* factory = isolate_->factory();
1592 Handle<FixedArray> break_points(
1593 factory->NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction));
1594
1595 // Make a copy of the bytecode array if available.
1596 Handle<Object> maybe_debug_bytecode_array = factory->undefined_value();
1597 if (shared->HasBytecodeArray()) {
1598 Handle<BytecodeArray> original(shared->bytecode_array());
1599 maybe_debug_bytecode_array = factory->CopyBytecodeArray(original);
1600 }
1601
1602 debug_info->set_flags(debug_info->flags() | DebugInfo::kHasBreakInfo);
1603 debug_info->set_debug_bytecode_array(*maybe_debug_bytecode_array);
1604 debug_info->set_break_points(*break_points);
1605 }
1606
1607 Handle<DebugInfo> Debug::GetOrCreateDebugInfo(
1608 Handle<SharedFunctionInfo> shared) {
1609 if (shared->HasDebugInfo()) return handle(shared->GetDebugInfo());
1610
1611 // Create debug info and add it to the list.
1582 Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared); 1612 Handle<DebugInfo> debug_info = isolate_->factory()->NewDebugInfo(shared);
1583
1584 // Add debug info to the list.
1585 DebugInfoListNode* node = new DebugInfoListNode(*debug_info); 1613 DebugInfoListNode* node = new DebugInfoListNode(*debug_info);
1586 node->set_next(debug_info_list_); 1614 node->set_next(debug_info_list_);
1587 debug_info_list_ = node; 1615 debug_info_list_ = node;
1616
1617 return debug_info;
1588 } 1618 }
1589 1619
1590 1620 void Debug::FindDebugInfo(Handle<DebugInfo> debug_info,
1591 void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) { 1621 DebugInfoListNode** prev, DebugInfoListNode** curr) {
1592 HandleScope scope(isolate_); 1622 HandleScope scope(isolate_);
1593 Handle<SharedFunctionInfo> shared(debug_info->shared()); 1623 *prev = nullptr;
1594 1624 *curr = debug_info_list_;
1595 DCHECK_NOT_NULL(debug_info_list_); 1625 while (*curr != nullptr) {
1596 // Run through the debug info objects to find this one and remove it. 1626 if ((*curr)->debug_info().is_identical_to(debug_info)) return;
1597 DebugInfoListNode* prev = NULL; 1627 *prev = *curr;
1598 DebugInfoListNode* current = debug_info_list_; 1628 *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 } 1629 }
1615 1630
1616 UNREACHABLE(); 1631 UNREACHABLE();
1617 } 1632 }
1618 1633
1634 void Debug::RemoveBreakInfoAndMaybeFree(Handle<DebugInfo> debug_info) {
1635 bool should_unlink = debug_info->ClearBreakInfo();
1636 if (should_unlink) {
1637 DebugInfoListNode* prev;
1638 DebugInfoListNode* node;
1639 FindDebugInfo(debug_info, &prev, &node);
1640 FreeDebugInfoListNode(prev, node);
1641 }
1642 }
1643
1644 void Debug::FreeDebugInfoListNode(DebugInfoListNode* prev,
1645 DebugInfoListNode* node) {
1646 DCHECK(node->debug_info()->IsEmpty());
1647
1648 // Unlink from list. If prev is NULL we are looking at the first element.
1649 if (prev == nullptr) {
1650 debug_info_list_ = node->next();
1651 } else {
1652 prev->set_next(node->next());
1653 }
1654
1655 // Pack debugger hints back into the SFI::debug_info field.
1656 Handle<DebugInfo> debug_info(node->debug_info());
1657 debug_info->shared()->set_debug_info(
1658 Smi::FromInt(debug_info->debugger_hints()));
1659
1660 delete node;
1661 }
1662
1619 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) { 1663 bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
1620 HandleScope scope(isolate_); 1664 HandleScope scope(isolate_);
1621 1665
1622 // Get the executing function in which the debug break occurred. 1666 // Get the executing function in which the debug break occurred.
1623 Handle<SharedFunctionInfo> shared(frame->function()->shared()); 1667 Handle<SharedFunctionInfo> shared(frame->function()->shared());
1624 1668
1625 // With no debug info there are no break points, so we can't be at a return. 1669 // With no debug info there are no break points, so we can't be at a return.
1626 if (!shared->HasDebugInfo()) return false; 1670 if (!shared->HasBreakInfo()) return false;
1627 1671
1628 DCHECK(!frame->is_optimized()); 1672 DCHECK(!frame->is_optimized());
1629 Handle<DebugInfo> debug_info(shared->GetDebugInfo()); 1673 Handle<DebugInfo> debug_info(shared->GetDebugInfo());
1630 BreakLocation location = BreakLocation::FromFrame(debug_info, frame); 1674 BreakLocation location = BreakLocation::FromFrame(debug_info, frame);
1631 return location.IsReturn() || location.IsTailCall(); 1675 return location.IsReturn() || location.IsTailCall();
1632 } 1676 }
1633 1677
1634 void Debug::ScheduleFrameRestart(StackFrame* frame) { 1678 void Debug::ScheduleFrameRestart(StackFrame* frame) {
1635 // Set a target FP for the FrameDropperTrampoline builtin to drop to once 1679 // Set a target FP for the FrameDropperTrampoline builtin to drop to once
1636 // we return from the debugger. 1680 // we return from the debugger.
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 isolate_->Throw(*isolate_->factory()->NewEvalError( 2492 isolate_->Throw(*isolate_->factory()->NewEvalError(
2449 MessageTemplate::kNoSideEffectDebugEvaluate)); 2493 MessageTemplate::kNoSideEffectDebugEvaluate));
2450 } 2494 }
2451 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_); 2495 isolate_->set_needs_side_effect_check(old_needs_side_effect_check_);
2452 isolate_->debug()->UpdateHookOnFunctionCall(); 2496 isolate_->debug()->UpdateHookOnFunctionCall();
2453 isolate_->debug()->side_effect_check_failed_ = false; 2497 isolate_->debug()->side_effect_check_failed_ = false;
2454 } 2498 }
2455 2499
2456 } // namespace internal 2500 } // namespace internal
2457 } // namespace v8 2501 } // namespace v8
OLDNEW
« no previous file with comments | « src/debug/debug.h ('k') | src/debug/debug-scopes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698