Chromium Code Reviews| Index: runtime/vm/debugger.cc |
| =================================================================== |
| --- runtime/vm/debugger.cc (revision 16761) |
| +++ runtime/vm/debugger.cc (working copy) |
| @@ -216,6 +216,30 @@ |
| } |
| +bool Debugger::HasBreakpoint(const Function& func) { |
| + if (!func.HasCode()) { |
| + // If the function is not compiled yet, just check whether there |
| + // is a user-defined latent breakpoint. |
| + SourceBreakpoint* sbpt = src_breakpoints_; |
| + while (sbpt != NULL) { |
| + if (func.raw() == sbpt->function()) { |
| + return true; |
| + } |
| + sbpt = sbpt->next_; |
| + } |
| + return false; |
| + } |
| + CodeBreakpoint* cbpt = code_breakpoints_; |
| + while (cbpt != NULL) { |
| + if (func.raw() == cbpt->function()) { |
| + return true; |
| + } |
| + cbpt = cbpt->next_; |
| + } |
| + return false; |
| +} |
| + |
| + |
| RawString* ActivationFrame::QualifiedFunctionName() { |
| const Function& func = DartFunction(); |
| return String::New(Debugger::QualifiedFunctionName(func)); |
| @@ -703,18 +727,6 @@ |
| } |
| -bool Debugger::IsActive() { |
| - // TODO(hausner): The code generator uses this function to prevent |
| - // generation of optimized code when Dart code is being debugged. |
| - // This is probably not conservative enough (we could set the first |
| - // breakpoint after optimized code has already been produced). |
| - // Long-term, we need to be able to de-optimize code. |
| - return (src_breakpoints_ != NULL) || |
| - (code_breakpoints_ != NULL) || |
| - (exc_pause_info_ != kNoPauseOnExceptions); |
| -} |
| - |
| - |
| static RawFunction* ResolveLibraryFunction( |
| const Library& library, |
| const String& fname) { |
| @@ -748,27 +760,35 @@ |
| } |
| -// Deoptimize function if necessary. Does not patch return addresses on the |
| -// stack. If there are activation frames of this function on the stack, |
| -// the optimized code will be executed when the callee returns. |
| -void Debugger::EnsureFunctionIsDeoptimized(const Function& func) { |
| - if (func.HasOptimizedCode()) { |
| - if (FLAG_verbose_debug) { |
| - OS::Print("Deoptimizing function %s\n", |
| - String::Handle(func.name()).ToCString()); |
| +// Deoptimize all functions in the isolate. |
| +void Debugger::DeoptimizeWorld() { |
| + // Deoptimize all functions on in stack activation frames. |
|
srdjan
2013/01/08 18:03:57
Fix comment.
hausner
2013/01/08 18:37:57
Done.
|
| + DeoptimizeAll(); |
|
srdjan
2013/01/08 18:03:57
Add a TODO to deoptimize only functions that have
hausner
2013/01/08 18:37:57
Done.
|
| + // Iterate over all classes, deoptimize functions. |
| + const ClassTable& class_table = *isolate_->class_table(); |
|
srdjan
2013/01/08 18:03:57
Add a TODO to factor it out with RemoveOptimizedC
hausner
2013/01/08 18:37:57
Done.
|
| + Class& cls = Class::Handle(); |
| + Array& functions = Array::Handle(); |
| + Function& function = Function::Handle(); |
| + intptr_t num_classes = class_table.NumCids(); |
| + for (intptr_t i = 1; i < num_classes; i++) { |
| + if (class_table.HasValidClassAt(i)) { |
| + cls = class_table.At(i); |
| + functions = cls.functions(); |
| + intptr_t num_functions = functions.IsNull() ? 0 : functions.Length(); |
| + for (intptr_t f = 0; f < num_functions; f++) { |
| + function ^= functions.At(f); |
| + ASSERT(!function.IsNull()); |
| + if (function.HasOptimizedCode()) { |
| + function.SwitchToUnoptimizedCode(); |
| + } |
| + } |
| } |
| - func.set_usage_counter(0); |
| - func.set_deoptimization_counter(func.deoptimization_counter() + 1); |
| - Compiler::CompileFunction(func); |
| - ASSERT(!func.HasOptimizedCode()); |
| } |
| } |
| void Debugger::InstrumentForStepping(const Function& target_function) { |
| - if (target_function.HasCode()) { |
| - EnsureFunctionIsDeoptimized(target_function); |
| - } else { |
| + if (!target_function.HasCode()) { |
| Compiler::CompileFunction(target_function); |
| // If there were any errors, ignore them silently and return without |
| // adding breakpoints to target. |
| @@ -776,6 +796,8 @@ |
| return; |
| } |
| } |
| + DeoptimizeWorld(); |
| + ASSERT(!target_function.HasOptimizedCode()); |
| Code& code = Code::Handle(target_function.unoptimized_code()); |
| ASSERT(!code.IsNull()); |
| PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |
| @@ -972,7 +994,8 @@ |
| // The given token position is not within the target function. |
| return NULL; |
| } |
| - EnsureFunctionIsDeoptimized(target_function); |
| + DeoptimizeWorld(); |
| + ASSERT(!target_function.HasOptimizedCode()); |
| CodeBreakpoint* cbpt = NULL; |
| SourceBreakpoint* source_bpt = NULL; |
| @@ -1027,7 +1050,7 @@ |
| const Function& closure = |
| Function::Handle(target_function.ImplicitClosureFunction()); |
| if (closure.HasCode()) { |
| - EnsureFunctionIsDeoptimized(closure); |
| + ASSERT(!closure.HasOptimizedCode()); |
| CodeBreakpoint* closure_bpt = |
| MakeCodeBreakpoint(closure, first_token_pos, last_token_pos); |
| if ((closure_bpt != NULL) && (closure_bpt->src_bpt() == NULL)) { |