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.h" | 7 #include "vm/assembler.h" |
8 #include "vm/deopt_instructions.h" | 8 #include "vm/deopt_instructions.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 | 54 |
55 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 55 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
56 // NOTE: This code runs while GC is in progress and runs within | 56 // NOTE: This code runs while GC is in progress and runs within |
57 // a NoHandleScope block. Hence it is not ok to use regular Zone or | 57 // a NoHandleScope block. Hence it is not ok to use regular Zone or |
58 // Scope handles. We use direct stack handles, the raw pointers in | 58 // Scope handles. We use direct stack handles, the raw pointers in |
59 // these handles are not traversed. The use of handles is mainly to | 59 // these handles are not traversed. The use of handles is mainly to |
60 // be able to reuse the handle based code and avoid having to add | 60 // be able to reuse the handle based code and avoid having to add |
61 // helper functions to the raw object interface. | 61 // helper functions to the raw object interface. |
62 ASSERT(visitor != NULL); | 62 ASSERT(visitor != NULL); |
63 NoGCScope no_gc; | 63 NoGCScope no_gc; |
64 RawObject** first = reinterpret_cast<RawObject**>(sp()); | |
65 RawObject** last = reinterpret_cast<RawObject**>( | |
66 fp() + (kFirstLocalSlotFromFp * kWordSize)); | |
67 Code code; | 64 Code code; |
68 code = LookupDartCode(); | 65 code = LookupDartCode(); |
69 if (!code.IsNull()) { | 66 if (!code.IsNull()) { |
70 // Visit the code object. | 67 // Visit the code object. |
71 RawObject* raw_code = code.raw(); | 68 RawObject* raw_code = code.raw(); |
72 visitor->VisitPointer(&raw_code); | 69 visitor->VisitPointer(&raw_code); |
73 // Visit stack based on stack maps. | 70 |
| 71 // Optimized frames have a stack map. We need to visit the frame based |
| 72 // on the stack map. |
74 Array maps; | 73 Array maps; |
75 maps = Array::null(); | 74 maps = Array::null(); |
76 Stackmap map; | 75 Stackmap map; |
77 map = code.GetStackmap(pc(), &maps, &map); | 76 map = code.GetStackmap(pc(), &maps, &map); |
78 if (!map.IsNull()) { | 77 if (!map.IsNull()) { |
| 78 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
| 79 RawObject** last = reinterpret_cast<RawObject**>( |
| 80 fp() + (kFirstLocalSlotFromFp * kWordSize)); |
| 81 |
79 // A stack map is present in the code object, use the stack map to | 82 // A stack map is present in the code object, use the stack map to |
80 // visit frame slots which are marked as having objects. | 83 // visit frame slots which are marked as having objects. |
81 // | 84 // |
82 // The layout of the frame is (lower addresses to the right): | 85 // The layout of the frame is (lower addresses to the right): |
83 // | spill slots | outgoing arguments | saved registers | | 86 // | spill slots | outgoing arguments | saved registers | |
84 // |XXXXXXXXXXXXX|--------------------|XXXXXXXXXXXXXXXXX| | 87 // |XXXXXXXXXXXXX|--------------------|XXXXXXXXXXXXXXXXX| |
85 // | 88 // |
86 // The splill slots and any saved registers are described in the stack | 89 // The splill slots and any saved registers are described in the stack |
87 // map. The outgoing arguments are assumed to be tagged; the number | 90 // map. The outgoing arguments are assumed to be tagged; the number |
88 // of outgoing arguments is not explicitly tracked. | 91 // of outgoing arguments is not explicitly tracked. |
(...skipping 12 matching lines...) Expand all Loading... |
101 // The live registers at the 'top' of the frame comprise the rest of the | 104 // The live registers at the 'top' of the frame comprise the rest of the |
102 // stack map. | 105 // stack map. |
103 for (intptr_t bit = length - 1; bit >= spill_slot_count; --bit) { | 106 for (intptr_t bit = length - 1; bit >= spill_slot_count; --bit) { |
104 if (map.IsObject(bit)) visitor->VisitPointer(first); | 107 if (map.IsObject(bit)) visitor->VisitPointer(first); |
105 ++first; | 108 ++first; |
106 } | 109 } |
107 | 110 |
108 // The last slot can be one slot (but not more) past the last slot | 111 // The last slot can be one slot (but not more) past the last slot |
109 // in the case that all slots were covered by the stack map. | 112 // in the case that all slots were covered by the stack map. |
110 ASSERT((last + 1) >= first); | 113 ASSERT((last + 1) >= first); |
| 114 visitor->VisitPointers(first, last); |
| 115 |
| 116 // Now visit other slots which might be part of the calling convention. |
| 117 first = reinterpret_cast<RawObject**>( |
| 118 fp() + ((kFirstLocalSlotFromFp + 1) * kWordSize)); |
| 119 last = reinterpret_cast<RawObject**>( |
| 120 fp() + (kFirstObjectSlotFromFp * kWordSize)); |
| 121 visitor->VisitPointers(first, last); |
| 122 return; |
111 } | 123 } |
112 } | 124 } |
113 // Each slot between the first and last included are tagged objects. | 125 // For normal unoptimized Dart frames and Stub frames each slot |
| 126 // between the first and last included are tagged objects. |
| 127 RawObject** first = reinterpret_cast<RawObject**>(sp()); |
| 128 RawObject** last = reinterpret_cast<RawObject**>( |
| 129 fp() + (kFirstObjectSlotFromFp * kWordSize)); |
114 visitor->VisitPointers(first, last); | 130 visitor->VisitPointers(first, last); |
115 } | 131 } |
116 | 132 |
117 | 133 |
118 RawFunction* StackFrame::LookupDartFunction() const { | 134 RawFunction* StackFrame::LookupDartFunction() const { |
119 const Code& code = Code::Handle(LookupDartCode()); | 135 const Code& code = Code::Handle(LookupDartCode()); |
120 if (!code.IsNull()) { | 136 if (!code.IsNull()) { |
121 return code.function(); | 137 return code.function(); |
122 } | 138 } |
123 return Function::null(); | 139 return Function::null(); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { | 424 if (deopt_instr->kind() == DeoptInstr::kCallerFp) { |
409 return index; | 425 return index; |
410 } | 426 } |
411 } | 427 } |
412 UNREACHABLE(); | 428 UNREACHABLE(); |
413 return 0; | 429 return 0; |
414 } | 430 } |
415 | 431 |
416 | 432 |
417 } // namespace dart | 433 } // namespace dart |
OLD | NEW |