| 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 138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   149     location.AddProperty("type", "Location"); |   149     location.AddProperty("type", "Location"); | 
|   150  |   150  | 
|   151     const String& url = String::Handle(script.url()); |   151     const String& url = String::Handle(script.url()); | 
|   152     location.AddProperty("script", url.ToCString()); |   152     location.AddProperty("script", url.ToCString()); | 
|   153     location.AddProperty("tokenPos", token_pos); |   153     location.AddProperty("tokenPos", token_pos); | 
|   154   } |   154   } | 
|   155 } |   155 } | 
|   156  |   156  | 
|   157  |   157  | 
|   158 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { |   158 void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 
|   159   visitor->VisitPointer(reinterpret_cast<RawObject**>(&function_)); |   159   visitor->VisitPointer(reinterpret_cast<RawObject**>(&code_)); | 
|   160 } |   160 } | 
|   161  |   161  | 
|   162  |   162  | 
|   163 ActivationFrame::ActivationFrame( |   163 ActivationFrame::ActivationFrame( | 
|   164     uword pc, |   164     uword pc, | 
|   165     uword fp, |   165     uword fp, | 
|   166     uword sp, |   166     uword sp, | 
|   167     const Code& code, |   167     const Code& code, | 
|   168     const Array& deopt_frame, |   168     const Array& deopt_frame, | 
|   169     intptr_t deopt_frame_offset) |   169     intptr_t deopt_frame_offset) | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   262   while (cbpt != NULL) { |   262   while (cbpt != NULL) { | 
|   263     if (func.raw() == cbpt->function()) { |   263     if (func.raw() == cbpt->function()) { | 
|   264       return true; |   264       return true; | 
|   265     } |   265     } | 
|   266     cbpt = cbpt->next_; |   266     cbpt = cbpt->next_; | 
|   267   } |   267   } | 
|   268   return false; |   268   return false; | 
|   269 } |   269 } | 
|   270  |   270  | 
|   271  |   271  | 
 |   272 bool Debugger::HasBreakpoint(const Code& code) { | 
 |   273   CodeBreakpoint* cbpt = code_breakpoints_; | 
 |   274   while (cbpt != NULL) { | 
 |   275     if (code.raw() == cbpt->code_) { | 
 |   276       return true; | 
 |   277     } | 
 |   278     cbpt = cbpt->next_; | 
 |   279   } | 
 |   280   return false; | 
 |   281 } | 
 |   282  | 
 |   283  | 
|   272 void Debugger::PrintBreakpointsToJSONArray(JSONArray* jsarr) const { |   284 void Debugger::PrintBreakpointsToJSONArray(JSONArray* jsarr) const { | 
|   273   SourceBreakpoint* sbpt = src_breakpoints_; |   285   SourceBreakpoint* sbpt = src_breakpoints_; | 
|   274   while (sbpt != NULL) { |   286   while (sbpt != NULL) { | 
|   275     jsarr->AddValue(sbpt); |   287     jsarr->AddValue(sbpt); | 
|   276     sbpt = sbpt->next_; |   288     sbpt = sbpt->next_; | 
|   277   } |   289   } | 
|   278 } |   290 } | 
|   279  |   291  | 
|   280  |   292  | 
|   281 RawString* ActivationFrame::QualifiedFunctionName() { |   293 RawString* ActivationFrame::QualifiedFunctionName() { | 
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   699           (kind == PcDescriptors::kRuntimeCall)); |   711           (kind == PcDescriptors::kRuntimeCall)); | 
|   700 } |   712 } | 
|   701  |   713  | 
|   702  |   714  | 
|   703 static bool IsSafePoint(const PcDescriptors& desc, intptr_t i) { |   715 static bool IsSafePoint(const PcDescriptors& desc, intptr_t i) { | 
|   704   return IsSafeDescKind(desc.DescriptorKind(i)) && |   716   return IsSafeDescKind(desc.DescriptorKind(i)) && | 
|   705          (desc.TokenPos(i) != Scanner::kNoSourcePos); |   717          (desc.TokenPos(i) != Scanner::kNoSourcePos); | 
|   706 } |   718 } | 
|   707  |   719  | 
|   708  |   720  | 
|   709 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) |   721 CodeBreakpoint::CodeBreakpoint(const Code& code, intptr_t pc_desc_index) | 
|   710     : function_(func.raw()), |   722     : code_(code.raw()), | 
|   711       pc_desc_index_(pc_desc_index), |   723       pc_desc_index_(pc_desc_index), | 
|   712       pc_(0), |   724       pc_(0), | 
|   713       line_number_(-1), |   725       line_number_(-1), | 
|   714       is_enabled_(false), |   726       is_enabled_(false), | 
|   715       src_bpt_(NULL), |   727       src_bpt_(NULL), | 
|   716       next_(NULL) { |   728       next_(NULL) { | 
|   717   saved_value_ = 0; |   729   saved_value_ = 0; | 
|   718   ASSERT(!func.HasOptimizedCode()); |   730   ASSERT(!code.IsNull()); | 
|   719   Code& code = Code::Handle(func.unoptimized_code()); |  | 
|   720   ASSERT(!code.IsNull());  // Function must be compiled. |  | 
|   721   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |   731   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 
|   722   ASSERT(pc_desc_index < desc.Length()); |   732   ASSERT(pc_desc_index < desc.Length()); | 
|   723   token_pos_ = desc.TokenPos(pc_desc_index); |   733   token_pos_ = desc.TokenPos(pc_desc_index); | 
|   724   ASSERT(token_pos_ > 0); |   734   ASSERT(token_pos_ > 0); | 
|   725   pc_ = desc.PC(pc_desc_index); |   735   pc_ = desc.PC(pc_desc_index); | 
|   726   ASSERT(pc_ != 0); |   736   ASSERT(pc_ != 0); | 
|   727   breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); |   737   breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 
|   728   ASSERT(IsSafeDescKind(breakpoint_kind_)); |   738   ASSERT(IsSafeDescKind(breakpoint_kind_)); | 
|   729 } |   739 } | 
|   730  |   740  | 
|   731  |   741  | 
|   732 CodeBreakpoint::~CodeBreakpoint() { |   742 CodeBreakpoint::~CodeBreakpoint() { | 
|   733   // Make sure we don't leave patched code behind. |   743   // Make sure we don't leave patched code behind. | 
|   734   ASSERT(!IsEnabled()); |   744   ASSERT(!IsEnabled()); | 
|   735   // Poison the data so we catch use after free errors. |   745   // Poison the data so we catch use after free errors. | 
|   736 #ifdef DEBUG |   746 #ifdef DEBUG | 
|   737   function_ = Function::null(); |   747   code_ = Code::null(); | 
|   738   pc_ = 0ul; |   748   pc_ = 0ul; | 
|   739   src_bpt_ = NULL; |   749   src_bpt_ = NULL; | 
|   740   next_ = NULL; |   750   next_ = NULL; | 
|   741   breakpoint_kind_ = PcDescriptors::kOther; |   751   breakpoint_kind_ = PcDescriptors::kOther; | 
|   742 #endif |   752 #endif | 
|   743 } |   753 } | 
|   744  |   754  | 
|   745  |   755  | 
 |   756 RawFunction* CodeBreakpoint::function() const { | 
 |   757   return Code::Handle(code_).function(); | 
 |   758 } | 
 |   759  | 
 |   760  | 
|   746 RawScript* CodeBreakpoint::SourceCode() { |   761 RawScript* CodeBreakpoint::SourceCode() { | 
|   747   const Function& func = Function::Handle(function_); |   762   const Function& func = Function::Handle(this->function()); | 
|   748   return func.script(); |   763   return func.script(); | 
|   749 } |   764 } | 
|   750  |   765  | 
|   751  |   766  | 
|   752 RawString* CodeBreakpoint::SourceUrl() { |   767 RawString* CodeBreakpoint::SourceUrl() { | 
|   753   const Script& script = Script::Handle(SourceCode()); |   768   const Script& script = Script::Handle(SourceCode()); | 
|   754   return script.url(); |   769   return script.url(); | 
|   755 } |   770 } | 
|   756  |   771  | 
|   757  |   772  | 
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   957     return; |   972     return; | 
|   958   } |   973   } | 
|   959   if (!target_function.HasCode()) { |   974   if (!target_function.HasCode()) { | 
|   960     Compiler::CompileFunction(target_function); |   975     Compiler::CompileFunction(target_function); | 
|   961     // If there were any errors, ignore them silently and return without |   976     // If there were any errors, ignore them silently and return without | 
|   962     // adding breakpoints to target. |   977     // adding breakpoints to target. | 
|   963     if (!target_function.HasCode()) { |   978     if (!target_function.HasCode()) { | 
|   964       return; |   979       return; | 
|   965     } |   980     } | 
|   966   } |   981   } | 
 |   982   // Hang on to the code object before deoptimizing, in case deoptimization | 
 |   983   // might cause the GC to run. | 
 |   984   Code& code = Code::Handle(target_function.unoptimized_code()); | 
 |   985   ASSERT(!code.IsNull()); | 
|   967   DeoptimizeWorld(); |   986   DeoptimizeWorld(); | 
|   968   ASSERT(!target_function.HasOptimizedCode()); |   987   ASSERT(!target_function.HasOptimizedCode()); | 
|   969   Code& code = Code::Handle(target_function.unoptimized_code()); |  | 
|   970   ASSERT(!code.IsNull()); |  | 
|   971   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |   988   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 
|   972   for (intptr_t i = 0; i < desc.Length(); i++) { |   989   for (intptr_t i = 0; i < desc.Length(); i++) { | 
|   973     if (IsSafePoint(desc, i)) { |   990     if (IsSafePoint(desc, i)) { | 
|   974       CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); |   991       CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); | 
|   975       if (bpt != NULL) { |   992       if (bpt != NULL) { | 
|   976         // There is already a breakpoint for this address. Make sure |   993         // There is already a breakpoint for this address. Make sure | 
|   977         // it is enabled. |   994         // it is enabled. | 
|   978         bpt->Enable(); |   995         bpt->Enable(); | 
|   979         continue; |   996         continue; | 
|   980       } |   997       } | 
|   981       bpt = new CodeBreakpoint(target_function, i); |   998       bpt = new CodeBreakpoint(code, i); | 
|   982       RegisterCodeBreakpoint(bpt); |   999       RegisterCodeBreakpoint(bpt); | 
|   983       bpt->Enable(); |  1000       bpt->Enable(); | 
|   984     } |  1001     } | 
|   985   } |  1002   } | 
|   986 } |  1003 } | 
|   987  |  1004  | 
|   988  |  1005  | 
|   989 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { |  1006 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 
|   990   if (event_handler_ != NULL) { |  1007   if (event_handler_ != NULL) { | 
|   991     DebuggerEvent event(kBreakpointResolved); |  1008     DebuggerEvent event(kBreakpointResolved); | 
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1299   ASSERT(!func.HasOptimizedCode()); |  1316   ASSERT(!func.HasOptimizedCode()); | 
|  1300   Code& code = Code::Handle(func.unoptimized_code()); |  1317   Code& code = Code::Handle(func.unoptimized_code()); | 
|  1301   ASSERT(!code.IsNull()); |  1318   ASSERT(!code.IsNull()); | 
|  1302   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); |  1319   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 
|  1303   for (intptr_t i = 0; i < desc.Length(); i++) { |  1320   for (intptr_t i = 0; i < desc.Length(); i++) { | 
|  1304     intptr_t desc_token_pos = desc.TokenPos(i); |  1321     intptr_t desc_token_pos = desc.TokenPos(i); | 
|  1305     if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(desc, i)) { |  1322     if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(desc, i)) { | 
|  1306       CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); |  1323       CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(i)); | 
|  1307       if (code_bpt == NULL) { |  1324       if (code_bpt == NULL) { | 
|  1308         // No code breakpoint for this code exists; create one. |  1325         // No code breakpoint for this code exists; create one. | 
|  1309         code_bpt = new CodeBreakpoint(func, i); |  1326         code_bpt = new CodeBreakpoint(code, i); | 
|  1310         RegisterCodeBreakpoint(code_bpt); |  1327         RegisterCodeBreakpoint(code_bpt); | 
|  1311       } |  1328       } | 
|  1312       code_bpt->set_src_bpt(bpt); |  1329       code_bpt->set_src_bpt(bpt); | 
|  1313       if (bpt->IsEnabled()) { |  1330       if (bpt->IsEnabled()) { | 
|  1314         code_bpt->Enable(); |  1331         code_bpt->Enable(); | 
|  1315       } |  1332       } | 
|  1316     } |  1333     } | 
|  1317   } |  1334   } | 
|  1318 } |  1335 } | 
|  1319  |  1336  | 
| (...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2240 } |  2257 } | 
|  2241  |  2258  | 
|  2242  |  2259  | 
|  2243 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { |  2260 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 
|  2244   ASSERT(bpt->next() == NULL); |  2261   ASSERT(bpt->next() == NULL); | 
|  2245   bpt->set_next(code_breakpoints_); |  2262   bpt->set_next(code_breakpoints_); | 
|  2246   code_breakpoints_ = bpt; |  2263   code_breakpoints_ = bpt; | 
|  2247 } |  2264 } | 
|  2248  |  2265  | 
|  2249 }  // namespace dart |  2266 }  // namespace dart | 
| OLD | NEW |