| 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.h" | 7 #include "vm/assembler.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 10 matching lines...) Expand all Loading... |
| 21 | 21 |
| 22 bool StackFrame::IsStubFrame() const { | 22 bool StackFrame::IsStubFrame() const { |
| 23 ASSERT(!(IsEntryFrame() || IsExitFrame())); | 23 ASSERT(!(IsEntryFrame() || IsExitFrame())); |
| 24 uword saved_pc = | 24 uword saved_pc = |
| 25 *(reinterpret_cast<uword*>(fp() + (kPcMarkerSlotFromFp * kWordSize))); | 25 *(reinterpret_cast<uword*>(fp() + (kPcMarkerSlotFromFp * kWordSize))); |
| 26 return (saved_pc == 0); | 26 return (saved_pc == 0); |
| 27 } | 27 } |
| 28 | 28 |
| 29 | 29 |
| 30 const char* StackFrame::ToCString() const { | 30 const char* StackFrame::ToCString() const { |
| 31 ASSERT(isolate_ == Isolate::Current()); |
| 31 Zone* zone = Isolate::Current()->current_zone(); | 32 Zone* zone = Isolate::Current()->current_zone(); |
| 32 if (IsDartFrame()) { | 33 if (IsDartFrame()) { |
| 33 const Code& code = Code::Handle(LookupDartCode()); | 34 const Code& code = Code::Handle(LookupDartCode()); |
| 34 ASSERT(!code.IsNull()); | 35 ASSERT(!code.IsNull()); |
| 35 const Object& owner = Object::Handle(code.owner()); | 36 const Object& owner = Object::Handle(code.owner()); |
| 36 ASSERT(!owner.IsNull()); | 37 ASSERT(!owner.IsNull()); |
| 37 if (owner.IsFunction()) { | 38 if (owner.IsFunction()) { |
| 38 const Function& function = Function::Cast(owner); | 39 const Function& function = Function::Cast(owner); |
| 39 return zone->PrintToString( | 40 return zone->PrintToString( |
| 40 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s ]", | 41 "[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px ") %s ]", |
| (...skipping 18 matching lines...) Expand all Loading... |
| 59 } | 60 } |
| 60 | 61 |
| 61 | 62 |
| 62 RawContext* EntryFrame::SavedContext() const { | 63 RawContext* EntryFrame::SavedContext() const { |
| 63 return *(reinterpret_cast<RawContext**>( | 64 return *(reinterpret_cast<RawContext**>( |
| 64 fp() + (kSavedContextSlotFromEntryFp * kWordSize))); | 65 fp() + (kSavedContextSlotFromEntryFp * kWordSize))); |
| 65 } | 66 } |
| 66 | 67 |
| 67 | 68 |
| 68 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 69 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 70 ASSERT(isolate() == Isolate::Current()); |
| 69 // Visit objects between SP and (FP - callee_save_area). | 71 // Visit objects between SP and (FP - callee_save_area). |
| 70 ASSERT(visitor != NULL); | 72 ASSERT(visitor != NULL); |
| 71 RawObject** first = reinterpret_cast<RawObject**>(sp()); | 73 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
| 72 RawObject** last = reinterpret_cast<RawObject**>( | 74 RawObject** last = reinterpret_cast<RawObject**>( |
| 73 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize); | 75 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize); |
| 74 visitor->VisitPointers(first, last); | 76 visitor->VisitPointers(first, last); |
| 75 } | 77 } |
| 76 | 78 |
| 77 | 79 |
| 78 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 80 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 79 // NOTE: This code runs while GC is in progress and runs within | 81 // NOTE: This code runs while GC is in progress and runs within |
| 80 // a NoHandleScope block. Hence it is not ok to use regular Zone or | 82 // a NoHandleScope block. Hence it is not ok to use regular Zone or |
| 81 // Scope handles. We use direct stack handles, the raw pointers in | 83 // Scope handles. We use direct stack handles, the raw pointers in |
| 82 // these handles are not traversed. The use of handles is mainly to | 84 // these handles are not traversed. The use of handles is mainly to |
| 83 // be able to reuse the handle based code and avoid having to add | 85 // be able to reuse the handle based code and avoid having to add |
| 84 // helper functions to the raw object interface. | 86 // helper functions to the raw object interface. |
| 87 ASSERT(isolate_ == Isolate::Current()); |
| 85 ASSERT(visitor != NULL); | 88 ASSERT(visitor != NULL); |
| 86 NoGCScope no_gc; | 89 NoGCScope no_gc; |
| 87 Code code; | 90 Code code; |
| 88 code = LookupDartCode(); | 91 code = LookupDartCode(); |
| 89 if (!code.IsNull()) { | 92 if (!code.IsNull()) { |
| 90 // Visit the code object. | 93 // Visit the code object. |
| 91 RawObject* raw_code = code.raw(); | 94 RawObject* raw_code = code.raw(); |
| 92 visitor->VisitPointer(&raw_code); | 95 visitor->VisitPointer(&raw_code); |
| 93 | 96 |
| 94 // Optimized frames have a stack map. We need to visit the frame based | 97 // Optimized frames have a stack map. We need to visit the frame based |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 // For normal unoptimized Dart frames and Stub frames each slot | 155 // For normal unoptimized Dart frames and Stub frames each slot |
| 153 // between the first and last included are tagged objects. | 156 // between the first and last included are tagged objects. |
| 154 RawObject** first = reinterpret_cast<RawObject**>(sp()); | 157 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
| 155 RawObject** last = reinterpret_cast<RawObject**>( | 158 RawObject** last = reinterpret_cast<RawObject**>( |
| 156 fp() + (kFirstObjectSlotFromFp * kWordSize)); | 159 fp() + (kFirstObjectSlotFromFp * kWordSize)); |
| 157 visitor->VisitPointers(first, last); | 160 visitor->VisitPointers(first, last); |
| 158 } | 161 } |
| 159 | 162 |
| 160 | 163 |
| 161 RawFunction* StackFrame::LookupDartFunction() const { | 164 RawFunction* StackFrame::LookupDartFunction() const { |
| 165 ASSERT(isolate_ == Isolate::Current()); |
| 162 const Code& code = Code::Handle(LookupDartCode()); | 166 const Code& code = Code::Handle(LookupDartCode()); |
| 163 if (!code.IsNull()) { | 167 if (!code.IsNull()) { |
| 164 return code.function(); | 168 return code.function(); |
| 165 } | 169 } |
| 166 return Function::null(); | 170 return Function::null(); |
| 167 } | 171 } |
| 168 | 172 |
| 169 | 173 |
| 170 RawCode* StackFrame::LookupDartCode() const { | 174 RawCode* StackFrame::LookupDartCode() const { |
| 175 ASSERT(isolate_ == Isolate::Current()); |
| 171 // We add a no gc scope to ensure that the code below does not trigger | 176 // We add a no gc scope to ensure that the code below does not trigger |
| 172 // a GC as we are handling raw object references here. It is possible | 177 // a GC as we are handling raw object references here. It is possible |
| 173 // that the code is called while a GC is in progress, that is ok. | 178 // that the code is called while a GC is in progress, that is ok. |
| 174 NoGCScope no_gc; | 179 NoGCScope no_gc; |
| 175 RawCode* code = GetCodeObject(); | 180 RawCode* code = GetCodeObject(); |
| 176 ASSERT(code == Code::null() || code->ptr()->owner_ != Function::null()); | 181 ASSERT(code == Code::null() || code->ptr()->owner_ != Function::null()); |
| 177 return code; | 182 return code; |
| 178 } | 183 } |
| 179 | 184 |
| 180 | 185 |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 276 |
| 272 void StackFrameIterator::SetupNextExitFrameData() { | 277 void StackFrameIterator::SetupNextExitFrameData() { |
| 273 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); | 278 uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); |
| 274 uword exit_marker = *reinterpret_cast<uword*>(exit_address); | 279 uword exit_marker = *reinterpret_cast<uword*>(exit_address); |
| 275 frames_.fp_ = exit_marker; | 280 frames_.fp_ = exit_marker; |
| 276 frames_.sp_ = 0; | 281 frames_.sp_ = 0; |
| 277 frames_.pc_ = 0; | 282 frames_.pc_ = 0; |
| 278 } | 283 } |
| 279 | 284 |
| 280 | 285 |
| 281 StackFrameIterator::StackFrameIterator(bool validate) | 286 StackFrameIterator::StackFrameIterator(bool validate, Isolate* isolate) |
| 282 : validate_(validate), entry_(), exit_(), current_frame_(NULL) { | 287 : validate_(validate), |
| 288 entry_(isolate), |
| 289 exit_(isolate), |
| 290 frames_(isolate), |
| 291 current_frame_(NULL), |
| 292 isolate_(isolate) { |
| 293 ASSERT((isolate_ == Isolate::Current()) || |
| 294 OS::AllowStackFrameIteratorFromAnotherThread()); |
| 283 SetupLastExitFrameData(); // Setup data for last exit frame. | 295 SetupLastExitFrameData(); // Setup data for last exit frame. |
| 284 } | 296 } |
| 285 | 297 |
| 286 | 298 |
| 287 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate) | 299 StackFrameIterator::StackFrameIterator(uword last_fp, bool validate, |
| 288 : validate_(validate), entry_(), exit_(), current_frame_(NULL) { | 300 Isolate* isolate) |
| 301 : validate_(validate), |
| 302 entry_(isolate), |
| 303 exit_(isolate), |
| 304 frames_(isolate), |
| 305 current_frame_(NULL), |
| 306 isolate_(isolate) { |
| 307 ASSERT((isolate_ == Isolate::Current()) || |
| 308 OS::AllowStackFrameIteratorFromAnotherThread()); |
| 289 frames_.fp_ = last_fp; | 309 frames_.fp_ = last_fp; |
| 290 frames_.sp_ = 0; | 310 frames_.sp_ = 0; |
| 291 frames_.pc_ = 0; | 311 frames_.pc_ = 0; |
| 292 } | 312 } |
| 293 | 313 |
| 294 | 314 |
| 295 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc, | 315 StackFrameIterator::StackFrameIterator(uword fp, uword sp, uword pc, |
| 296 bool validate) | 316 bool validate, Isolate* isolate) |
| 297 : validate_(validate), entry_(), exit_(), current_frame_(NULL) { | 317 : validate_(validate), |
| 318 entry_(isolate), |
| 319 exit_(isolate), |
| 320 frames_(isolate), |
| 321 current_frame_(NULL), |
| 322 isolate_(isolate) { |
| 323 ASSERT((isolate_ == Isolate::Current()) || |
| 324 OS::AllowStackFrameIteratorFromAnotherThread()); |
| 298 frames_.fp_ = fp; | 325 frames_.fp_ = fp; |
| 299 frames_.sp_ = sp; | 326 frames_.sp_ = sp; |
| 300 frames_.pc_ = pc; | 327 frames_.pc_ = pc; |
| 301 } | 328 } |
| 302 | 329 |
| 303 | 330 |
| 304 StackFrame* StackFrameIterator::NextFrame() { | 331 StackFrame* StackFrameIterator::NextFrame() { |
| 305 // When we are at the start of iteration after having created an | 332 // When we are at the start of iteration after having created an |
| 306 // iterator object, current_frame_ will be NULL as we haven't seen | 333 // iterator object, current_frame_ will be NULL as we haven't seen |
| 307 // any frames yet (unless we start iterating in the simulator from a given | 334 // any frames yet (unless we start iterating in the simulator from a given |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { | 483 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { |
| 457 return (index - num_materializations_); | 484 return (index - num_materializations_); |
| 458 } | 485 } |
| 459 } | 486 } |
| 460 UNREACHABLE(); | 487 UNREACHABLE(); |
| 461 return 0; | 488 return 0; |
| 462 } | 489 } |
| 463 | 490 |
| 464 | 491 |
| 465 } // namespace dart | 492 } // namespace dart |
| OLD | NEW |