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/stack_frame.h" | 5 #include "vm/stack_frame.h" |
6 | 6 |
7 #include "platform/memory_sanitizer.h" | 7 #include "platform/memory_sanitizer.h" |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/deopt_instructions.h" | 9 #include "vm/deopt_instructions.h" |
10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 entry_.pc_ = frames_.pc_; | 482 entry_.pc_ = frames_.pc_; |
483 SetupNextExitFrameData(); // Setup data for next exit frame in chain. | 483 SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
484 ASSERT(entry_.IsValid()); | 484 ASSERT(entry_.IsValid()); |
485 return &entry_; | 485 return &entry_; |
486 } | 486 } |
487 | 487 |
488 | 488 |
489 InlinedFunctionsIterator::InlinedFunctionsIterator(const Code& code, uword pc) | 489 InlinedFunctionsIterator::InlinedFunctionsIterator(const Code& code, uword pc) |
490 : index_(0), | 490 : index_(0), |
491 num_materializations_(0), | 491 num_materializations_(0), |
| 492 dest_frame_size_(0), |
492 code_(Code::Handle(code.raw())), | 493 code_(Code::Handle(code.raw())), |
493 deopt_info_(TypedData::Handle()), | 494 deopt_info_(TypedData::Handle()), |
494 function_(Function::Handle()), | 495 function_(Function::Handle()), |
495 pc_(pc), | 496 pc_(pc), |
496 deopt_instructions_(), | 497 deopt_instructions_(), |
497 object_table_(ObjectPool::Handle()) { | 498 object_table_(ObjectPool::Handle()) { |
498 ASSERT(code_.is_optimized()); | 499 ASSERT(code_.is_optimized()); |
499 ASSERT(pc_ != 0); | 500 ASSERT(pc_ != 0); |
500 ASSERT(code.ContainsInstructionAt(pc)); | 501 ASSERT(code.ContainsInstructionAt(pc)); |
501 ICData::DeoptReasonId deopt_reason = ICData::kDeoptUnknown; | 502 ICData::DeoptReasonId deopt_reason = ICData::kDeoptUnknown; |
502 uint32_t deopt_flags = 0; | 503 uint32_t deopt_flags = 0; |
503 deopt_info_ = code_.GetDeoptInfoAtPc(pc, &deopt_reason, &deopt_flags); | 504 deopt_info_ = code_.GetDeoptInfoAtPc(pc, &deopt_reason, &deopt_flags); |
504 if (deopt_info_.IsNull()) { | 505 if (deopt_info_.IsNull()) { |
505 // This is the case when a call without deopt info in optimized code | 506 // This is the case when a call without deopt info in optimized code |
506 // throws an exception. (e.g. in the parameter copying prologue). | 507 // throws an exception. (e.g. in the parameter copying prologue). |
507 // In that case there won't be any inlined frames. | 508 // In that case there won't be any inlined frames. |
508 function_ = code_.function(); | 509 function_ = code_.function(); |
509 } else { | 510 } else { |
510 // Unpack deopt info into instructions (translate away suffixes). | 511 // Unpack deopt info into instructions (translate away suffixes). |
511 const Array& deopt_table = Array::Handle(code_.deopt_info_array()); | 512 const Array& deopt_table = Array::Handle(code_.deopt_info_array()); |
512 ASSERT(!deopt_table.IsNull()); | 513 ASSERT(!deopt_table.IsNull()); |
513 DeoptInfo::Unpack(deopt_table, deopt_info_, &deopt_instructions_); | 514 DeoptInfo::Unpack(deopt_table, deopt_info_, &deopt_instructions_); |
514 num_materializations_ = DeoptInfo::NumMaterializations(deopt_instructions_); | 515 num_materializations_ = DeoptInfo::NumMaterializations(deopt_instructions_); |
| 516 dest_frame_size_ = DeoptInfo::FrameSize(deopt_info_); |
515 object_table_ = code_.GetObjectPool(); | 517 object_table_ = code_.GetObjectPool(); |
516 Advance(); | 518 Advance(); |
517 } | 519 } |
518 } | 520 } |
519 | 521 |
520 | 522 |
521 void InlinedFunctionsIterator::Advance() { | 523 void InlinedFunctionsIterator::Advance() { |
522 // Iterate over the deopt instructions and determine the inlined | 524 // Iterate over the deopt instructions and determine the inlined |
523 // functions if any and iterate over them. | 525 // functions if any and iterate over them. |
524 ASSERT(!Done()); | 526 ASSERT(!Done()); |
(...skipping 18 matching lines...) Expand all Loading... |
543 | 545 |
544 // Finds the potential offset for the current function's FP if the | 546 // Finds the potential offset for the current function's FP if the |
545 // current frame were to be deoptimized. | 547 // current frame were to be deoptimized. |
546 intptr_t InlinedFunctionsIterator::GetDeoptFpOffset() const { | 548 intptr_t InlinedFunctionsIterator::GetDeoptFpOffset() const { |
547 ASSERT(deopt_instructions_.length() != 0); | 549 ASSERT(deopt_instructions_.length() != 0); |
548 for (intptr_t index = index_; | 550 for (intptr_t index = index_; |
549 index < deopt_instructions_.length(); | 551 index < deopt_instructions_.length(); |
550 index++) { | 552 index++) { |
551 DeoptInstr* deopt_instr = deopt_instructions_[index]; | 553 DeoptInstr* deopt_instr = deopt_instructions_[index]; |
552 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { | 554 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { |
| 555 #if defined(TARGET_ARCH_DBC) |
| 556 // Stack on DBC is growing upwards but we record deopt commands |
| 557 // in the same order we record them on other architectures as if |
| 558 // the stack was growing downwards. |
| 559 return dest_frame_size_ - index; |
| 560 #else |
553 return (index - num_materializations_); | 561 return (index - num_materializations_); |
| 562 #endif |
554 } | 563 } |
555 } | 564 } |
556 UNREACHABLE(); | 565 UNREACHABLE(); |
557 return 0; | 566 return 0; |
558 } | 567 } |
559 | 568 |
560 | 569 |
561 } // namespace dart | 570 } // namespace dart |
OLD | NEW |