| 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 701 | 701 | 
| 702 | 702 | 
| 703 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) | 703 CodeBreakpoint::CodeBreakpoint(const Function& func, intptr_t pc_desc_index) | 
| 704     : function_(func.raw()), | 704     : function_(func.raw()), | 
| 705       pc_desc_index_(pc_desc_index), | 705       pc_desc_index_(pc_desc_index), | 
| 706       pc_(0), | 706       pc_(0), | 
| 707       line_number_(-1), | 707       line_number_(-1), | 
| 708       is_enabled_(false), | 708       is_enabled_(false), | 
| 709       src_bpt_(NULL), | 709       src_bpt_(NULL), | 
| 710       next_(NULL) { | 710       next_(NULL) { | 
|  | 711   saved_value_ = 0; | 
| 711   ASSERT(!func.HasOptimizedCode()); | 712   ASSERT(!func.HasOptimizedCode()); | 
| 712   Code& code = Code::Handle(func.unoptimized_code()); | 713   Code& code = Code::Handle(func.unoptimized_code()); | 
| 713   ASSERT(!code.IsNull());  // Function must be compiled. | 714   ASSERT(!code.IsNull());  // Function must be compiled. | 
| 714   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 715   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 
| 715   ASSERT(pc_desc_index < desc.Length()); | 716   ASSERT(pc_desc_index < desc.Length()); | 
| 716   token_pos_ = desc.TokenPos(pc_desc_index); | 717   token_pos_ = desc.TokenPos(pc_desc_index); | 
| 717   ASSERT(token_pos_ >= 0); | 718   ASSERT(token_pos_ >= 0); | 
| 718   pc_ = desc.PC(pc_desc_index); | 719   pc_ = desc.PC(pc_desc_index); | 
| 719   ASSERT(pc_ != 0); | 720   ASSERT(pc_ != 0); | 
| 720   breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 721   breakpoint_kind_ = desc.DescriptorKind(pc_desc_index); | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
| 751 intptr_t CodeBreakpoint::LineNumber() { | 752 intptr_t CodeBreakpoint::LineNumber() { | 
| 752   // Compute line number lazily since it causes scanning of the script. | 753   // Compute line number lazily since it causes scanning of the script. | 
| 753   if (line_number_ < 0) { | 754   if (line_number_ < 0) { | 
| 754     const Script& script = Script::Handle(SourceCode()); | 755     const Script& script = Script::Handle(SourceCode()); | 
| 755     script.GetTokenLocation(token_pos_, &line_number_, NULL); | 756     script.GetTokenLocation(token_pos_, &line_number_, NULL); | 
| 756   } | 757   } | 
| 757   return line_number_; | 758   return line_number_; | 
| 758 } | 759 } | 
| 759 | 760 | 
| 760 | 761 | 
| 761 void CodeBreakpoint::PatchCode() { |  | 
| 762   ASSERT(!is_enabled_); |  | 
| 763   switch (breakpoint_kind_) { |  | 
| 764     case PcDescriptors::kIcCall: { |  | 
| 765       const Code& code = |  | 
| 766           Code::Handle(Function::Handle(function_).unoptimized_code()); |  | 
| 767       saved_bytes_.target_address_ = |  | 
| 768           CodePatcher::GetInstanceCallAt(pc_, code, NULL); |  | 
| 769       CodePatcher::PatchInstanceCallAt(pc_, code, |  | 
| 770                                        StubCode::BreakpointDynamicEntryPoint()); |  | 
| 771       break; |  | 
| 772     } |  | 
| 773     case PcDescriptors::kUnoptStaticCall: { |  | 
| 774       const Code& code = |  | 
| 775           Code::Handle(Function::Handle(function_).unoptimized_code()); |  | 
| 776       saved_bytes_.target_address_ = |  | 
| 777           CodePatcher::GetStaticCallTargetAt(pc_, code); |  | 
| 778       CodePatcher::PatchStaticCallAt(pc_, code, |  | 
| 779                                      StubCode::BreakpointStaticEntryPoint()); |  | 
| 780       break; |  | 
| 781     } |  | 
| 782     case PcDescriptors::kRuntimeCall: |  | 
| 783     case PcDescriptors::kClosureCall: |  | 
| 784     case PcDescriptors::kReturn: { |  | 
| 785       const Code& code = |  | 
| 786           Code::Handle(Function::Handle(function_).unoptimized_code()); |  | 
| 787       saved_bytes_.target_address_ = |  | 
| 788           CodePatcher::GetStaticCallTargetAt(pc_, code); |  | 
| 789       CodePatcher::PatchStaticCallAt(pc_, code, |  | 
| 790                                      StubCode::BreakpointRuntimeEntryPoint()); |  | 
| 791       break; |  | 
| 792     } |  | 
| 793     default: |  | 
| 794       UNREACHABLE(); |  | 
| 795   } |  | 
| 796   is_enabled_ = true; |  | 
| 797 } |  | 
| 798 |  | 
| 799 |  | 
| 800 void CodeBreakpoint::RestoreCode() { |  | 
| 801   ASSERT(is_enabled_); |  | 
| 802   switch (breakpoint_kind_) { |  | 
| 803     case PcDescriptors::kIcCall: { |  | 
| 804       const Code& code = |  | 
| 805           Code::Handle(Function::Handle(function_).unoptimized_code()); |  | 
| 806       CodePatcher::PatchInstanceCallAt(pc_, code, |  | 
| 807                                        saved_bytes_.target_address_); |  | 
| 808       break; |  | 
| 809     } |  | 
| 810     case PcDescriptors::kUnoptStaticCall: |  | 
| 811     case PcDescriptors::kClosureCall: |  | 
| 812     case PcDescriptors::kRuntimeCall: |  | 
| 813     case PcDescriptors::kReturn: { |  | 
| 814       const Code& code = |  | 
| 815           Code::Handle(Function::Handle(function_).unoptimized_code()); |  | 
| 816       CodePatcher::PatchStaticCallAt(pc_, code, |  | 
| 817                                      saved_bytes_.target_address_); |  | 
| 818       break; |  | 
| 819     } |  | 
| 820     default: |  | 
| 821       UNREACHABLE(); |  | 
| 822   } |  | 
| 823   is_enabled_ = false; |  | 
| 824 } |  | 
| 825 |  | 
| 826 |  | 
| 827 void CodeBreakpoint::Enable() { | 762 void CodeBreakpoint::Enable() { | 
| 828   if (!is_enabled_) { | 763   if (!is_enabled_) { | 
| 829     PatchCode(); | 764     PatchCode(); | 
| 830   } | 765   } | 
| 831   ASSERT(is_enabled_); | 766   ASSERT(is_enabled_); | 
| 832 } | 767 } | 
| 833 | 768 | 
| 834 | 769 | 
| 835 void CodeBreakpoint::Disable() { | 770 void CodeBreakpoint::Disable() { | 
| 836   if (is_enabled_) { | 771   if (is_enabled_) { | 
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1022     if (!target_function.HasCode()) { | 957     if (!target_function.HasCode()) { | 
| 1023       return; | 958       return; | 
| 1024     } | 959     } | 
| 1025   } | 960   } | 
| 1026   DeoptimizeWorld(); | 961   DeoptimizeWorld(); | 
| 1027   ASSERT(!target_function.HasOptimizedCode()); | 962   ASSERT(!target_function.HasOptimizedCode()); | 
| 1028   Code& code = Code::Handle(target_function.unoptimized_code()); | 963   Code& code = Code::Handle(target_function.unoptimized_code()); | 
| 1029   ASSERT(!code.IsNull()); | 964   ASSERT(!code.IsNull()); | 
| 1030   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 965   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); | 
| 1031   for (intptr_t i = 0; i < desc.Length(); i++) { | 966   for (intptr_t i = 0; i < desc.Length(); i++) { | 
| 1032     CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); |  | 
| 1033     if (bpt != NULL) { |  | 
| 1034       // There is already a breakpoint for this address. Make sure |  | 
| 1035       // it is enabled. |  | 
| 1036       bpt->Enable(); |  | 
| 1037       continue; |  | 
| 1038     } |  | 
| 1039     if (IsSafePoint(desc.DescriptorKind(i))) { | 967     if (IsSafePoint(desc.DescriptorKind(i))) { | 
|  | 968       CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); | 
|  | 969       if (bpt != NULL) { | 
|  | 970         // There is already a breakpoint for this address. Make sure | 
|  | 971         // it is enabled. | 
|  | 972         bpt->Enable(); | 
|  | 973         continue; | 
|  | 974       } | 
| 1040       bpt = new CodeBreakpoint(target_function, i); | 975       bpt = new CodeBreakpoint(target_function, i); | 
| 1041       RegisterCodeBreakpoint(bpt); | 976       RegisterCodeBreakpoint(bpt); | 
| 1042       bpt->Enable(); | 977       bpt->Enable(); | 
| 1043     } | 978     } | 
| 1044   } | 979   } | 
| 1045 } | 980 } | 
| 1046 | 981 | 
| 1047 | 982 | 
| 1048 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 983 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { | 
| 1049   if (event_handler_ != NULL) { | 984   if (event_handler_ != NULL) { | 
| (...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2168     } | 2103     } | 
| 2169     bpt = bpt->next(); | 2104     bpt = bpt->next(); | 
| 2170   } | 2105   } | 
| 2171   return NULL; | 2106   return NULL; | 
| 2172 } | 2107 } | 
| 2173 | 2108 | 
| 2174 | 2109 | 
| 2175 uword Debugger::GetPatchedStubAddress(uword breakpoint_address) { | 2110 uword Debugger::GetPatchedStubAddress(uword breakpoint_address) { | 
| 2176   CodeBreakpoint* bpt = GetCodeBreakpoint(breakpoint_address); | 2111   CodeBreakpoint* bpt = GetCodeBreakpoint(breakpoint_address); | 
| 2177   if (bpt != NULL) { | 2112   if (bpt != NULL) { | 
| 2178     return bpt->saved_bytes_.target_address_; | 2113     return bpt->OrigStubAddress(); | 
| 2179   } | 2114   } | 
| 2180   UNREACHABLE(); | 2115   UNREACHABLE(); | 
| 2181   return 0L; | 2116   return 0L; | 
| 2182 } | 2117 } | 
| 2183 | 2118 | 
| 2184 | 2119 | 
| 2185 // Remove and delete the source breakpoint bpt and its associated | 2120 // Remove and delete the source breakpoint bpt and its associated | 
| 2186 // code breakpoints. | 2121 // code breakpoints. | 
| 2187 void Debugger::RemoveBreakpoint(intptr_t bp_id) { | 2122 void Debugger::RemoveBreakpoint(intptr_t bp_id) { | 
| 2188   SourceBreakpoint* prev_bpt = NULL; | 2123   SourceBreakpoint* prev_bpt = NULL; | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2281 } | 2216 } | 
| 2282 | 2217 | 
| 2283 | 2218 | 
| 2284 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 2219 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { | 
| 2285   ASSERT(bpt->next() == NULL); | 2220   ASSERT(bpt->next() == NULL); | 
| 2286   bpt->set_next(code_breakpoints_); | 2221   bpt->set_next(code_breakpoints_); | 
| 2287   code_breakpoints_ = bpt; | 2222   code_breakpoints_ = bpt; | 
| 2288 } | 2223 } | 
| 2289 | 2224 | 
| 2290 }  // namespace dart | 2225 }  // namespace dart | 
| OLD | NEW | 
|---|