| 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 "include/dart_api.h" | 7 #include "include/dart_api.h" |
| 8 | 8 |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| (...skipping 1158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 if (function.HasOptimizedCode()) { | 1169 if (function.HasOptimizedCode()) { |
| 1170 function.SwitchToUnoptimizedCode(); | 1170 function.SwitchToUnoptimizedCode(); |
| 1171 } | 1171 } |
| 1172 } | 1172 } |
| 1173 } | 1173 } |
| 1174 } | 1174 } |
| 1175 } | 1175 } |
| 1176 } | 1176 } |
| 1177 | 1177 |
| 1178 | 1178 |
| 1179 void Debugger::SetInternalBreakpoints(const Function& target_function) { | 1179 RawError* Debugger::SetInternalBreakpoints(const Function& target_function) { |
| 1180 if (target_function.is_native()) { | 1180 if (target_function.is_native()) { |
| 1181 // Can't instrument native functions. | 1181 // Can't instrument native functions. Fail silently. |
| 1182 return; | 1182 return Error::null(); |
| 1183 } | 1183 } |
| 1184 Isolate* isolate = Isolate::Current(); | 1184 Isolate* isolate = Isolate::Current(); |
| 1185 if (!target_function.HasCode()) { | 1185 if (!target_function.HasCode()) { |
| 1186 Compiler::CompileFunction(isolate, target_function); | 1186 const Error& error = Error::Handle( |
| 1187 // If there were any errors, ignore them silently and return without | 1187 Compiler::CompileFunction(isolate, target_function)); |
| 1188 // adding breakpoints to target. | 1188 if (!error.IsNull()) { |
| 1189 if (!target_function.HasCode()) { | 1189 return error.raw(); |
| 1190 return; | |
| 1191 } | 1190 } |
| 1192 } | 1191 } |
| 1193 // Hang on to the code object before deoptimizing, in case deoptimization | 1192 // Hang on to the code object before deoptimizing, in case deoptimization |
| 1194 // might cause the GC to run. | 1193 // might cause the GC to run. |
| 1195 Code& code = Code::Handle(isolate, target_function.unoptimized_code()); | 1194 Code& code = Code::Handle(isolate, target_function.unoptimized_code()); |
| 1196 ASSERT(!code.IsNull()); | 1195 ASSERT(!code.IsNull()); |
| 1197 DeoptimizeWorld(); | 1196 DeoptimizeWorld(); |
| 1198 ASSERT(!target_function.HasOptimizedCode()); | 1197 ASSERT(!target_function.HasOptimizedCode()); |
| 1199 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors()); | 1198 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors()); |
| 1200 PcDescriptors::Iterator iter(desc, kSafepointKind); | 1199 PcDescriptors::Iterator iter(desc, kSafepointKind); |
| 1201 while (iter.MoveNext()) { | 1200 while (iter.MoveNext()) { |
| 1202 if (iter.TokenPos() != Scanner::kNoSourcePos) { | 1201 if (iter.TokenPos() != Scanner::kNoSourcePos) { |
| 1203 CodeBreakpoint* bpt = GetCodeBreakpoint(iter.Pc()); | 1202 CodeBreakpoint* bpt = GetCodeBreakpoint(iter.Pc()); |
| 1204 if (bpt != NULL) { | 1203 if (bpt != NULL) { |
| 1205 // There is already a breakpoint for this address. Make sure | 1204 // There is already a breakpoint for this address. Make sure |
| 1206 // it is enabled. | 1205 // it is enabled. |
| 1207 bpt->Enable(); | 1206 bpt->Enable(); |
| 1208 continue; | 1207 continue; |
| 1209 } | 1208 } |
| 1210 bpt = new CodeBreakpoint(code, iter.TokenPos(), | 1209 bpt = new CodeBreakpoint(code, iter.TokenPos(), |
| 1211 iter.Pc(), iter.Kind()); | 1210 iter.Pc(), iter.Kind()); |
| 1212 RegisterCodeBreakpoint(bpt); | 1211 RegisterCodeBreakpoint(bpt); |
| 1213 bpt->Enable(); | 1212 bpt->Enable(); |
| 1214 } | 1213 } |
| 1215 } | 1214 } |
| 1215 return Error::null(); |
| 1216 } | 1216 } |
| 1217 | 1217 |
| 1218 | 1218 |
| 1219 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 1219 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { |
| 1220 if (HasEventHandler()) { | 1220 if (HasEventHandler()) { |
| 1221 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved); | 1221 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved); |
| 1222 event.set_breakpoint(bpt); | 1222 event.set_breakpoint(bpt); |
| 1223 InvokeEventHandler(&event); | 1223 InvokeEventHandler(&event); |
| 1224 } | 1224 } |
| 1225 } | 1225 } |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1865 cbpt->Enable(); | 1865 cbpt->Enable(); |
| 1866 } else { | 1866 } else { |
| 1867 cbpt->Disable(); | 1867 cbpt->Disable(); |
| 1868 } | 1868 } |
| 1869 } | 1869 } |
| 1870 cbpt = cbpt->next(); | 1870 cbpt = cbpt->next(); |
| 1871 } | 1871 } |
| 1872 } | 1872 } |
| 1873 | 1873 |
| 1874 | 1874 |
| 1875 void Debugger::OneTimeBreakAtEntry(const Function& target_function) { | 1875 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) { |
| 1876 SetInternalBreakpoints(target_function); | 1876 Error& err = Error::Handle(); |
| 1877 if (target_function.HasImplicitClosureFunction()) { | 1877 err = SetInternalBreakpoints(target_function); |
| 1878 if (err.IsNull() && target_function.HasImplicitClosureFunction()) { |
| 1878 const Function& closure_func = | 1879 const Function& closure_func = |
| 1879 Function::Handle(target_function.ImplicitClosureFunction()); | 1880 Function::Handle(target_function.ImplicitClosureFunction()); |
| 1880 SetInternalBreakpoints(closure_func); | 1881 err = SetInternalBreakpoints(closure_func); |
| 1881 } | 1882 } |
| 1883 return err.raw(); |
| 1882 } | 1884 } |
| 1883 | 1885 |
| 1884 | 1886 |
| 1885 SourceBreakpoint* Debugger::SetBreakpointAtEntry( | 1887 SourceBreakpoint* Debugger::SetBreakpointAtEntry( |
| 1886 const Function& target_function) { | 1888 const Function& target_function) { |
| 1887 ASSERT(!target_function.IsNull()); | 1889 ASSERT(!target_function.IsNull()); |
| 1888 const Script& script = Script::Handle(target_function.script()); | 1890 const Script& script = Script::Handle(target_function.script()); |
| 1889 return SetBreakpoint(script, | 1891 return SetBreakpoint(script, |
| 1890 target_function.token_pos(), | 1892 target_function.token_pos(), |
| 1891 target_function.end_token_pos()); | 1893 target_function.end_token_pos()); |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2578 } | 2580 } |
| 2579 | 2581 |
| 2580 | 2582 |
| 2581 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2583 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |
| 2582 ASSERT(bpt->next() == NULL); | 2584 ASSERT(bpt->next() == NULL); |
| 2583 bpt->set_next(code_breakpoints_); | 2585 bpt->set_next(code_breakpoints_); |
| 2584 code_breakpoints_ = bpt; | 2586 code_breakpoints_ = bpt; |
| 2585 } | 2587 } |
| 2586 | 2588 |
| 2587 } // namespace dart | 2589 } // namespace dart |
| OLD | NEW |