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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 RawObject** first = reinterpret_cast<RawObject**>(fp()); | 82 RawObject** first = reinterpret_cast<RawObject**>(fp()); |
83 RawObject** last = reinterpret_cast<RawObject**>(sp()); | 83 RawObject** last = reinterpret_cast<RawObject**>(sp()); |
84 visitor->VisitPointers(first, last); | 84 visitor->VisitPointers(first, last); |
85 #endif | 85 #endif |
86 } | 86 } |
87 | 87 |
88 | 88 |
89 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 89 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
90 ASSERT(thread() == Thread::Current()); | 90 ASSERT(thread() == Thread::Current()); |
91 ASSERT(visitor != NULL); | 91 ASSERT(visitor != NULL); |
92 #if !defined(TARGET_ARCH_DBC) | |
93 // NOTE: This code runs while GC is in progress and runs within | 92 // NOTE: This code runs while GC is in progress and runs within |
94 // a NoHandleScope block. Hence it is not ok to use regular Zone or | 93 // a NoHandleScope block. Hence it is not ok to use regular Zone or |
95 // Scope handles. We use direct stack handles, the raw pointers in | 94 // Scope handles. We use direct stack handles, the raw pointers in |
96 // these handles are not traversed. The use of handles is mainly to | 95 // these handles are not traversed. The use of handles is mainly to |
97 // be able to reuse the handle based code and avoid having to add | 96 // be able to reuse the handle based code and avoid having to add |
98 // helper functions to the raw object interface. | 97 // helper functions to the raw object interface. |
99 NoSafepointScope no_safepoint; | 98 NoSafepointScope no_safepoint; |
100 Code code; | 99 Code code; |
101 code = LookupDartCode(); | 100 code = LookupDartCode(); |
102 if (!code.IsNull()) { | 101 if (!code.IsNull()) { |
103 // Visit the code object. | 102 // Visit the code object. |
104 RawObject* raw_code = code.raw(); | 103 RawObject* raw_code = code.raw(); |
105 visitor->VisitPointer(&raw_code); | 104 visitor->VisitPointer(&raw_code); |
106 | 105 |
107 // Optimized frames have a stack map. We need to visit the frame based | 106 // Optimized frames have a stack map. We need to visit the frame based |
108 // on the stack map. | 107 // on the stack map. |
109 Array maps; | 108 Array maps; |
110 maps = Array::null(); | 109 maps = Array::null(); |
111 Stackmap map; | 110 Stackmap map; |
112 const uword entry = reinterpret_cast<uword>(code.instructions()->ptr()) + | 111 const uword entry = reinterpret_cast<uword>(code.instructions()->ptr()) + |
113 Instructions::HeaderSize(); | 112 Instructions::HeaderSize(); |
114 map = code.GetStackmap(pc() - entry, &maps, &map); | 113 map = code.GetStackmap(pc() - entry, &maps, &map); |
115 if (!map.IsNull()) { | 114 if (!map.IsNull()) { |
| 115 #if !defined(TARGET_ARCH_DBC) |
116 RawObject** first = reinterpret_cast<RawObject**>(sp()); | 116 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
117 RawObject** last = reinterpret_cast<RawObject**>( | 117 RawObject** last = reinterpret_cast<RawObject**>( |
118 fp() + (kFirstLocalSlotFromFp * kWordSize)); | 118 fp() + (kFirstLocalSlotFromFp * kWordSize)); |
119 | 119 |
120 // A stack map is present in the code object, use the stack map to | 120 // A stack map is present in the code object, use the stack map to |
121 // visit frame slots which are marked as having objects. | 121 // visit frame slots which are marked as having objects. |
122 // | 122 // |
123 // The layout of the frame is (lower addresses to the right): | 123 // The layout of the frame is (lower addresses to the right): |
124 // | spill slots | outgoing arguments | saved registers | slow-path args | | 124 // | spill slots | outgoing arguments | saved registers | slow-path args | |
125 // |XXXXXXXXXXXXX|--------------------|XXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXX| | 125 // |XXXXXXXXXXXXX|--------------------|XXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXX| |
(...skipping 24 matching lines...) Expand all Loading... |
150 // in the case that all slots were covered by the stack map. | 150 // in the case that all slots were covered by the stack map. |
151 ASSERT((last + 1) >= first); | 151 ASSERT((last + 1) >= first); |
152 visitor->VisitPointers(first, last); | 152 visitor->VisitPointers(first, last); |
153 | 153 |
154 // Now visit other slots which might be part of the calling convention. | 154 // Now visit other slots which might be part of the calling convention. |
155 first = reinterpret_cast<RawObject**>( | 155 first = reinterpret_cast<RawObject**>( |
156 fp() + ((kFirstLocalSlotFromFp + 1) * kWordSize)); | 156 fp() + ((kFirstLocalSlotFromFp + 1) * kWordSize)); |
157 last = reinterpret_cast<RawObject**>( | 157 last = reinterpret_cast<RawObject**>( |
158 fp() + (kFirstObjectSlotFromFp * kWordSize)); | 158 fp() + (kFirstObjectSlotFromFp * kWordSize)); |
159 visitor->VisitPointers(first, last); | 159 visitor->VisitPointers(first, last); |
| 160 #else |
| 161 RawObject** first = reinterpret_cast<RawObject**>(fp()); |
| 162 RawObject** last = reinterpret_cast<RawObject**>(sp()); |
| 163 |
| 164 // Visit fixed prefix of the frame. |
| 165 ASSERT((first + kFirstObjectSlotFromFp) < first); |
| 166 visitor->VisitPointers(first + kFirstObjectSlotFromFp, first - 1); |
| 167 |
| 168 // A stack map is present in the code object, use the stack map to |
| 169 // visit frame slots which are marked as having objects. |
| 170 // |
| 171 // The layout of the frame is (lower addresses to the left): |
| 172 // | registers | outgoing arguments | |
| 173 // |XXXXXXXXXXX|--------------------| |
| 174 // |
| 175 // The DBC registers are described in the stack map. |
| 176 // The outgoing arguments are assumed to be tagged; the number |
| 177 // of outgoing arguments is not explicitly tracked. |
| 178 ASSERT(map.SlowPathBitCount() == 0); |
| 179 |
| 180 // Visit DBC registers that contain tagged values. |
| 181 intptr_t length = map.Length(); |
| 182 for (intptr_t bit = 0; bit < length; ++bit) { |
| 183 if (map.IsObject(bit)) { |
| 184 visitor->VisitPointer(first + bit); |
| 185 } |
| 186 } |
| 187 |
| 188 // Visit outgoing arguments. |
| 189 if ((first + length) <= last) { |
| 190 visitor->VisitPointers(first + length, last); |
| 191 } |
| 192 #endif // !defined(TARGET_ARCH_DBC) |
160 return; | 193 return; |
161 } | 194 } |
162 | 195 |
163 // No stack map, fall through. | 196 // No stack map, fall through. |
164 } | 197 } |
| 198 |
| 199 #if !defined(TARGET_ARCH_DBC) |
165 // For normal unoptimized Dart frames and Stub frames each slot | 200 // For normal unoptimized Dart frames and Stub frames each slot |
166 // between the first and last included are tagged objects. | 201 // between the first and last included are tagged objects. |
167 RawObject** first = reinterpret_cast<RawObject**>(sp()); | 202 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
168 RawObject** last = reinterpret_cast<RawObject**>( | 203 RawObject** last = reinterpret_cast<RawObject**>( |
169 fp() + (kFirstObjectSlotFromFp * kWordSize)); | 204 fp() + (kFirstObjectSlotFromFp * kWordSize)); |
170 visitor->VisitPointers(first, last); | |
171 #else | 205 #else |
172 // On DBC stack grows upwards: fp() <= sp(). | 206 // On DBC stack grows upwards: fp() <= sp(). |
173 RawObject** first = reinterpret_cast<RawObject**>( | 207 RawObject** first = reinterpret_cast<RawObject**>( |
174 fp() + (kFirstObjectSlotFromFp * kWordSize)); | 208 fp() + (kFirstObjectSlotFromFp * kWordSize)); |
175 RawObject** last = reinterpret_cast<RawObject**>(sp()); | 209 RawObject** last = reinterpret_cast<RawObject**>(sp()); |
| 210 #endif // !defined(TARGET_ARCH_DBC) |
| 211 |
176 visitor->VisitPointers(first, last); | 212 visitor->VisitPointers(first, last); |
177 #endif // !defined(TARGET_ARCH_DBC) | |
178 } | 213 } |
179 | 214 |
180 | 215 |
181 RawFunction* StackFrame::LookupDartFunction() const { | 216 RawFunction* StackFrame::LookupDartFunction() const { |
182 const Code& code = Code::Handle(LookupDartCode()); | 217 const Code& code = Code::Handle(LookupDartCode()); |
183 if (!code.IsNull()) { | 218 if (!code.IsNull()) { |
184 return code.function(); | 219 return code.function(); |
185 } | 220 } |
186 return Function::null(); | 221 return Function::null(); |
187 } | 222 } |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { | 552 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { |
518 return (index - num_materializations_); | 553 return (index - num_materializations_); |
519 } | 554 } |
520 } | 555 } |
521 UNREACHABLE(); | 556 UNREACHABLE(); |
522 return 0; | 557 return 0; |
523 } | 558 } |
524 | 559 |
525 | 560 |
526 } // namespace dart | 561 } // namespace dart |
OLD | NEW |