Chromium Code Reviews| Index: runtime/vm/stack_frame.cc |
| diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc |
| index a7b01e843b57c9cbd8bed413b6092415c021da3b..53e66170e0d6b5909ed37a2dc0b807047082b8cf 100644 |
| --- a/runtime/vm/stack_frame.cc |
| +++ b/runtime/vm/stack_frame.cc |
| @@ -51,7 +51,11 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| // these handles are not traversed. The use of handles is mainly to |
| // be able to reuse the handle based code and avoid having to add |
| // helper functions to the raw object interface. |
| + ASSERT(visitor != NULL); |
| NoGCScope no_gc; |
| + RawObject** start_addr = reinterpret_cast<RawObject**>(sp()); |
| + RawObject** end_addr = reinterpret_cast<RawObject**>( |
| + fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
| Code code; |
| code = LookupDartCode(); |
| if (!code.IsNull()) { |
| @@ -62,31 +66,28 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| if (!map.IsNull()) { |
| // A stack map is present in the code object, use the stack map to visit |
| // frame slots which are marked as having objects. |
| - intptr_t bit_index = map.MinimumBitIndex(); |
| - ASSERT(bit_index != Stackmap::kNoMinimum); |
| intptr_t end_bit_index = map.MaximumBitIndex(); |
| - ASSERT(end_bit_index != Stackmap::kNoMaximum); |
| - uword base_addr = |
| - fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize); |
| - while (bit_index <= end_bit_index) { |
| - uword addr = base_addr - (bit_index * kWordSize); |
| - ASSERT(addr >= sp()); |
| - if (map.IsObject(bit_index)) { |
| - visitor->VisitPointer(reinterpret_cast<RawObject**>(addr)); |
| + // It's possible that no bits are set. |
| + if (end_bit_index != Stackmap::kNoMaximum) { |
| + intptr_t bit_index = map.MinimumBitIndex(); |
| + ASSERT(bit_index != Stackmap::kNoMinimum); |
| + ASSERT(bit_index <= end_bit_index); |
| + ASSERT(end_bit_index <= (end_addr - start_addr)); |
| + while (bit_index <= end_bit_index) { |
| + if (map.IsObject(bit_index)) { |
| + visitor->VisitPointer(end_addr - bit_index); |
| + } |
| + ++bit_index; |
| } |
| - ++bit_index; |
| } |
| - return; |
| + // The stack slots that are not spill slots (i.e., outgoing arguments) |
| + // are tagged objects. |
| + end_addr = end_addr - (code.spill_slot_count() - 1); |
| + ASSERT(end_addr >= start_addr); |
| } |
| } |
| - // No stack maps are present in the code object which means this |
| - // frame relies on tagged pointers and hence we visit each entry |
| - // on the frame between SP and FP. |
| - ASSERT(visitor != NULL); |
| - RawObject** start = reinterpret_cast<RawObject**>(sp()); |
| - RawObject** end = reinterpret_cast<RawObject**>( |
| - fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
| - visitor->VisitPointers(start, end); |
| + // Each slot between the start and end address are tagged objects. |
| + visitor->VisitPointers(start_addr, end_addr); |
|
siva
2012/08/10 18:01:25
I think this hybrid approach of having a stack map
Vyacheslav Egorov (Google)
2012/08/10 18:11:42
I agree that it might be a little bit confusing an
|
| } |