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 |