| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/debugger.h" | 5 #include "vm/debugger.h" |
| 6 | 6 |
| 7 #include "vm/code_index_table.h" | 7 #include "vm/code_index_table.h" |
| 8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // Compute line number lazily since it causes scanning of the script. | 66 // Compute line number lazily since it causes scanning of the script. |
| 67 if (line_number_ < 0) { | 67 if (line_number_ < 0) { |
| 68 const Script& script = Script::Handle(SourceCode()); | 68 const Script& script = Script::Handle(SourceCode()); |
| 69 intptr_t ignore_column; | 69 intptr_t ignore_column; |
| 70 script.GetTokenLocation(token_index_, &line_number_, &ignore_column); | 70 script.GetTokenLocation(token_index_, &line_number_, &ignore_column); |
| 71 } | 71 } |
| 72 return line_number_; | 72 return line_number_; |
| 73 } | 73 } |
| 74 | 74 |
| 75 | 75 |
| 76 void SourceBreakpoint::set_function(const Function& func) { |
| 77 function_ = func.raw(); |
| 78 } |
| 79 |
| 80 |
| 76 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 81 void SourceBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 77 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 82 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
| 78 } | 83 } |
| 79 | 84 |
| 80 | 85 |
| 81 | 86 |
| 82 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 87 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 83 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); | 88 visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |
| 84 } | 89 } |
| 85 | 90 |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 SetBreakpointHandler(DefaultBreakpointHandler); | 934 SetBreakpointHandler(DefaultBreakpointHandler); |
| 930 } | 935 } |
| 931 | 936 |
| 932 | 937 |
| 933 void Debugger::NotifyCompilation(const Function& func) { | 938 void Debugger::NotifyCompilation(const Function& func) { |
| 934 if (src_breakpoints_ == NULL) { | 939 if (src_breakpoints_ == NULL) { |
| 935 // Return with minimal overhead if there are no breakpoints. | 940 // Return with minimal overhead if there are no breakpoints. |
| 936 return; | 941 return; |
| 937 } | 942 } |
| 938 Function& lookup_function = Function::Handle(func.raw()); | 943 Function& lookup_function = Function::Handle(func.raw()); |
| 939 if (func.IsClosureFunction()) { | 944 if (func.IsImplicitClosureFunction()) { |
| 940 // If the newly compiled function is a closure, we need to use | 945 // If the newly compiled function is a an implicit closure (a closure that |
| 941 // the closure's parent function to see whether there are any | 946 // was formed by assigning a static or instance method to a function |
| 942 // breakpoints. | 947 // object), we need to use the closure's parent function to see whether |
| 948 // there are any breakpoints. The parent function is the actual method on |
| 949 // which the user sets breakpoints. |
| 943 lookup_function = func.parent_function(); | 950 lookup_function = func.parent_function(); |
| 951 ASSERT(!lookup_function.IsNull()); |
| 944 } | 952 } |
| 945 SourceBreakpoint* bpt = src_breakpoints_; | 953 SourceBreakpoint* bpt = src_breakpoints_; |
| 946 while (bpt != NULL) { | 954 while (bpt != NULL) { |
| 947 if (lookup_function.raw() == bpt->function()) { | 955 if (lookup_function.raw() == bpt->function()) { |
| 948 if (verbose) { | 956 // Check if the breakpoint is inside a closure or local function |
| 949 OS::Print("Enable latent breakpoint for function '%s'\n", | 957 // within the newly compiled function. |
| 950 String::Handle(lookup_function.name()).ToCString()); | 958 Class& owner = Class::Handle(lookup_function.owner()); |
| 951 } | 959 Function& closure = |
| 952 // Set breakpoint in newly compiled code of function func. | 960 Function::Handle(owner.LookupClosureFunction(bpt->token_index())); |
| 953 CodeBreakpoint* cbpt = MakeCodeBreakpoint(func, bpt->token_index()); | 961 if (!closure.IsNull() && (closure.raw() != lookup_function.raw())) { |
| 954 if (cbpt != NULL) { | 962 if (verbose) { |
| 955 cbpt->set_src_bpt(bpt); | 963 OS::Print("Resetting pending breakpoint to function %s\n", |
| 964 String::Handle(closure.name()).ToCString()); |
| 965 } |
| 966 bpt->set_function(closure); |
| 967 } else { |
| 968 if (verbose) { |
| 969 OS::Print("Enable pending breakpoint for function '%s'\n", |
| 970 String::Handle(lookup_function.name()).ToCString()); |
| 971 } |
| 972 // Set breakpoint in newly compiled code of function func. |
| 973 CodeBreakpoint* cbpt = MakeCodeBreakpoint(func, bpt->token_index()); |
| 974 if (cbpt != NULL) { |
| 975 cbpt->set_src_bpt(bpt); |
| 976 } |
| 956 } | 977 } |
| 957 bpt->Enable(); // Enables the code breakpoint as well. | 978 bpt->Enable(); // Enables the code breakpoint as well. |
| 958 } | 979 } |
| 959 bpt = bpt->next(); | 980 bpt = bpt->next(); |
| 960 } | 981 } |
| 961 } | 982 } |
| 962 | 983 |
| 963 | 984 |
| 964 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) { | 985 CodeBreakpoint* Debugger::GetCodeBreakpoint(uword breakpoint_address) { |
| 965 CodeBreakpoint* bpt = code_breakpoints_; | 986 CodeBreakpoint* bpt = code_breakpoints_; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 } | 1071 } |
| 1051 | 1072 |
| 1052 | 1073 |
| 1053 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 1074 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 1054 ASSERT(bpt->next() == NULL); | 1075 ASSERT(bpt->next() == NULL); |
| 1055 bpt->set_next(code_breakpoints_); | 1076 bpt->set_next(code_breakpoints_); |
| 1056 code_breakpoints_ = bpt; | 1077 code_breakpoints_ = bpt; |
| 1057 } | 1078 } |
| 1058 | 1079 |
| 1059 } // namespace dart | 1080 } // namespace dart |
| OLD | NEW |