Chromium Code Reviews| 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. |
|
Vyacheslav Egorov (Google)
2013/01/30 13:03:11
Can we verify that this is indeed a prologue that
Florian Schneider
2013/01/30 14:11:16
In the failing tests it is. But that does not excl
| |
| 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 } | |
| 301 } | 310 } |
| 302 | 311 |
| 303 | 312 |
| 304 RawFunction* InlinedFunctionsInDartFrameIterator::GetNextFunction(uword* pc) { | 313 RawFunction* InlinedFunctionsIterator::GetNextFunctionAndCode(uword* pc, |
|
Vyacheslav Egorov (Google)
2013/01/30 13:03:11
Instead of having three return values you can refa
Florian Schneider
2013/01/30 14:06:43
Done.
| |
| 314 Code* code) { | |
| 305 if (index_ == -1) { | 315 if (index_ == -1) { |
| 306 return Function::null(); | 316 return Function::null(); |
| 307 } | 317 } |
| 308 | 318 |
| 319 if (deopt_info_.IsNull()) { | |
| 320 // No deoptimization info. Return the optimized code and pc. | |
| 321 index_ = -1; | |
| 322 *pc = pc_; | |
| 323 *code = code_.raw(); | |
| 324 return function_.raw(); | |
| 325 } | |
| 326 | |
| 309 // Iterate over the deopt instructions and determine the inlined | 327 // Iterate over the deopt instructions and determine the inlined |
| 310 // functions if any and iterate over them. | 328 // functions if any and iterate over them. |
| 311 Function& func = Function::Handle(); | 329 Function& func = Function::Handle(); |
| 312 ASSERT(deopt_instructions_.length() != 0); | 330 ASSERT(deopt_instructions_.length() != 0); |
| 313 while (index_ < deopt_instructions_.length()) { | 331 while (index_ < deopt_instructions_.length()) { |
| 314 DeoptInstr* deopt_instr = deopt_instructions_[index_++]; | 332 DeoptInstr* deopt_instr = deopt_instructions_[index_++]; |
| 315 ASSERT(deopt_instr->kind() != DeoptInstr::kRetBeforeAddress); | 333 ASSERT(deopt_instr->kind() != DeoptInstr::kRetBeforeAddress); |
| 316 if (deopt_instr->kind() == DeoptInstr::kRetAfterAddress) { | 334 if (deopt_instr->kind() == DeoptInstr::kRetAfterAddress) { |
| 317 *pc = DeoptInstr::GetRetAfterAddress(deopt_instr, | 335 *pc = DeoptInstr::GetRetAfterAddress(deopt_instr, |
| 318 object_table_, | 336 object_table_, |
| 319 &func); | 337 &func); |
| 338 *code = func.unoptimized_code(); | |
| 320 return func.raw(); | 339 return func.raw(); |
| 321 } | 340 } |
| 322 } | 341 } |
| 323 index_ = -1; | 342 index_ = -1; |
| 324 return Function::null(); | 343 return Function::null(); |
| 325 } | 344 } |
| 326 | 345 |
| 327 } // namespace dart | 346 } // namespace dart |
| OLD | NEW |