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

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

Issue 396213005: Fix PcDescriptor iteratot to never return a pointer to a memory location since the data can move wi… (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 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 uword pc, 172 uword pc,
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_initialized_(false),
182 token_pos_(-1), 183 token_pos_(-1),
183 desc_rec_(NULL), 184 try_index_(-1),
184 line_number_(-1), 185 line_number_(-1),
185 column_number_(-1), 186 column_number_(-1),
186 context_level_(-1), 187 context_level_(-1),
187 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())), 188 deopt_frame_(Array::ZoneHandle(deopt_frame.raw())),
188 deopt_frame_offset_(deopt_frame_offset), 189 deopt_frame_offset_(deopt_frame_offset),
189 vars_initialized_(false), 190 vars_initialized_(false),
190 var_descriptors_(LocalVarDescriptors::ZoneHandle()), 191 var_descriptors_(LocalVarDescriptors::ZoneHandle()),
191 desc_indices_(8), 192 desc_indices_(8),
192 pc_desc_(PcDescriptors::ZoneHandle()) { 193 pc_desc_(PcDescriptors::ZoneHandle()) {
193 } 194 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 348
348 349
349 void ActivationFrame::GetPcDescriptors() { 350 void ActivationFrame::GetPcDescriptors() {
350 if (pc_desc_.IsNull()) { 351 if (pc_desc_.IsNull()) {
351 pc_desc_ = code().pc_descriptors(); 352 pc_desc_ = code().pc_descriptors();
352 ASSERT(!pc_desc_.IsNull()); 353 ASSERT(!pc_desc_.IsNull());
353 } 354 }
354 } 355 }
355 356
356 357
357 // Compute token_pos_ and pc_desc_index_. 358 // Compute token_pos_ and try_index_ and token_pos_initialized_.
358 intptr_t ActivationFrame::TokenPos() { 359 intptr_t ActivationFrame::TokenPos() {
359 if (token_pos_ < 0) { 360 if (!token_pos_initialized_) {
361 token_pos_initialized_ = true;
360 token_pos_ = Scanner::kNoSourcePos; 362 token_pos_ = Scanner::kNoSourcePos;
361 GetPcDescriptors(); 363 GetPcDescriptors();
362 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind); 364 PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
363 while (iter.HasNext()) { 365 while (iter.HasNext()) {
364 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); 366 RawPcDescriptors::PcDescriptorRec rec;
367 iter.NextRec(&rec);
365 if (rec.pc() == pc_) { 368 if (rec.pc() == pc_) {
366 desc_rec_ = &rec; 369 try_index_ = rec.try_index();
367 token_pos_ = rec.token_pos(); 370 token_pos_ = rec.token_pos();
368 break; 371 break;
369 } 372 }
370 } 373 }
371 } 374 }
372 return token_pos_; 375 return token_pos_;
373 } 376 }
374 377
375 378
376 intptr_t ActivationFrame::TryIndex() { 379 intptr_t ActivationFrame::TryIndex() {
377 if (desc_rec_ == NULL) { 380 if (!token_pos_initialized_) {
378 TokenPos(); // Side effect: compute desc_rec_ lazily. 381 TokenPos(); // Side effect: computes token_pos_initialized_, try_index_.
379 } 382 }
380 if (desc_rec_ == NULL) { 383 return try_index_;
381 return -1;
382 } else {
383 return desc_rec_->try_index();
384 }
385 } 384 }
386 385
387 386
388 intptr_t ActivationFrame::LineNumber() { 387 intptr_t ActivationFrame::LineNumber() {
389 // Compute line number lazily since it causes scanning of the script. 388 // Compute line number lazily since it causes scanning of the script.
390 if ((line_number_ < 0) && (TokenPos() >= 0)) { 389 if ((line_number_ < 0) && (TokenPos() >= 0)) {
391 const Script& script = Script::Handle(SourceScript()); 390 const Script& script = Script::Handle(SourceScript());
392 script.GetTokenLocation(TokenPos(), &line_number_, NULL); 391 script.GetTokenLocation(TokenPos(), &line_number_, NULL);
393 } 392 }
394 return line_number_; 393 return line_number_;
(...skipping 28 matching lines...) Expand all
423 422
424 423
425 // Calculate the context level at the current token index of the frame. 424 // Calculate the context level at the current token index of the frame.
426 intptr_t ActivationFrame::ContextLevel() { 425 intptr_t ActivationFrame::ContextLevel() {
427 if (context_level_ < 0 && !ctx_.IsNull()) { 426 if (context_level_ < 0 && !ctx_.IsNull()) {
428 ASSERT(!code_.is_optimized()); 427 ASSERT(!code_.is_optimized());
429 context_level_ = 0; 428 context_level_ = 0;
430 // TODO(hausner): What to do if there is no descriptor entry 429 // TODO(hausner): What to do if there is no descriptor entry
431 // for the code position of the frame? For now say we are at context 430 // for the code position of the frame? For now say we are at context
432 // level 0. 431 // level 0.
433 if (desc_rec_ == NULL) { 432 TokenPos();
433 if (token_pos_ == -1) {
434 // No PcDescriptor.
434 return context_level_; 435 return context_level_;
435 } 436 }
436 ASSERT(!pc_desc_.IsNull()); 437 ASSERT(!pc_desc_.IsNull());
437 intptr_t innermost_begin_pos = 0; 438 intptr_t innermost_begin_pos = 0;
438 intptr_t activation_token_pos = TokenPos(); 439 intptr_t activation_token_pos = TokenPos();
439 ASSERT(activation_token_pos >= 0); 440 ASSERT(activation_token_pos >= 0);
440 GetVarDescriptors(); 441 GetVarDescriptors();
441 intptr_t var_desc_len = var_descriptors_.Length(); 442 intptr_t var_desc_len = var_descriptors_.Length();
442 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { 443 for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
443 RawLocalVarDescriptors::VarInfo var_info; 444 RawLocalVarDescriptors::VarInfo var_info;
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1198 }
1198 // Hang on to the code object before deoptimizing, in case deoptimization 1199 // Hang on to the code object before deoptimizing, in case deoptimization
1199 // might cause the GC to run. 1200 // might cause the GC to run.
1200 Code& code = Code::Handle(isolate, target_function.unoptimized_code()); 1201 Code& code = Code::Handle(isolate, target_function.unoptimized_code());
1201 ASSERT(!code.IsNull()); 1202 ASSERT(!code.IsNull());
1202 DeoptimizeWorld(); 1203 DeoptimizeWorld();
1203 ASSERT(!target_function.HasOptimizedCode()); 1204 ASSERT(!target_function.HasOptimizedCode());
1204 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors()); 1205 PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors());
1205 PcDescriptors::Iterator iter(desc, kSafepointKind); 1206 PcDescriptors::Iterator iter(desc, kSafepointKind);
1206 while (iter.HasNext()) { 1207 while (iter.HasNext()) {
1207 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); 1208 RawPcDescriptors::PcDescriptorRec rec;
1209 iter.NextRec(&rec);
1208 if (HasTokenPos(rec)) { 1210 if (HasTokenPos(rec)) {
1209 CodeBreakpoint* bpt = GetCodeBreakpoint(rec.pc()); 1211 CodeBreakpoint* bpt = GetCodeBreakpoint(rec.pc());
1210 if (bpt != NULL) { 1212 if (bpt != NULL) {
1211 // There is already a breakpoint for this address. Make sure 1213 // There is already a breakpoint for this address. Make sure
1212 // it is enabled. 1214 // it is enabled.
1213 bpt->Enable(); 1215 bpt->Enable();
1214 continue; 1216 continue;
1215 } 1217 }
1216 bpt = new CodeBreakpoint(code, rec); 1218 bpt = new CodeBreakpoint(code, rec);
1217 RegisterCodeBreakpoint(bpt); 1219 RegisterCodeBreakpoint(bpt);
(...skipping 30 matching lines...) Expand all
1248 1250
1249 // Is there a closure call at the current PC? 1251 // Is there a closure call at the current PC?
1250 // 1252 //
1251 // We can't just check the callee_activation to see if it is a 1253 // We can't just check the callee_activation to see if it is a
1252 // closure function, because it may not be on the stack yet. 1254 // closure function, because it may not be on the stack yet.
1253 bool is_closure_call = false; 1255 bool is_closure_call = false;
1254 const PcDescriptors& pc_desc = 1256 const PcDescriptors& pc_desc =
1255 PcDescriptors::Handle(isolate, code.pc_descriptors()); 1257 PcDescriptors::Handle(isolate, code.pc_descriptors());
1256 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall); 1258 PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall);
1257 while (iter.HasNext()) { 1259 while (iter.HasNext()) {
1258 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); 1260 const uword rec_pc = iter.NextPc();
1259 if (rec.pc() == pc) { 1261 if (rec_pc == pc) {
1260 is_closure_call = true; 1262 is_closure_call = true;
1261 break; 1263 break;
1262 } 1264 }
1263 } 1265 }
1264 1266
1265 // Recover the context for this frame. 1267 // Recover the context for this frame.
1266 if (is_closure_call) { 1268 if (is_closure_call) {
1267 // If the callee is a closure, we should have stored the context 1269 // If the callee is a closure, we should have stored the context
1268 // in the current frame before making the call. 1270 // in the current frame before making the call.
1269 const Context& closure_call_ctx = 1271 const Context& closure_call_ctx =
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
1540 requested_token_pos = func.token_pos(); 1542 requested_token_pos = func.token_pos();
1541 } 1543 }
1542 if (last_token_pos > func.end_token_pos()) { 1544 if (last_token_pos > func.end_token_pos()) {
1543 last_token_pos = func.end_token_pos(); 1545 last_token_pos = func.end_token_pos();
1544 } 1546 }
1545 1547
1546 Code& code = Code::Handle(func.unoptimized_code()); 1548 Code& code = Code::Handle(func.unoptimized_code());
1547 ASSERT(!code.IsNull()); 1549 ASSERT(!code.IsNull());
1548 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 1550 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
1549 intptr_t best_fit_pos = INT_MAX; 1551 intptr_t best_fit_pos = INT_MAX;
1550 const RawPcDescriptors::PcDescriptorRec* best_fit_rec = NULL;
1551 uword lowest_pc = kUwordMax; 1552 uword lowest_pc = kUwordMax;
1552 const RawPcDescriptors::PcDescriptorRec* lowest_pc_rec = NULL; 1553 intptr_t lowest_pc_token_pos = INT_MAX;
1553
1554 const RawPcDescriptors::PcDescriptorRec* rec = NULL;
1555 PcDescriptors::Iterator iter(desc, kSafepointKind); 1554 PcDescriptors::Iterator iter(desc, kSafepointKind);
1556 while (iter.HasNext()) { 1555 while (iter.HasNext()) {
1557 rec = &iter.Next(); 1556 RawPcDescriptors::PcDescriptorRec rec;
1558 intptr_t desc_token_pos = rec->token_pos(); 1557 iter.NextRec(&rec);
1558 intptr_t desc_token_pos = rec.token_pos();
1559 ASSERT(desc_token_pos >= 0); 1559 ASSERT(desc_token_pos >= 0);
1560 if (HasTokenPos(*rec)) { 1560 if (HasTokenPos(rec)) {
1561 if ((desc_token_pos < requested_token_pos) || 1561 if ((desc_token_pos < requested_token_pos) ||
1562 (desc_token_pos > last_token_pos)) { 1562 (desc_token_pos > last_token_pos)) {
1563 // This descriptor is outside the desired token range. 1563 // This descriptor is outside the desired token range.
1564 continue; 1564 continue;
1565 } 1565 }
1566 if (desc_token_pos < best_fit_pos) { 1566 if (desc_token_pos < best_fit_pos) {
1567 // So far, this descriptor has the lowest token position after 1567 // So far, this descriptor has the lowest token position after
1568 // the first acceptable token position. 1568 // the first acceptable token position.
1569 best_fit_pos = desc_token_pos; 1569 best_fit_pos = desc_token_pos;
1570 best_fit_rec = rec;
1571 } 1570 }
1572 if (rec->pc() < lowest_pc) { 1571 if (rec.pc() < lowest_pc) {
1573 // This descriptor so far has the lowest code address. 1572 // This descriptor so far has the lowest code address.
1574 lowest_pc = rec->pc(); 1573 lowest_pc = rec.pc();
1575 lowest_pc_rec = rec; 1574 lowest_pc_token_pos = desc_token_pos;
1576 } 1575 }
1577 } 1576 }
1578 } 1577 }
1579 if (lowest_pc_rec != NULL) { 1578 if (lowest_pc_token_pos != INT_MAX) {
1580 // We found the pc descriptor that has the lowest execution address. 1579 // We found the pc descriptor that has the lowest execution address.
1581 // This is the first possible breakpoint after the requested token 1580 // This is the first possible breakpoint after the requested token
1582 // position. We use this instead of the nearest PC descriptor 1581 // position. We use this instead of the nearest PC descriptor
1583 // measured in token index distance. 1582 // measured in token index distance.
1584 best_fit_rec = lowest_pc_rec; 1583 return lowest_pc_token_pos;
1585 } 1584 }
1586 if (best_fit_rec != NULL) { 1585 if (best_fit_pos != INT_MAX) {
1587 return best_fit_rec->token_pos(); 1586 return best_fit_pos;
1588 } 1587 }
1589 // We didn't find a safe point in the given token range. Try and find 1588 // We didn't find a safe point in the given token range. Try and find
1590 // a safe point in the remaining source code of the function. 1589 // a safe point in the remaining source code of the function.
1591 if (last_token_pos < func.end_token_pos()) { 1590 if (last_token_pos < func.end_token_pos()) {
1592 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos()); 1591 return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos());
1593 } 1592 }
1594 return -1; 1593 return -1;
1595 } 1594 }
1596 1595
1597 1596
1598 void Debugger::MakeCodeBreakpointAt(const Function& func, 1597 void Debugger::MakeCodeBreakpointAt(const Function& func,
1599 SourceBreakpoint* bpt) { 1598 SourceBreakpoint* bpt) {
1600 ASSERT((bpt != NULL) && bpt->IsResolved()); 1599 ASSERT((bpt != NULL) && bpt->IsResolved());
1601 ASSERT(!func.HasOptimizedCode()); 1600 ASSERT(!func.HasOptimizedCode());
1602 Code& code = Code::Handle(func.unoptimized_code()); 1601 Code& code = Code::Handle(func.unoptimized_code());
1603 ASSERT(!code.IsNull()); 1602 ASSERT(!code.IsNull());
1604 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); 1603 PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
1605 uword lowest_pc = kUwordMax; 1604 uword lowest_pc = kUwordMax;
1606 // Find the safe point with the lowest compiled code address 1605 // Find the safe point with the lowest compiled code address
1607 // that maps to the token position of the source breakpoint. 1606 // that maps to the token position of the source breakpoint.
1608 PcDescriptors::Iterator iter(desc, kSafepointKind); 1607 PcDescriptors::Iterator iter(desc, kSafepointKind);
1609 const RawPcDescriptors::PcDescriptorRec* lowest_rec = NULL; 1608 RawPcDescriptors::PcDescriptorRec lowest_rec;
1610 while (iter.HasNext()) { 1609 while (iter.HasNext()) {
1611 const RawPcDescriptors::PcDescriptorRec& rec = iter.Next(); 1610 RawPcDescriptors::PcDescriptorRec rec;
1611 iter.NextRec(&rec);
1612 intptr_t desc_token_pos = rec.token_pos(); 1612 intptr_t desc_token_pos = rec.token_pos();
1613 if ((desc_token_pos == bpt->token_pos_) && HasTokenPos(rec)) { 1613 if ((desc_token_pos == bpt->token_pos_) && HasTokenPos(rec)) {
1614 if (rec.pc() < lowest_pc) { 1614 if (rec.pc() < lowest_pc) {
1615 lowest_pc = rec.pc(); 1615 lowest_pc = rec.pc();
1616 lowest_rec = &rec; 1616 lowest_rec = rec;
1617 } 1617 }
1618 } 1618 }
1619 } 1619 }
1620 if (lowest_rec == NULL) { 1620 if (lowest_pc == kUwordMax) {
1621 return; 1621 return;
1622 } 1622 }
1623 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_rec->pc()); 1623 CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_rec.pc());
1624 if (code_bpt == NULL) { 1624 if (code_bpt == NULL) {
1625 // No code breakpoint for this code exists; create one. 1625 // No code breakpoint for this code exists; create one.
1626 code_bpt = new CodeBreakpoint(code, *lowest_rec); 1626 code_bpt = new CodeBreakpoint(code, lowest_rec);
1627 RegisterCodeBreakpoint(code_bpt); 1627 RegisterCodeBreakpoint(code_bpt);
1628 } 1628 }
1629 code_bpt->set_src_bpt(bpt); 1629 code_bpt->set_src_bpt(bpt);
1630 if (bpt->IsEnabled()) { 1630 if (bpt->IsEnabled()) {
1631 code_bpt->Enable(); 1631 code_bpt->Enable();
1632 } 1632 }
1633 } 1633 }
1634 1634
1635 1635
1636 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
2578 } 2578 }
2579 2579
2580 2580
2581 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) { 2581 void Debugger::RegisterCodeBreakpoint(CodeBreakpoint* bpt) {
2582 ASSERT(bpt->next() == NULL); 2582 ASSERT(bpt->next() == NULL);
2583 bpt->set_next(code_breakpoints_); 2583 bpt->set_next(code_breakpoints_);
2584 code_breakpoints_ = bpt; 2584 code_breakpoints_ = bpt;
2585 } 2585 }
2586 2586
2587 } // namespace dart 2587 } // 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