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_macros.h" | 7 #include "vm/assembler_macros.h" |
8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 47 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
48 // NOTE: This code runs while GC is in progress and runs within | 48 // NOTE: This code runs while GC is in progress and runs within |
49 // a NoHandleScope block. Hence it is not ok to use regular Zone or | 49 // a NoHandleScope block. Hence it is not ok to use regular Zone or |
50 // Scope handles. We use direct stack handles, the raw pointers in | 50 // Scope handles. We use direct stack handles, the raw pointers in |
51 // these handles are not traversed. The use of handles is mainly to | 51 // these handles are not traversed. The use of handles is mainly to |
52 // be able to reuse the handle based code and avoid having to add | 52 // be able to reuse the handle based code and avoid having to add |
53 // helper functions to the raw object interface. | 53 // helper functions to the raw object interface. |
54 ASSERT(visitor != NULL); | 54 ASSERT(visitor != NULL); |
55 NoGCScope no_gc; | 55 NoGCScope no_gc; |
56 RawObject** start_addr = reinterpret_cast<RawObject**>(sp()); | 56 RawObject** start_addr = reinterpret_cast<RawObject**>(sp()); |
57 RawObject** end_addr = reinterpret_cast<RawObject**>( | 57 RawObject** end_addr = reinterpret_cast<RawObject**>(fp()) + |
58 fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 58 ParsedFunction::kFirstLocalSlotIndex; |
59 Code code; | 59 Code code; |
60 code = LookupDartCode(); | 60 code = LookupDartCode(); |
61 if (!code.IsNull()) { | 61 if (!code.IsNull()) { |
62 Array maps; | 62 Array maps; |
63 maps = Array::null(); | 63 maps = Array::null(); |
64 Stackmap map; | 64 Stackmap map; |
65 map = code.GetStackmap(pc(), &maps, &map); | 65 map = code.GetStackmap(pc(), &maps, &map); |
66 if (!map.IsNull()) { | 66 if (!map.IsNull()) { |
67 // A stack map is present in the code object, use the stack map to visit | 67 // A stack map is present in the code object, use the stack map to visit |
68 // frame slots which are marked as having objects. | 68 // frame slots which are marked as having objects. |
69 intptr_t end_bit_index = map.MaximumBitIndex(); | 69 intptr_t length = map.Length(); |
70 // It's possible that no bits are set. | 70 for (intptr_t bit_index = 0; bit_index < length; ++bit_index) { |
71 if (end_bit_index != Stackmap::kNoMaximum) { | 71 if (map.IsObject(bit_index)) { |
72 intptr_t bit_index = map.MinimumBitIndex(); | 72 visitor->VisitPointer(end_addr - bit_index); |
73 ASSERT(bit_index != Stackmap::kNoMinimum); | |
74 ASSERT(bit_index <= end_bit_index); | |
75 ASSERT(end_bit_index <= (end_addr - start_addr)); | |
76 while (bit_index <= end_bit_index) { | |
77 if (map.IsObject(bit_index)) { | |
78 visitor->VisitPointer(end_addr - bit_index); | |
79 } | |
80 ++bit_index; | |
81 } | 73 } |
82 } | 74 } |
83 // The stack slots that are not spill slots (i.e., outgoing arguments) | 75 // The stack slots that are not spill slots (i.e., outgoing arguments) |
84 // are tagged objects. | 76 // are tagged objects. |
85 end_addr = end_addr - (code.spill_slot_count() - 1); | 77 end_addr -= length; |
86 ASSERT(end_addr >= start_addr); | 78 // The end address can be one slot (but not more) past the start |
| 79 // address in the case that all slots were covered by the stack map. |
| 80 ASSERT((end_addr + 1) >= start_addr); |
87 } | 81 } |
88 } | 82 } |
89 // Each slot between the start and end address are tagged objects. | 83 // Each slot between the start and end address are tagged objects. |
90 visitor->VisitPointers(start_addr, end_addr); | 84 visitor->VisitPointers(start_addr, end_addr); |
91 } | 85 } |
92 | 86 |
93 | 87 |
94 RawFunction* StackFrame::LookupDartFunction() const { | 88 RawFunction* StackFrame::LookupDartFunction() const { |
95 const Code& code = Code::Handle(LookupDartCode()); | 89 const Code& code = Code::Handle(LookupDartCode()); |
96 if (!code.IsNull()) { | 90 if (!code.IsNull()) { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 EntryFrame* StackFrameIterator::NextEntryFrame() { | 242 EntryFrame* StackFrameIterator::NextEntryFrame() { |
249 ASSERT(!frames_.HasNext()); | 243 ASSERT(!frames_.HasNext()); |
250 entry_.sp_ = frames_.sp_; | 244 entry_.sp_ = frames_.sp_; |
251 entry_.fp_ = frames_.fp_; | 245 entry_.fp_ = frames_.fp_; |
252 SetupNextExitFrameData(); // Setup data for next exit frame in chain. | 246 SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
253 ASSERT(entry_.IsValid()); | 247 ASSERT(entry_.IsValid()); |
254 return &entry_; | 248 return &entry_; |
255 } | 249 } |
256 | 250 |
257 } // namespace dart | 251 } // namespace dart |
OLD | NEW |