| 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 "vm/assembler_macros.h" | 7 #include "vm/assembler_macros.h" |
| 8 #include "vm/deopt_instructions.h" | 8 #include "vm/deopt_instructions.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 EntryFrame* StackFrameIterator::NextEntryFrame() { | 273 EntryFrame* StackFrameIterator::NextEntryFrame() { |
| 274 ASSERT(!frames_.HasNext()); | 274 ASSERT(!frames_.HasNext()); |
| 275 entry_.sp_ = frames_.sp_; | 275 entry_.sp_ = frames_.sp_; |
| 276 entry_.fp_ = frames_.fp_; | 276 entry_.fp_ = frames_.fp_; |
| 277 SetupNextExitFrameData(); // Setup data for next exit frame in chain. | 277 SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
| 278 ASSERT(entry_.IsValid()); | 278 ASSERT(entry_.IsValid()); |
| 279 return &entry_; | 279 return &entry_; |
| 280 } | 280 } |
| 281 | 281 |
| 282 | 282 |
| 283 InlinedFunctionsInDartFrameIterator::InlinedFunctionsInDartFrameIterator( | 283 InlinedFunctionsIterator::InlinedFunctionsIterator(StackFrame* frame) |
| 284 StackFrame* frame) : index_(0), | 284 : index_(0), |
| 285 deopt_instructions_(), | 285 code_(Code::Handle()), |
| 286 object_table_(Array::Handle()) { | 286 deopt_info_(DeoptInfo::Handle()), |
| 287 function_(Function::Handle()), |
| 288 pc_(0), |
| 289 deopt_instructions_(), |
| 290 object_table_(Array::Handle()) { |
| 287 ASSERT(frame != NULL); | 291 ASSERT(frame != NULL); |
| 288 const Code& code = Code::Handle(frame->LookupDartCode()); | 292 code_ = frame->LookupDartCode(); |
| 289 ASSERT(code.is_optimized()); | 293 ASSERT(code_.is_optimized()); |
| 290 intptr_t deopt_reason = kDeoptUnknown; | 294 intptr_t deopt_reason = kDeoptUnknown; |
| 291 const DeoptInfo& deopt_info = DeoptInfo::Handle( | 295 deopt_info_ = code_.GetDeoptInfoAtPc(frame->pc(), &deopt_reason); |
| 292 code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason)); | 296 if (deopt_info_.IsNull()) { |
| 293 ASSERT(!deopt_info.IsNull()); | 297 // This is the case when a call without deopt info in optimzed code |
| 294 | 298 // throws an exception. (e.g. in the parameter copying prologue). |
| 295 // Unpack deopt info into instructions (translate away suffixes). | 299 // In that case there won't be any inlined frames. |
| 296 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | 300 function_ = code_.function(); |
| 297 ASSERT(!deopt_table.IsNull()); | 301 pc_ = frame->pc(); |
| 298 deopt_info.ToInstructions(deopt_table, &deopt_instructions_); | 302 ASSERT(pc_ != 0); |
| 299 | 303 } else { |
| 300 object_table_ = code.object_table(); | 304 // Unpack deopt info into instructions (translate away suffixes). |
| 305 const Array& deopt_table = Array::Handle(code_.deopt_info_array()); |
| 306 ASSERT(!deopt_table.IsNull()); |
| 307 deopt_info_.ToInstructions(deopt_table, &deopt_instructions_); |
| 308 object_table_ = code_.object_table(); |
| 309 Advance(); |
| 310 } |
| 301 } | 311 } |
| 302 | 312 |
| 303 | 313 |
| 304 RawFunction* InlinedFunctionsInDartFrameIterator::GetNextFunction(uword* pc) { | 314 void InlinedFunctionsIterator::Advance() { |
| 305 if (index_ == -1) { | 315 // Iterate over the deopt instructions and determine the inlined |
| 306 return Function::null(); | 316 // functions if any and iterate over them. |
| 317 ASSERT(!Done()); |
| 318 |
| 319 if (deopt_info_.IsNull()) { |
| 320 SetDone(); |
| 321 return; |
| 307 } | 322 } |
| 308 | 323 |
| 309 // Iterate over the deopt instructions and determine the inlined | |
| 310 // functions if any and iterate over them. | |
| 311 Function& func = Function::Handle(); | 324 Function& func = Function::Handle(); |
| 312 ASSERT(deopt_instructions_.length() != 0); | 325 ASSERT(deopt_instructions_.length() != 0); |
| 313 while (index_ < deopt_instructions_.length()) { | 326 while (index_ < deopt_instructions_.length()) { |
| 314 DeoptInstr* deopt_instr = deopt_instructions_[index_++]; | 327 DeoptInstr* deopt_instr = deopt_instructions_[index_++]; |
| 315 ASSERT(deopt_instr->kind() != DeoptInstr::kRetBeforeAddress); | 328 ASSERT(deopt_instr->kind() != DeoptInstr::kRetBeforeAddress); |
| 316 if (deopt_instr->kind() == DeoptInstr::kRetAfterAddress) { | 329 if (deopt_instr->kind() == DeoptInstr::kRetAfterAddress) { |
| 317 *pc = DeoptInstr::GetRetAfterAddress(deopt_instr, | 330 pc_ = DeoptInstr::GetRetAfterAddress(deopt_instr, |
| 318 object_table_, | 331 object_table_, |
| 319 &func); | 332 &func); |
| 320 return func.raw(); | 333 code_ = func.unoptimized_code(); |
| 334 function_ = func.raw(); |
| 335 return; |
| 321 } | 336 } |
| 322 } | 337 } |
| 323 index_ = -1; | 338 SetDone(); |
| 324 return Function::null(); | |
| 325 } | 339 } |
| 326 | 340 |
| 327 } // namespace dart | 341 } // namespace dart |
| OLD | NEW |