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

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

Issue 403643002: One more iteration of PcDescriptor iterator improvement: do not copy record but access individual … (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/object.h » ('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 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 } 355 }
356 356
357 357
358 // Compute token_pos_ and try_index_ and token_pos_initialized_. 358 // Compute token_pos_ and try_index_ and token_pos_initialized_.
359 intptr_t ActivationFrame::TokenPos() { 359 intptr_t ActivationFrame::TokenPos() {
360 if (!token_pos_initialized_) { 360 if (!token_pos_initialized_) {
361 token_pos_initialized_ = true; 361 token_pos_initialized_ = true;
362 token_pos_ = Scanner::kNoSourcePos; 362 token_pos_ = Scanner::kNoSourcePos;
363 GetPcDescriptors(); 363 GetPcDescriptors();
364 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); 364 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
365 while (iter.HasNext()) { 365 while (iter.MoveNext()) {
366 RawPcDescriptors::PcDescriptorRec rec; 366 if (iter.Pc() == pc_) {
367 iter.NextRec(&rec); 367 try_index_ = iter.TryIndex();
368 if (rec.pc() == pc_) { 368 token_pos_ = iter.TokenPos();
369 try_index_ = rec.try_index();
370 token_pos_ = rec.token_pos();
371 break; 369 break;
372 } 370 }
373 } 371 }
374 } 372 }
375 return token_pos_; 373 return token_pos_;
376 } 374 }
377 375
378 376
379 intptr_t ActivationFrame::TryIndex() { 377 intptr_t ActivationFrame::TryIndex() {
380 if (!token_pos_initialized_) { 378 if (!token_pos_initialized_) {
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 } 922 }
925 } 923 }
926 924
927 925
928 const uint8_t kSafepointKind = 926 const uint8_t kSafepointKind =
929 RawPcDescriptors::kIcCall | RawPcDescriptors::kOptStaticCall | 927 RawPcDescriptors::kIcCall | RawPcDescriptors::kOptStaticCall |
930 RawPcDescriptors::kUnoptStaticCall | RawPcDescriptors::kClosureCall | 928 RawPcDescriptors::kUnoptStaticCall | RawPcDescriptors::kClosureCall |
931 RawPcDescriptors::kRuntimeCall; 929 RawPcDescriptors::kRuntimeCall;
932 930
933 931
934 static bool HasTokenPos(const RawPcDescriptors::PcDescriptorRec& rec) {
935 return rec.token_pos() != Scanner::kNoSourcePos;
936 }
937
938
939 CodeBreakpoint::CodeBreakpoint(const Code& code, 932 CodeBreakpoint::CodeBreakpoint(const Code& code,
940 const RawPcDescriptors::PcDescriptorRec& rec) 933 intptr_t token_pos,
934 uword pc,
935 RawPcDescriptors::Kind kind)
941 : code_(code.raw()), 936 : code_(code.raw()),
942 token_pos_(rec.token_pos()), 937 token_pos_(token_pos),
943 pc_(rec.pc()), 938 pc_(pc),
944 line_number_(-1), 939 line_number_(-1),
945 is_enabled_(false), 940 is_enabled_(false),
946 src_bpt_(NULL), 941 src_bpt_(NULL),
947 next_(NULL), 942 next_(NULL),
948 breakpoint_kind_(rec.kind()), 943 breakpoint_kind_(kind),
949 saved_value_(0) { 944 saved_value_(0) {
950 ASSERT(!code.IsNull()); 945 ASSERT(!code.IsNull());
951 ASSERT(token_pos_ > 0); 946 ASSERT(token_pos_ > 0);
952 ASSERT(pc_ != 0); 947 ASSERT(pc_ != 0);
953 ASSERT((breakpoint_kind_ & kSafepointKind) != 0); 948 ASSERT((breakpoint_kind_ & kSafepointKind) != 0);
954 } 949 }
955 950
956 951
957 CodeBreakpoint::~CodeBreakpoint() { 952 CodeBreakpoint::~CodeBreakpoint() {
958 // Make sure we don't leave patched code behind. 953 // Make sure we don't leave patched code behind.
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1192 }
1198 } 1193 }
1199 // Hang on to the code object before deoptimizing, in case deoptimization 1194 // Hang on to the code object before deoptimizing, in case deoptimization
1200 // might cause the GC to run. 1195 // might cause the GC to run.
1201 Code& code = Code::Handle(isolate, target_function.unoptimized_code()); 1196 Code& code = Code::Handle(isolate, target_function.unoptimized_code());
1202 ASSERT(!code.IsNull()); 1197 ASSERT(!code.IsNull());
1203 DeoptimizeWorld(); 1198 DeoptimizeWorld();
1204 ASSERT(!target_function.HasOptimizedCode()); 1199 ASSERT(!target_function.HasOptimizedCode());
1205 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors()); 1200 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors());
1206 PcDescriptors::Iterator iter(desc, kSafepointKind); 1201 PcDescriptors::Iterator iter(desc, kSafepointKind);
1207 while (iter.HasNext()) { 1202 while (iter.MoveNext()) {
1208 RawPcDescriptors::PcDescriptorRec rec; 1203 if (iter.TokenPos() != Scanner::kNoSourcePos) {
1209 iter.NextRec(&rec); 1204 CodeBreakpoint* bpt = GetCodeBreakpoint(iter.Pc());
1210 if (HasTokenPos(rec)) {
1211 CodeBreakpoint* bpt = GetCodeBreakpoint(rec.pc());
1212 if (bpt != NULL) { 1205 if (bpt != NULL) {
1213 // There is already a breakpoint for this address. Make sure 1206 // There is already a breakpoint for this address. Make sure
1214 // it is enabled. 1207 // it is enabled.
1215 bpt->Enable(); 1208 bpt->Enable();
1216 continue; 1209 continue;
1217 } 1210 }
1218 bpt = new CodeBreakpoint(code, rec); 1211 bpt = new CodeBreakpoint(code, iter.TokenPos(),
1212 iter.Pc(), iter.Kind());
1219 RegisterCodeBreakpoint(bpt); 1213 RegisterCodeBreakpoint(bpt);
1220 bpt->Enable(); 1214 bpt->Enable();
1221 } 1215 }
1222 } 1216 }
1223 } 1217 }
1224 1218
1225 1219
1226 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) { 1220 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
1227 if (HasEventHandler()) { 1221 if (HasEventHandler()) {
1228 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved); 1222 DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
(...skipping 20 matching lines...) Expand all
1249 deopt_frame, deopt_frame_offset); 1243 deopt_frame, deopt_frame_offset);
1250 1244
1251 // Is there a closure call at the current PC? 1245 // Is there a closure call at the current PC?
1252 // 1246 //
1253 // We can't just check the callee_activation to see if it is a 1247 // We can't just check the callee_activation to see if it is a
1254 // closure function, because it may not be on the stack yet. 1248 // closure function, because it may not be on the stack yet.
1255 bool is_closure_call = false; 1249 bool is_closure_call = false;
1256 const PcDescriptors& pc_desc = 1250 const PcDescriptors& pc_desc =
1257 PcDescriptors::Handle(isolate, code.pc_descriptors()); 1251 PcDescriptors::Handle(isolate, code.pc_descriptors());
1258 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall); 1252 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall);
1259 while (iter.HasNext()) { 1253 while (iter.MoveNext()) {
1260 const uword rec_pc = iter.NextPc(); 1254 if (iter.Pc() == pc) {
1261 if (rec_pc == pc) {
1262 is_closure_call = true; 1255 is_closure_call = true;
1263 break; 1256 break;
1264 } 1257 }
1265 } 1258 }
1266 1259
1267 // Recover the context for this frame. 1260 // Recover the context for this frame.
1268 if (is_closure_call) { 1261 if (is_closure_call) {
1269 // If the callee is a closure, we should have stored the context 1262 // If the callee is a closure, we should have stored the context
1270 // in the current frame before making the call. 1263 // in the current frame before making the call.
1271 const Context& closure_call_ctx = 1264 const Context& closure_call_ctx =
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 last_token_pos = func.end_token_pos(); 1538 last_token_pos = func.end_token_pos();
1546 } 1539 }
1547 1540
1548 Code& code = Code::Handle(func.unoptimized_code()); 1541 Code& code = Code::Handle(func.unoptimized_code());
1549 ASSERT(!code.IsNull()); 1542 ASSERT(!code.IsNull());
1550 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 1543 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
1551 intptr_t best_fit_pos = INT_MAX; 1544 intptr_t best_fit_pos = INT_MAX;
1552 uword lowest_pc = kUwordMax; 1545 uword lowest_pc = kUwordMax;
1553 intptr_t lowest_pc_token_pos = INT_MAX; 1546 intptr_t lowest_pc_token_pos = INT_MAX;
1554 PcDescriptors::Iterator iter(desc, kSafepointKind); 1547 PcDescriptors::Iterator iter(desc, kSafepointKind);
1555 while (iter.HasNext()) { 1548 while (iter.MoveNext()) {
1556 RawPcDescriptors::PcDescriptorRec rec; 1549 const intptr_t desc_token_pos = iter.TokenPos();
1557 iter.NextRec(&rec);
1558 intptr_t desc_token_pos = rec.token_pos();
1559 ASSERT(desc_token_pos >= 0); 1550 ASSERT(desc_token_pos >= 0);
1560 if (HasTokenPos(rec)) { 1551 if (desc_token_pos != Scanner::kNoSourcePos) {
1561 if ((desc_token_pos < requested_token_pos) || 1552 if ((desc_token_pos < requested_token_pos) ||
1562 (desc_token_pos > last_token_pos)) { 1553 (desc_token_pos > last_token_pos)) {
1563 // This descriptor is outside the desired token range. 1554 // This descriptor is outside the desired token range.
1564 continue; 1555 continue;
1565 } 1556 }
1566 if (desc_token_pos < best_fit_pos) { 1557 if (desc_token_pos < best_fit_pos) {
1567 // So far, this descriptor has the lowest token position after 1558 // So far, this descriptor has the lowest token position after
1568 // the first acceptable token position. 1559 // the first acceptable token position.
1569 best_fit_pos = desc_token_pos; 1560 best_fit_pos = desc_token_pos;
1570 } 1561 }
1571 if (rec.pc() < lowest_pc) { 1562 if (iter.Pc() < lowest_pc) {
1572 // This descriptor so far has the lowest code address. 1563 // This descriptor so far has the lowest code address.
1573 lowest_pc = rec.pc(); 1564 lowest_pc = iter.Pc();
1574 lowest_pc_token_pos = desc_token_pos; 1565 lowest_pc_token_pos = desc_token_pos;
1575 } 1566 }
1576 } 1567 }
1577 } 1568 }
1578 if (lowest_pc_token_pos != INT_MAX) { 1569 if (lowest_pc_token_pos != INT_MAX) {
1579 // We found the pc descriptor that has the lowest execution address. 1570 // We found the pc descriptor that has the lowest execution address.
1580 // This is the first possible breakpoint after the requested token 1571 // This is the first possible breakpoint after the requested token
1581 // position. We use this instead of the nearest PC descriptor 1572 // position. We use this instead of the nearest PC descriptor
1582 // measured in token index distance. 1573 // measured in token index distance.
1583 return lowest_pc_token_pos; 1574 return lowest_pc_token_pos;
1584 } 1575 }
1585 if (best_fit_pos != INT_MAX) { 1576 if (best_fit_pos != INT_MAX) {
1586 return best_fit_pos; 1577 return best_fit_pos;
1587 } 1578 }
1588 // We didn't find a safe point in the given token range. Try and find 1579 // We didn't find a safe point in the given token range. Try and find
1589 // a safe point in the remaining source code of the function. 1580 // a safe point in the remaining source code of the function.
1590 if (last_token_pos < func.end_token_pos()) { 1581 if (last_token_pos < func.end_token_pos()) {
1591 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos()); 1582 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos());
1592 } 1583 }
1593 return -1; 1584 return -1;
1594 } 1585 }
1595 1586
1596 1587
1597 void Debugger::MakeCodeBreakpointAt(const Function& func, 1588 void Debugger::MakeCodeBreakpointAt(const Function& func,
1598 SourceBreakpoint* bpt) { 1589 SourceBreakpoint* bpt) {
1590 ASSERT(bpt->token_pos_ != Scanner::kNoSourcePos);
1599 ASSERT((bpt != NULL) && bpt->IsResolved()); 1591 ASSERT((bpt != NULL) && bpt->IsResolved());
1600 ASSERT(!func.HasOptimizedCode()); 1592 ASSERT(!func.HasOptimizedCode());
1601 Code& code = Code::Handle(func.unoptimized_code()); 1593 Code& code = Code::Handle(func.unoptimized_code());
1602 ASSERT(!code.IsNull()); 1594 ASSERT(!code.IsNull());
1603 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 1595 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
1604 uword lowest_pc = kUwordMax; 1596 uword lowest_pc = kUwordMax;
1597 RawPcDescriptors::Kind lowest_kind = RawPcDescriptors::kAnyKind;
1605 // Find the safe point with the lowest compiled code address 1598 // Find the safe point with the lowest compiled code address
1606 // that maps to the token position of the source breakpoint. 1599 // that maps to the token position of the source breakpoint.
1607 PcDescriptors::Iterator iter(desc, kSafepointKind); 1600 PcDescriptors::Iterator iter(desc, kSafepointKind);
1608 RawPcDescriptors::PcDescriptorRec lowest_rec; 1601 while (iter.MoveNext()) {
1609 while (iter.HasNext()) { 1602 if (iter.TokenPos() == bpt->token_pos_) {
1610 RawPcDescriptors::PcDescriptorRec rec; 1603 if (iter.Pc() < lowest_pc) {
1611 iter.NextRec(&rec); 1604 lowest_pc = iter.Pc();
1612 intptr_t desc_token_pos = rec.token_pos(); 1605 lowest_kind = iter.Kind();
1613 if ((desc_token_pos == bpt->token_pos_) && HasTokenPos(rec)) {
1614 if (rec.pc() < lowest_pc) {
1615 lowest_pc = rec.pc();
1616 lowest_rec = rec;
1617 } 1606 }
1618 } 1607 }
1619 } 1608 }
1620 if (lowest_pc == kUwordMax) { 1609 if (lowest_pc == kUwordMax) {
1621 return; 1610 return;
1622 } 1611 }
1623 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_rec.pc()); 1612 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc);
1624 if (code_bpt == NULL) { 1613 if (code_bpt == NULL) {
1625 // No code breakpoint for this code exists; create one. 1614 // No code breakpoint for this code exists; create one.
1626 code_bpt = new CodeBreakpoint(code, lowest_rec); 1615 code_bpt = new CodeBreakpoint(code, bpt->token_pos_,
1616 lowest_pc, lowest_kind);
1627 RegisterCodeBreakpoint(code_bpt); 1617 RegisterCodeBreakpoint(code_bpt);
1628 } 1618 }
1629 code_bpt->set_src_bpt(bpt); 1619 code_bpt->set_src_bpt(bpt);
1630 if (bpt->IsEnabled()) { 1620 if (bpt->IsEnabled()) {
1631 code_bpt->Enable(); 1621 code_bpt->Enable();
1632 } 1622 }
1633 } 1623 }
1634 1624
1635 1625
1636 void Debugger::FindCompiledFunctions(const Script& script, 1626 void Debugger::FindCompiledFunctions(const Script& script,
(...skipping 941 matching lines...) Expand 10 before | Expand all | Expand 10 after
2578 } 2568 }
2579 2569
2580 2570
2581 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2571 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2582 ASSERT(bpt->next() == NULL); 2572 ASSERT(bpt->next() == NULL);
2583 bpt->set_next(code_breakpoints_); 2573 bpt->set_next(code_breakpoints_);
2584 code_breakpoints_ = bpt; 2574 code_breakpoints_ = bpt;
2585 } 2575 }
2586 2576
2587 } // namespace dart 2577 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698