| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 } | 61 } |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 65 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 66 // There are no objects to visit in this frame. | 66 // There are no objects to visit in this frame. |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 70 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 71 ASSERT(thread() == Thread::Current()); | |
| 72 // Visit objects between SP and (FP - callee_save_area). | 71 // Visit objects between SP and (FP - callee_save_area). |
| 73 ASSERT(visitor != NULL); | 72 ASSERT(visitor != NULL); |
| 74 #if !defined(TARGET_ARCH_DBC) | 73 #if !defined(TARGET_ARCH_DBC) |
| 75 RawObject** first = reinterpret_cast<RawObject**>(sp()); | 74 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
| 76 RawObject** last = reinterpret_cast<RawObject**>( | 75 RawObject** last = reinterpret_cast<RawObject**>( |
| 77 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize); | 76 fp() + (kExitLinkSlotFromEntryFp - 1) * kWordSize); |
| 78 visitor->VisitPointers(first, last); | 77 visitor->VisitPointers(first, last); |
| 79 #else | 78 #else |
| 80 // On DBC stack is growing upwards which implies fp() <= sp(). | 79 // On DBC stack is growing upwards which implies fp() <= sp(). |
| 81 RawObject** first = reinterpret_cast<RawObject**>(fp()); | 80 RawObject** first = reinterpret_cast<RawObject**>(fp()); |
| 82 RawObject** last = reinterpret_cast<RawObject**>(sp()); | 81 RawObject** last = reinterpret_cast<RawObject**>(sp()); |
| 83 visitor->VisitPointers(first, last); | 82 visitor->VisitPointers(first, last); |
| 84 #endif | 83 #endif |
| 85 } | 84 } |
| 86 | 85 |
| 87 | 86 |
| 88 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 87 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 89 ASSERT(thread() == Thread::Current()); | |
| 90 ASSERT(visitor != NULL); | 88 ASSERT(visitor != NULL); |
| 91 // NOTE: This code runs while GC is in progress and runs within | 89 // NOTE: This code runs while GC is in progress and runs within |
| 92 // a NoHandleScope block. Hence it is not ok to use regular Zone or | 90 // a NoHandleScope block. Hence it is not ok to use regular Zone or |
| 93 // Scope handles. We use direct stack handles, the raw pointers in | 91 // Scope handles. We use direct stack handles, the raw pointers in |
| 94 // these handles are not traversed. The use of handles is mainly to | 92 // these handles are not traversed. The use of handles is mainly to |
| 95 // be able to reuse the handle based code and avoid having to add | 93 // be able to reuse the handle based code and avoid having to add |
| 96 // helper functions to the raw object interface. | 94 // helper functions to the raw object interface. |
| 97 NoSafepointScope no_safepoint; | 95 NoSafepointScope no_safepoint; |
| 98 Code code; | 96 Code code; |
| 99 code = GetCodeObject(); | 97 code = GetCodeObject(); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 | 337 |
| 340 // Tell MemorySanitizer that generated code initializes part of the stack. | 338 // Tell MemorySanitizer that generated code initializes part of the stack. |
| 341 // TODO(koda): Limit to frames that are actually written by generated code. | 339 // TODO(koda): Limit to frames that are actually written by generated code. |
| 342 static void UnpoisonStack(uword fp) { | 340 static void UnpoisonStack(uword fp) { |
| 343 ASSERT(fp != 0); | 341 ASSERT(fp != 0); |
| 344 uword size = OSThread::GetSpecifiedStackSize(); | 342 uword size = OSThread::GetSpecifiedStackSize(); |
| 345 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size); | 343 MSAN_UNPOISON(reinterpret_cast<void*>(fp - size), 2 * size); |
| 346 } | 344 } |
| 347 | 345 |
| 348 | 346 |
| 349 StackFrameIterator::StackFrameIterator(bool validate, Thread* thread) | 347 StackFrameIterator::StackFrameIterator(bool validate, |
| 348 Thread* thread, |
| 349 bool allow_iterating_other_thread) |
| 350 : validate_(validate), | 350 : validate_(validate), |
| 351 entry_(thread), | 351 entry_(thread), |
| 352 exit_(thread), | 352 exit_(thread), |
| 353 frames_(thread), | 353 frames_(thread), |
| 354 current_frame_(NULL), | 354 current_frame_(NULL), |
| 355 thread_(thread) { | 355 thread_(thread) { |
| 356 ASSERT((thread_ == Thread::Current()) || | 356 ASSERT((allow_iterating_other_thread || thread_ == Thread::Current())); |
| 357 OS::AllowStackFrameIteratorFromAnotherThread()); | |
| 358 SetupLastExitFrameData(); // Setup data for last exit frame. | 357 SetupLastExitFrameData(); // Setup data for last exit frame. |
| 359 } | 358 } |
| 360 | 359 |
| 361 | 360 |
| 362 StackFrameIterator::StackFrameIterator(uword last_fp, | 361 StackFrameIterator::StackFrameIterator(uword last_fp, |
| 363 bool validate, | 362 bool validate, |
| 364 Thread* thread) | 363 Thread* thread, |
| 364 bool allow_iterating_other_thread) |
| 365 : validate_(validate), | 365 : validate_(validate), |
| 366 entry_(thread), | 366 entry_(thread), |
| 367 exit_(thread), | 367 exit_(thread), |
| 368 frames_(thread), | 368 frames_(thread), |
| 369 current_frame_(NULL), | 369 current_frame_(NULL), |
| 370 thread_(thread) { | 370 thread_(thread) { |
| 371 ASSERT((thread_ == Thread::Current()) || | 371 ASSERT((allow_iterating_other_thread || thread_ == Thread::Current())); |
| 372 OS::AllowStackFrameIteratorFromAnotherThread()); | |
| 373 frames_.fp_ = last_fp; | 372 frames_.fp_ = last_fp; |
| 374 frames_.sp_ = 0; | 373 frames_.sp_ = 0; |
| 375 frames_.pc_ = 0; | 374 frames_.pc_ = 0; |
| 376 } | 375 } |
| 377 | 376 |
| 378 | 377 |
| 379 #if !defined(TARGET_ARCH_DBC) | 378 #if !defined(TARGET_ARCH_DBC) |
| 380 StackFrameIterator::StackFrameIterator(uword fp, | 379 StackFrameIterator::StackFrameIterator(uword fp, |
| 381 uword sp, | 380 uword sp, |
| 382 uword pc, | 381 uword pc, |
| 383 bool validate, | 382 bool validate, |
| 384 Thread* thread) | 383 Thread* thread, |
| 384 bool allow_iterating_other_thread) |
| 385 : validate_(validate), | 385 : validate_(validate), |
| 386 entry_(thread), | 386 entry_(thread), |
| 387 exit_(thread), | 387 exit_(thread), |
| 388 frames_(thread), | 388 frames_(thread), |
| 389 current_frame_(NULL), | 389 current_frame_(NULL), |
| 390 thread_(thread) { | 390 thread_(thread) { |
| 391 ASSERT((thread_ == Thread::Current()) || | 391 ASSERT((allow_iterating_other_thread || thread_ == Thread::Current())); |
| 392 OS::AllowStackFrameIteratorFromAnotherThread()); | |
| 393 frames_.fp_ = fp; | 392 frames_.fp_ = fp; |
| 394 frames_.sp_ = sp; | 393 frames_.sp_ = sp; |
| 395 frames_.pc_ = pc; | 394 frames_.pc_ = pc; |
| 396 } | 395 } |
| 397 #endif | 396 #endif |
| 398 | 397 |
| 399 | 398 |
| 400 StackFrame* StackFrameIterator::NextFrame() { | 399 StackFrame* StackFrameIterator::NextFrame() { |
| 401 // When we are at the start of iteration after having created an | 400 // When we are at the start of iteration after having created an |
| 402 // iterator object, current_frame_ will be NULL as we haven't seen | 401 // iterator object, current_frame_ will be NULL as we haven't seen |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 return fp_offset; | 569 return fp_offset; |
| 571 } | 570 } |
| 572 } | 571 } |
| 573 UNREACHABLE(); | 572 UNREACHABLE(); |
| 574 return 0; | 573 return 0; |
| 575 } | 574 } |
| 576 | 575 |
| 577 | 576 |
| 578 #if defined(DEBUG) | 577 #if defined(DEBUG) |
| 579 void ValidateFrames() { | 578 void ValidateFrames() { |
| 580 StackFrameIterator frames(StackFrameIterator::kValidateFrames); | 579 StackFrameIterator frames(StackFrameIterator::kValidateFrames, |
| 580 Thread::Current(), false); |
| 581 StackFrame* frame = frames.NextFrame(); | 581 StackFrame* frame = frames.NextFrame(); |
| 582 while (frame != NULL) { | 582 while (frame != NULL) { |
| 583 frame = frames.NextFrame(); | 583 frame = frames.NextFrame(); |
| 584 } | 584 } |
| 585 } | 585 } |
| 586 #endif | 586 #endif |
| 587 | 587 |
| 588 | 588 |
| 589 } // namespace dart | 589 } // namespace dart |
| OLD | NEW |