| 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(ValidationPolicy validation_policy, |
| 350 : validate_(validate), | 348 Thread* thread, |
| 349 CrossThreadPolicy cross_thread_policy) |
| 350 : validate_(validation_policy == kValidateFrames), |
| 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(cross_thread_policy == kAllowCrossThreadIteration || |
| 357 OS::AllowStackFrameIteratorFromAnotherThread()); | 357 thread_ == Thread::Current()); |
| 358 SetupLastExitFrameData(); // Setup data for last exit frame. | 358 SetupLastExitFrameData(); // Setup data for last exit frame. |
| 359 } | 359 } |
| 360 | 360 |
| 361 | 361 |
| 362 StackFrameIterator::StackFrameIterator(uword last_fp, | 362 StackFrameIterator::StackFrameIterator(uword last_fp, |
| 363 bool validate, | 363 ValidationPolicy validation_policy, |
| 364 Thread* thread) | 364 Thread* thread, |
| 365 : validate_(validate), | 365 CrossThreadPolicy cross_thread_policy) |
| 366 : validate_(validation_policy == kValidateFrames), |
| 366 entry_(thread), | 367 entry_(thread), |
| 367 exit_(thread), | 368 exit_(thread), |
| 368 frames_(thread), | 369 frames_(thread), |
| 369 current_frame_(NULL), | 370 current_frame_(NULL), |
| 370 thread_(thread) { | 371 thread_(thread) { |
| 371 ASSERT((thread_ == Thread::Current()) || | 372 ASSERT(cross_thread_policy == kAllowCrossThreadIteration || |
| 372 OS::AllowStackFrameIteratorFromAnotherThread()); | 373 thread_ == Thread::Current()); |
| 373 frames_.fp_ = last_fp; | 374 frames_.fp_ = last_fp; |
| 374 frames_.sp_ = 0; | 375 frames_.sp_ = 0; |
| 375 frames_.pc_ = 0; | 376 frames_.pc_ = 0; |
| 376 } | 377 } |
| 377 | 378 |
| 378 | 379 |
| 379 #if !defined(TARGET_ARCH_DBC) | 380 #if !defined(TARGET_ARCH_DBC) |
| 380 StackFrameIterator::StackFrameIterator(uword fp, | 381 StackFrameIterator::StackFrameIterator(uword fp, |
| 381 uword sp, | 382 uword sp, |
| 382 uword pc, | 383 uword pc, |
| 383 bool validate, | 384 ValidationPolicy validation_policy, |
| 384 Thread* thread) | 385 Thread* thread, |
| 385 : validate_(validate), | 386 CrossThreadPolicy cross_thread_policy) |
| 387 : validate_(validation_policy == kValidateFrames), |
| 386 entry_(thread), | 388 entry_(thread), |
| 387 exit_(thread), | 389 exit_(thread), |
| 388 frames_(thread), | 390 frames_(thread), |
| 389 current_frame_(NULL), | 391 current_frame_(NULL), |
| 390 thread_(thread) { | 392 thread_(thread) { |
| 391 ASSERT((thread_ == Thread::Current()) || | 393 ASSERT(cross_thread_policy == kAllowCrossThreadIteration || |
| 392 OS::AllowStackFrameIteratorFromAnotherThread()); | 394 thread_ == Thread::Current()); |
| 393 frames_.fp_ = fp; | 395 frames_.fp_ = fp; |
| 394 frames_.sp_ = sp; | 396 frames_.sp_ = sp; |
| 395 frames_.pc_ = pc; | 397 frames_.pc_ = pc; |
| 396 } | 398 } |
| 397 #endif | 399 #endif |
| 398 | 400 |
| 399 | 401 |
| 400 StackFrame* StackFrameIterator::NextFrame() { | 402 StackFrame* StackFrameIterator::NextFrame() { |
| 401 // When we are at the start of iteration after having created an | 403 // 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 | 404 // 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; | 572 return fp_offset; |
| 571 } | 573 } |
| 572 } | 574 } |
| 573 UNREACHABLE(); | 575 UNREACHABLE(); |
| 574 return 0; | 576 return 0; |
| 575 } | 577 } |
| 576 | 578 |
| 577 | 579 |
| 578 #if defined(DEBUG) | 580 #if defined(DEBUG) |
| 579 void ValidateFrames() { | 581 void ValidateFrames() { |
| 580 StackFrameIterator frames(StackFrameIterator::kValidateFrames); | 582 StackFrameIterator frames(StackFrameIterator::kValidateFrames, |
| 583 Thread::Current(), |
| 584 StackFrameIterator::kNoCrossThreadIteration); |
| 581 StackFrame* frame = frames.NextFrame(); | 585 StackFrame* frame = frames.NextFrame(); |
| 582 while (frame != NULL) { | 586 while (frame != NULL) { |
| 583 frame = frames.NextFrame(); | 587 frame = frames.NextFrame(); |
| 584 } | 588 } |
| 585 } | 589 } |
| 586 #endif | 590 #endif |
| 587 | 591 |
| 588 | 592 |
| 589 } // namespace dart | 593 } // namespace dart |
| OLD | NEW |