Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: runtime/vm/debugger.cc

Issue 356923006: Iterate over PcDescriptors only via iterators, not via an index. (preparation for more compression … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 uword fp, 173 uword fp,
174 uword sp, 174 uword sp,
175 const Code& code, 175 const Code& code,
176 const Array& deopt_frame, 176 const Array& deopt_frame,
177 intptr_t deopt_frame_offset) 177 intptr_t deopt_frame_offset)
178 : pc_(pc), fp_(fp), sp_(sp), 178 : pc_(pc), fp_(fp), sp_(sp),
179 ctx_(Context::ZoneHandle()), 179 ctx_(Context::ZoneHandle()),
180 code_(Code::ZoneHandle(code.raw())), 180 code_(Code::ZoneHandle(code.raw())),
181 function_(Function::ZoneHandle(code.function())), 181 function_(Function::ZoneHandle(code.function())),
182 token_pos_(-1), 182 token_pos_(-1),
183 pc_desc_index_(-1), 183 desc_rec_(NULL),
184 line_number_(-1), 184 line_number_(-1),
185 column_number_(-1), 185 column_number_(-1),
186 context_level_(-1), 186 context_level_(-1),
187 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 187 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
188 deopt_frame_offset_(deopt_frame_offset), 188 deopt_frame_offset_(deopt_frame_offset),
189 vars_initialized_(false), 189 vars_initialized_(false),
190 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 190 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
191 desc_indices_(8), 191 desc_indices_(8),
192 pc_desc_(PcDescriptors::ZoneHandle()) { 192 pc_desc_(PcDescriptors::ZoneHandle()) {
193 } 193 }
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 ASSERT(!pc_desc_.IsNull()); 352 ASSERT(!pc_desc_.IsNull());
353 } 353 }
354 } 354 }
355 355
356 356
357 // Compute token_pos_ and pc_desc_index_. 357 // Compute token_pos_ and pc_desc_index_.
358 intptr_t ActivationFrame::TokenPos() { 358 intptr_t ActivationFrame::TokenPos() {
359 if (token_pos_ < 0) { 359 if (token_pos_ < 0) {
360 token_pos_ = Scanner::kNoSourcePos; 360 token_pos_ = Scanner::kNoSourcePos;
361 GetPcDescriptors(); 361 GetPcDescriptors();
362 for (intptr_t i = 0; i < pc_desc_.Length(); i++) { 362 PcDescriptors::Iterator iter(pc_desc_);
363 if (pc_desc_.PC(i) == pc_) { 363 while (iter.HasNext()) {
364 pc_desc_index_ = i; 364 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
365 token_pos_ = pc_desc_.TokenPos(i); 365 if (rec.pc == pc_) {
366 desc_rec_ = &rec;
Ivan Posva 2014/07/16 08:08:49 What is the lifetime of this PcDescriptorRec? Or a
hausner 2014/07/16 16:14:08 Good call. It seems that desc_rec_ is pointing int
367 token_pos_ = rec.token_pos;
366 break; 368 break;
367 } 369 }
368 } 370 }
369 } 371 }
370 return token_pos_; 372 return token_pos_;
371 } 373 }
372 374
373 375
374 intptr_t ActivationFrame::PcDescIndex() {
375 if (pc_desc_index_ < 0) {
376 TokenPos(); // Sets pc_desc_index_ as a side effect.
377 }
378 return pc_desc_index_;
379 }
380
381
382 intptr_t ActivationFrame::TryIndex() { 376 intptr_t ActivationFrame::TryIndex() {
383 intptr_t desc_index = PcDescIndex(); 377 if (desc_rec_ == NULL) {
384 if (desc_index < 0) {
385 return -1; 378 return -1;
386 } else { 379 } else {
387 return pc_desc_.TryIndex(desc_index); 380 return desc_rec_->try_index;
388 } 381 }
389 } 382 }
390 383
391 384
392 intptr_t ActivationFrame::LineNumber() { 385 intptr_t ActivationFrame::LineNumber() {
393 // Compute line number lazily since it causes scanning of the script. 386 // Compute line number lazily since it causes scanning of the script.
394 if ((line_number_ < 0) && (TokenPos() >= 0)) { 387 if ((line_number_ < 0) && (TokenPos() >= 0)) {
395 const Script& script = Script::Handle(SourceScript()); 388 const Script& script = Script::Handle(SourceScript());
396 script.GetTokenLocation(TokenPos(), &line_number_, NULL); 389 script.GetTokenLocation(TokenPos(), &line_number_, NULL);
397 } 390 }
(...skipping 26 matching lines...) Expand all
424 bool ActivationFrame::IsDebuggable() const { 417 bool ActivationFrame::IsDebuggable() const {
425 return Debugger::IsDebuggable(function()); 418 return Debugger::IsDebuggable(function());
426 } 419 }
427 420
428 421
429 // Calculate the context level at the current token index of the frame. 422 // Calculate the context level at the current token index of the frame.
430 intptr_t ActivationFrame::ContextLevel() { 423 intptr_t ActivationFrame::ContextLevel() {
431 if (context_level_ < 0 && !ctx_.IsNull()) { 424 if (context_level_ < 0 && !ctx_.IsNull()) {
432 ASSERT(!code_.is_optimized()); 425 ASSERT(!code_.is_optimized());
433 context_level_ = 0; 426 context_level_ = 0;
434 intptr_t pc_desc_idx = PcDescIndex();
435 // TODO(hausner): What to do if there is no descriptor entry 427 // TODO(hausner): What to do if there is no descriptor entry
436 // for the code position of the frame? For now say we are at context 428 // for the code position of the frame? For now say we are at context
437 // level 0. 429 // level 0.
438 if (pc_desc_idx < 0) { 430 if (desc_rec_ == NULL) {
439 return context_level_; 431 return context_level_;
440 } 432 }
441 ASSERT(!pc_desc_.IsNull()); 433 ASSERT(!pc_desc_.IsNull());
442 intptr_t innermost_begin_pos = 0; 434 intptr_t innermost_begin_pos = 0;
443 intptr_t activation_token_pos = TokenPos(); 435 intptr_t activation_token_pos = TokenPos();
444 ASSERT(activation_token_pos >= 0); 436 ASSERT(activation_token_pos >= 0);
445 GetVarDescriptors(); 437 GetVarDescriptors();
446 intptr_t var_desc_len = var_descriptors_.Length(); 438 intptr_t var_desc_len = var_descriptors_.Length();
447 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { 439 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
448 RawLocalVarDescriptors::VarInfo var_info; 440 RawLocalVarDescriptors::VarInfo var_info;
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 914
923 915
924 916
925 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) { 917 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
926 if (FLAG_show_invisible_frames || frame->function().is_visible()) { 918 if (FLAG_show_invisible_frames || frame->function().is_visible()) {
927 trace_.Add(frame); 919 trace_.Add(frame);
928 } 920 }
929 } 921 }
930 922
931 923
932 static bool IsSafeDescKind(PcDescriptors::Kind kind) { 924 static bool IsSafeDescKind(int8_t kind) {
933 return ((kind == PcDescriptors::kIcCall) || 925 return ((kind == RawPcDescriptors::kIcCall) ||
934 (kind == PcDescriptors::kOptStaticCall) || 926 (kind == RawPcDescriptors::kOptStaticCall) ||
935 (kind == PcDescriptors::kUnoptStaticCall) || 927 (kind == RawPcDescriptors::kUnoptStaticCall) ||
936 (kind == PcDescriptors::kClosureCall) || 928 (kind == RawPcDescriptors::kClosureCall) ||
937 (kind == PcDescriptors::kRuntimeCall)); 929 (kind == RawPcDescriptors::kRuntimeCall));
938 } 930 }
939 931
940 932
941 static bool IsSafePoint(const PcDescriptors& desc, intptr_t i) { 933 static bool IsSafePoint(const RawPcDescriptors::PcDescriptorRec& rec) {
942 return IsSafeDescKind(desc.DescriptorKind(i)) && 934 return IsSafeDescKind(rec.kind()) && (rec.token_pos != Scanner::kNoSourcePos);
943 (desc.TokenPos(i) != Scanner::kNoSourcePos);
944 } 935 }
945 936
946 937
947 CodeBreakpoint::CodeBreakpoint(const Code& code, intptr_t pc_desc_index) 938 CodeBreakpoint::CodeBreakpoint(const Code& code,
939 const RawPcDescriptors::PcDescriptorRec& rec)
948 : code_(code.raw()), 940 : code_(code.raw()),
949 pc_desc_index_(pc_desc_index), 941 token_pos_(rec.token_pos),
950 pc_(0), 942 pc_(rec.pc),
951 line_number_(-1), 943 line_number_(-1),
952 is_enabled_(false), 944 is_enabled_(false),
953 src_bpt_(NULL), 945 src_bpt_(NULL),
954 next_(NULL) { 946 next_(NULL),
955 saved_value_ = 0; 947 breakpoint_kind_(rec.kind()),
948 saved_value_(0) {
956 ASSERT(!code.IsNull()); 949 ASSERT(!code.IsNull());
957 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
958 ASSERT(pc_desc_index < desc.Length());
959 token_pos_ = desc.TokenPos(pc_desc_index);
960 ASSERT(token_pos_ > 0); 950 ASSERT(token_pos_ > 0);
961 pc_ = desc.PC(pc_desc_index);
962 ASSERT(pc_ != 0); 951 ASSERT(pc_ != 0);
963 breakpoint_kind_ = desc.DescriptorKind(pc_desc_index);
964 ASSERT(IsSafeDescKind(breakpoint_kind_)); 952 ASSERT(IsSafeDescKind(breakpoint_kind_));
965 } 953 }
966 954
967 955
968 CodeBreakpoint::~CodeBreakpoint() { 956 CodeBreakpoint::~CodeBreakpoint() {
969 // Make sure we don't leave patched code behind. 957 // Make sure we don't leave patched code behind.
970 ASSERT(!IsEnabled()); 958 ASSERT(!IsEnabled());
971 // Poison the data so we catch use after free errors. 959 // Poison the data so we catch use after free errors.
972 #ifdef DEBUG 960 #ifdef DEBUG
973 code_ = Code::null(); 961 code_ = Code::null();
974 pc_ = 0ul; 962 pc_ = 0ul;
975 src_bpt_ = NULL; 963 src_bpt_ = NULL;
976 next_ = NULL; 964 next_ = NULL;
977 breakpoint_kind_ = PcDescriptors::kOther; 965 breakpoint_kind_ = RawPcDescriptors::kOther;
978 #endif 966 #endif
979 } 967 }
980 968
981 969
982 RawFunction* CodeBreakpoint::function() const { 970 RawFunction* CodeBreakpoint::function() const {
983 return Code::Handle(code_).function(); 971 return Code::Handle(code_).function();
984 } 972 }
985 973
986 974
987 RawScript* CodeBreakpoint::SourceCode() { 975 RawScript* CodeBreakpoint::SourceCode() {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 return; 1195 return;
1208 } 1196 }
1209 } 1197 }
1210 // Hang on to the code object before deoptimizing, in case deoptimization 1198 // Hang on to the code object before deoptimizing, in case deoptimization
1211 // might cause the GC to run. 1199 // might cause the GC to run.
1212 Code& code = Code::Handle(isolate, target_function.unoptimized_code()); 1200 Code& code = Code::Handle(isolate, target_function.unoptimized_code());
1213 ASSERT(!code.IsNull()); 1201 ASSERT(!code.IsNull());
1214 DeoptimizeWorld(); 1202 DeoptimizeWorld();
1215 ASSERT(!target_function.HasOptimizedCode()); 1203 ASSERT(!target_function.HasOptimizedCode());
1216 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors()); 1204 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors());
1217 for (intptr_t i = 0; i < desc.Length(); i++) { 1205 PcDescriptors::Iterator iter(desc);
1218 if (IsSafePoint(desc, i)) { 1206 while (iter.HasNext()) {
1219 CodeBreakpoint* bpt = GetCodeBreakpoint(desc.PC(i)); 1207 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
1208 if (IsSafePoint(rec)) {
1209 CodeBreakpoint* bpt = GetCodeBreakpoint(rec.pc);
1220 if (bpt != NULL) { 1210 if (bpt != NULL) {
1221 // There is already a breakpoint for this address. Make sure 1211 // There is already a breakpoint for this address. Make sure
1222 // it is enabled. 1212 // it is enabled.
1223 bpt->Enable(); 1213 bpt->Enable();
1224 continue; 1214 continue;
1225 } 1215 }
1226 bpt = new CodeBreakpoint(code, i); 1216 bpt = new CodeBreakpoint(code, rec);
1227 RegisterCodeBreakpoint(bpt); 1217 RegisterCodeBreakpoint(bpt);
1228 bpt->Enable(); 1218 bpt->Enable();
1229 } 1219 }
1230 } 1220 }
1231 } 1221 }
1232 1222
1233 1223
1234 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { 1224 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
1235 if (HasEventHandler()) { 1225 if (HasEventHandler()) {
1236 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved); 1226 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
(...skipping 19 matching lines...) Expand all
1256 new ActivationFrame(pc, frame->fp(), frame->sp(), code, 1246 new ActivationFrame(pc, frame->fp(), frame->sp(), code,
1257 deopt_frame, deopt_frame_offset); 1247 deopt_frame, deopt_frame_offset);
1258 1248
1259 // Is there a closure call at the current PC? 1249 // Is there a closure call at the current PC?
1260 // 1250 //
1261 // We can't just check the callee_activation to see if it is a 1251 // We can't just check the callee_activation to see if it is a
1262 // closure function, because it may not be on the stack yet. 1252 // closure function, because it may not be on the stack yet.
1263 bool is_closure_call = false; 1253 bool is_closure_call = false;
1264 const PcDescriptors& pc_desc = 1254 const PcDescriptors& pc_desc =
1265 PcDescriptors::Handle(isolate, code.pc_descriptors()); 1255 PcDescriptors::Handle(isolate, code.pc_descriptors());
1266 1256 PcDescriptors::Iterator iter(pc_desc);
1267 for (int i = 0; i < pc_desc.Length(); i++) { 1257 while (iter.HasNext()) {
1268 if (pc_desc.PC(i) == pc && 1258 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
1269 pc_desc.DescriptorKind(i) == PcDescriptors::kClosureCall) { 1259 if ((rec.pc == pc) && (rec.kind() == RawPcDescriptors::kClosureCall)) {
1270 is_closure_call = true; 1260 is_closure_call = true;
1271 break; 1261 break;
1272 } 1262 }
1273 } 1263 }
1274 1264
1275 // Recover the context for this frame. 1265 // Recover the context for this frame.
1276 if (is_closure_call) { 1266 if (is_closure_call) {
1277 // If the callee is a closure, we should have stored the context 1267 // If the callee is a closure, we should have stored the context
1278 // in the current frame before making the call. 1268 // in the current frame before making the call.
1279 const Context& closure_call_ctx = 1269 const Context& closure_call_ctx =
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 if (requested_token_pos < func.token_pos()) { 1539 if (requested_token_pos < func.token_pos()) {
1550 requested_token_pos = func.token_pos(); 1540 requested_token_pos = func.token_pos();
1551 } 1541 }
1552 if (last_token_pos > func.end_token_pos()) { 1542 if (last_token_pos > func.end_token_pos()) {
1553 last_token_pos = func.end_token_pos(); 1543 last_token_pos = func.end_token_pos();
1554 } 1544 }
1555 1545
1556 Code& code = Code::Handle(func.unoptimized_code()); 1546 Code& code = Code::Handle(func.unoptimized_code());
1557 ASSERT(!code.IsNull()); 1547 ASSERT(!code.IsNull());
1558 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 1548 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
1559 intptr_t best_fit_index = -1;
1560 intptr_t best_fit_pos = INT_MAX; 1549 intptr_t best_fit_pos = INT_MAX;
1550 const RawPcDescriptors::PcDescriptorRec* best_fit_rec = NULL;
1561 uword lowest_pc = kUwordMax; 1551 uword lowest_pc = kUwordMax;
1562 intptr_t lowest_pc_index = -1; 1552 const RawPcDescriptors::PcDescriptorRec* lowest_pc_rec = NULL;
1563 1553
1564 for (intptr_t i = 0; i < desc.Length(); i++) { 1554 const RawPcDescriptors::PcDescriptorRec* rec = NULL;
1565 intptr_t desc_token_pos = desc.TokenPos(i); 1555 PcDescriptors::Iterator iter(desc);
1556 while (iter.HasNext()) {
1557 rec = &iter.Next();
1558 intptr_t desc_token_pos = rec->token_pos;
1566 ASSERT(desc_token_pos >= 0); 1559 ASSERT(desc_token_pos >= 0);
1567 if (IsSafePoint(desc, i)) { 1560 if (IsSafePoint(*rec)) {
1568 if ((desc_token_pos < requested_token_pos) || 1561 if ((desc_token_pos < requested_token_pos) ||
1569 (desc_token_pos > last_token_pos)) { 1562 (desc_token_pos > last_token_pos)) {
1570 // This descriptor is outside the desired token range. 1563 // This descriptor is outside the desired token range.
1571 continue; 1564 continue;
1572 } 1565 }
1573 if (desc_token_pos < best_fit_pos) { 1566 if (desc_token_pos < best_fit_pos) {
1574 // So far, this descriptor has the lowest token position after 1567 // So far, this descriptor has the lowest token position after
1575 // the first acceptable token position. 1568 // the first acceptable token position.
1576 best_fit_pos = desc_token_pos; 1569 best_fit_pos = desc_token_pos;
1577 best_fit_index = i; 1570 best_fit_rec = rec;
1578 } 1571 }
1579 if (desc.PC(i) < lowest_pc) { 1572 if (rec->pc < lowest_pc) {
1580 // This descriptor so far has the lowest code address. 1573 // This descriptor so far has the lowest code address.
1581 lowest_pc = desc.PC(i); 1574 lowest_pc = rec->pc;
1582 lowest_pc_index = i; 1575 lowest_pc_rec = rec;
1583 } 1576 }
1584 } 1577 }
1585 } 1578 }
1586 if (lowest_pc_index >= 0) { 1579 if (lowest_pc_rec != NULL) {
1587 // We found the pc descriptor that has the lowest execution address. 1580 // We found the pc descriptor that has the lowest execution address.
1588 // This is the first possible breakpoint after the requested token 1581 // This is the first possible breakpoint after the requested token
1589 // position. We use this instead of the nearest PC descriptor 1582 // position. We use this instead of the nearest PC descriptor
1590 // measured in token index distance. 1583 // measured in token index distance.
1591 best_fit_index = lowest_pc_index; 1584 best_fit_rec = lowest_pc_rec;
1592 } 1585 }
1593 if (best_fit_index >= 0) { 1586 if (best_fit_rec != NULL) {
1594 return desc.TokenPos(best_fit_index); 1587 return best_fit_rec->token_pos;
1595 } 1588 }
1596 // We didn't find a safe point in the given token range. Try and find 1589 // We didn't find a safe point in the given token range. Try and find
1597 // a safe point in the remaining source code of the function. 1590 // a safe point in the remaining source code of the function.
1598 if (last_token_pos < func.end_token_pos()) { 1591 if (last_token_pos < func.end_token_pos()) {
1599 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos()); 1592 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos());
1600 } 1593 }
1601 return -1; 1594 return -1;
1602 } 1595 }
1603 1596
1604 1597
1605 void Debugger::MakeCodeBreakpointAt(const Function& func, 1598 void Debugger::MakeCodeBreakpointAt(const Function& func,
1606 SourceBreakpoint* bpt) { 1599 SourceBreakpoint* bpt) {
1607 ASSERT((bpt != NULL) && bpt->IsResolved()); 1600 ASSERT((bpt != NULL) && bpt->IsResolved());
1608 ASSERT(!func.HasOptimizedCode()); 1601 ASSERT(!func.HasOptimizedCode());
1609 Code& code = Code::Handle(func.unoptimized_code()); 1602 Code& code = Code::Handle(func.unoptimized_code());
1610 ASSERT(!code.IsNull()); 1603 ASSERT(!code.IsNull());
1611 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 1604 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
1612 uword lowest_pc = kUwordMax; 1605 uword lowest_pc = kUwordMax;
1613 intptr_t lowest_pc_index = -1;
1614 // Find the safe point with the lowest compiled code address 1606 // Find the safe point with the lowest compiled code address
1615 // that maps to the token position of the source breakpoint. 1607 // that maps to the token position of the source breakpoint.
1616 for (intptr_t i = 0; i < desc.Length(); i++) { 1608 PcDescriptors::Iterator iter(desc);
1617 intptr_t desc_token_pos = desc.TokenPos(i); 1609 const RawPcDescriptors::PcDescriptorRec* lowest_rec = NULL;
1618 if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(desc, i)) { 1610 while (iter.HasNext()) {
1619 if (desc.PC(i) < lowest_pc) { 1611 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next();
1620 // This descriptor so far has the lowest code address. 1612 intptr_t desc_token_pos = rec.token_pos;
1621 lowest_pc = desc.PC(i); 1613 if ((desc_token_pos == bpt->token_pos_) && IsSafePoint(rec)) {
1622 lowest_pc_index = i; 1614 if (rec.pc < lowest_pc) {
1615 lowest_pc = rec.pc;
1616 lowest_rec = &rec;
1623 } 1617 }
1624 } 1618 }
1625 } 1619 }
1626 if (lowest_pc_index < 0) { 1620 if (lowest_rec == NULL) {
1627 return; 1621 return;
1628 } 1622 }
1629 CodeBreakpoint* code_bpt = GetCodeBreakpoint(desc.PC(lowest_pc_index)); 1623 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_rec->pc);
1630 if (code_bpt == NULL) { 1624 if (code_bpt == NULL) {
1631 // No code breakpoint for this code exists; create one. 1625 // No code breakpoint for this code exists; create one.
1632 code_bpt = new CodeBreakpoint(code, lowest_pc_index); 1626 code_bpt = new CodeBreakpoint(code, *lowest_rec);
1633 RegisterCodeBreakpoint(code_bpt); 1627 RegisterCodeBreakpoint(code_bpt);
1634 } 1628 }
1635 code_bpt->set_src_bpt(bpt); 1629 code_bpt->set_src_bpt(bpt);
1636 if (bpt->IsEnabled()) { 1630 if (bpt->IsEnabled()) {
1637 code_bpt->Enable(); 1631 code_bpt->Enable();
1638 } 1632 }
1639 } 1633 }
1640 1634
1641 1635
1642 void Debugger::FindCompiledFunctions(const Script& script, 1636 void Debugger::FindCompiledFunctions(const Script& script,
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
2584 } 2578 }
2585 2579
2586 2580
2587 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2581 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2588 ASSERT(bpt->next() == NULL); 2582 ASSERT(bpt->next() == NULL);
2589 bpt->set_next(code_breakpoints_); 2583 bpt->set_next(code_breakpoints_);
2590 code_breakpoints_ = bpt; 2584 code_breakpoints_ = bpt;
2591 } 2585 }
2592 2586
2593 } // namespace dart 2587 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698