| 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 |