Chromium Code Reviews| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 } | 44 } |
| 45 | 45 |
| 46 | 46 |
| 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 NoGCScope no_gc; | 55 NoGCScope no_gc; |
| 56 RawObject** start_addr = reinterpret_cast<RawObject**>(sp()); | |
| 57 RawObject** end_addr = reinterpret_cast<RawObject**>( | |
| 58 fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | |
| 55 Code code; | 59 Code code; |
| 56 code = LookupDartCode(); | 60 code = LookupDartCode(); |
| 57 if (!code.IsNull()) { | 61 if (!code.IsNull()) { |
| 58 Array maps; | 62 Array maps; |
| 59 maps = Array::null(); | 63 maps = Array::null(); |
| 60 Stackmap map; | 64 Stackmap map; |
| 61 map = code.GetStackmap(pc(), &maps, &map); | 65 map = code.GetStackmap(pc(), &maps, &map); |
| 62 if (!map.IsNull()) { | 66 if (!map.IsNull()) { |
| 63 // 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 |
| 64 // frame slots which are marked as having objects. | 68 // frame slots which are marked as having objects. |
| 65 intptr_t bit_index = map.MinimumBitIndex(); | |
| 66 ASSERT(bit_index != Stackmap::kNoMinimum); | |
| 67 intptr_t end_bit_index = map.MaximumBitIndex(); | 69 intptr_t end_bit_index = map.MaximumBitIndex(); |
| 68 ASSERT(end_bit_index != Stackmap::kNoMaximum); | 70 // It's possible that no bits are set. |
| 69 uword base_addr = | 71 if (end_bit_index != Stackmap::kNoMaximum) { |
| 70 fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize); | 72 intptr_t bit_index = map.MinimumBitIndex(); |
| 71 while (bit_index <= end_bit_index) { | 73 ASSERT(bit_index != Stackmap::kNoMinimum); |
| 72 uword addr = base_addr - (bit_index * kWordSize); | 74 ASSERT(bit_index <= end_bit_index); |
| 73 ASSERT(addr >= sp()); | 75 ASSERT(end_bit_index <= (end_addr - start_addr)); |
| 74 if (map.IsObject(bit_index)) { | 76 while (bit_index <= end_bit_index) { |
| 75 visitor->VisitPointer(reinterpret_cast<RawObject**>(addr)); | 77 if (map.IsObject(bit_index)) { |
| 78 visitor->VisitPointer(end_addr - bit_index); | |
| 79 } | |
| 80 ++bit_index; | |
| 76 } | 81 } |
| 77 ++bit_index; | |
| 78 } | 82 } |
| 79 return; | 83 // The stack slots that are not spill slots (i.e., outgoing arguments) |
| 84 // are tagged objects. | |
| 85 end_addr = end_addr - (code.spill_slot_count() - 1); | |
| 86 ASSERT(end_addr >= start_addr); | |
| 80 } | 87 } |
| 81 } | 88 } |
| 82 // No stack maps are present in the code object which means this | 89 // Each slot between the start and end address are tagged objects. |
| 83 // frame relies on tagged pointers and hence we visit each entry | 90 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
| |
| 84 // on the frame between SP and FP. | |
| 85 ASSERT(visitor != NULL); | |
| 86 RawObject** start = reinterpret_cast<RawObject**>(sp()); | |
| 87 RawObject** end = reinterpret_cast<RawObject**>( | |
| 88 fp() + (ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | |
| 89 visitor->VisitPointers(start, end); | |
| 90 } | 91 } |
| 91 | 92 |
| 92 | 93 |
| 93 RawFunction* StackFrame::LookupDartFunction() const { | 94 RawFunction* StackFrame::LookupDartFunction() const { |
| 94 const Code& code = Code::Handle(LookupDartCode()); | 95 const Code& code = Code::Handle(LookupDartCode()); |
| 95 if (!code.IsNull()) { | 96 if (!code.IsNull()) { |
| 96 return code.function(); | 97 return code.function(); |
| 97 } | 98 } |
| 98 return Function::null(); | 99 return Function::null(); |
| 99 } | 100 } |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 EntryFrame* StackFrameIterator::NextEntryFrame() { | 248 EntryFrame* StackFrameIterator::NextEntryFrame() { |
| 248 ASSERT(!frames_.HasNext()); | 249 ASSERT(!frames_.HasNext()); |
| 249 entry_.sp_ = frames_.sp_; | 250 entry_.sp_ = frames_.sp_; |
| 250 entry_.fp_ = frames_.fp_; | 251 entry_.fp_ = frames_.fp_; |
| 251 SetupNextExitFrameData(); // Setup data for next exit frame in chain. | 252 SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
| 252 ASSERT(entry_.IsValid()); | 253 ASSERT(entry_.IsValid()); |
| 253 return &entry_; | 254 return &entry_; |
| 254 } | 255 } |
| 255 | 256 |
| 256 } // namespace dart | 257 } // namespace dart |
| OLD | NEW |