Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/code_index_table.h" | |
| 8 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
| 9 #include "vm/object.h" | 8 #include "vm/object.h" |
| 10 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 11 #include "vm/os.h" | 10 #include "vm/os.h" |
| 12 #include "vm/raw_object.h" | 11 #include "vm/raw_object.h" |
| 13 #include "vm/stub_code.h" | 12 #include "vm/stub_code.h" |
| 14 #include "vm/visitor.h" | 13 #include "vm/visitor.h" |
| 15 | 14 |
| 16 namespace dart { | 15 namespace dart { |
| 17 | 16 |
| 17 bool StackFrame::FindRawCodeVisitor::FindObject(RawObject* obj) { | |
| 18 return RawInstructions::ContainsPC(obj, pc_); | |
| 19 } | |
| 20 | |
| 21 | |
| 18 void StackFrame::Print() const { | 22 void StackFrame::Print() const { |
| 19 OS::Print("[%-8s : sp(%p) ]\n", GetName(), sp()); | 23 OS::Print("[%-8s : sp(%p) ]\n", GetName(), sp()); |
| 20 } | 24 } |
| 21 | 25 |
| 22 | 26 |
| 27 RawCode* StackFrame::LookupCode(Isolate* isolate, uword pc) { | |
| 28 // TODO(asiva): Need to add a data structure for storing a (pc, code | |
| 29 // object) map in order to do a quick lookup and avoid having to | |
| 30 // traverse the code heap. | |
| 31 ASSERT(isolate != NULL); | |
| 32 // We add a no gc scope to ensure that the code below does not trigger | |
| 33 // a GC as we are handling raw object references here. It is possible | |
| 34 // that the code is called while a GC is in progress, that is ok. | |
| 35 NoGCScope no_gc; | |
| 36 FindRawCodeVisitor visitor(pc); | |
| 37 RawInstructions* instr = isolate->heap()->FindObjectInCodeSpace(&visitor); | |
| 38 if (instr != Instructions::null()) { | |
| 39 return instr->ptr()->code_; | |
| 40 } | |
| 41 return Code::null(); | |
| 42 } | |
| 43 | |
| 44 | |
| 23 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 45 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 24 // There are no objects to visit in this frame. | 46 // There are no objects to visit in this frame. |
| 25 } | 47 } |
| 26 | 48 |
| 27 | 49 |
| 28 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 50 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 29 // Visit objects between SP and (FP - callee_save_area). | 51 // Visit objects between SP and (FP - callee_save_area). |
| 30 ASSERT(visitor != NULL); | 52 ASSERT(visitor != NULL); |
| 31 RawObject** start = reinterpret_cast<RawObject**>(sp()); | 53 RawObject** start = reinterpret_cast<RawObject**>(sp()); |
| 32 RawObject** end = reinterpret_cast<RawObject**>( | 54 RawObject** end = reinterpret_cast<RawObject**>( |
| 33 fp() - kWordSize + ExitLinkOffset()); | 55 fp() - kWordSize + ExitLinkOffset()); |
| 34 visitor->VisitPointers(start, end); | 56 visitor->VisitPointers(start, end); |
| 35 } | 57 } |
| 36 | 58 |
| 37 | 59 |
| 38 void DartFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 60 void DartFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 39 // Visit objects between SP and FP. | 61 // NOTE: This code runs while GC is in progress and runs within |
| 40 ASSERT(visitor != NULL); | 62 // a NoHandleScope block. Hence it is not ok to use regular Zone or |
| 41 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), | 63 // Scope handles. We use direct stack handles, the raw pointers in |
| 42 reinterpret_cast<RawObject**>(fp() - kWordSize)); | 64 // these handles are not traversed. The use of handles is mainly to |
| 65 // be able to resuse the handle based code and avoid having to add | |
|
srdjan
2012/04/09 18:04:56
resuse -> reuse
siva
2012/04/09 18:17:32
Done.
| |
| 66 // helper functions to the raw object interface. | |
| 67 NoGCScope no_gc; | |
| 68 Code code; | |
| 69 code = LookupDartCode(); | |
| 70 ASSERT(!code.IsNull()); | |
| 71 Array maps; | |
| 72 maps = Array::null(); | |
| 73 Stackmap map; | |
| 74 map = code.GetStackmap(pc(), &maps, &map); | |
| 75 if (map.IsNull()) { | |
| 76 // No stack maps are present in the code object which means this | |
| 77 // frame relies on tagged pointers and hence we visit each entry | |
| 78 // on the frame between SP and FP. | |
| 79 ASSERT(visitor != NULL); | |
| 80 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), | |
| 81 reinterpret_cast<RawObject**>(fp() - kWordSize)); | |
| 82 return; | |
| 83 } | |
| 84 // A stack map is present in the code object, use the stack map to visit | |
| 85 // frame slots which are marked as having objects. | |
| 86 intptr_t bit_offset = map.MinimumBitOffset(); | |
| 87 intptr_t end_bit_offset = map.MaximumBitOffset(); | |
| 88 while (bit_offset <= end_bit_offset) { | |
| 89 uword addr = (fp() - ((bit_offset + 1) * kWordSize)); | |
| 90 ASSERT(addr >= sp()); | |
| 91 if (map.IsObject(bit_offset)) { | |
| 92 visitor->VisitPointer(reinterpret_cast<RawObject**>(addr)); | |
| 93 } | |
| 94 bit_offset += 1; | |
| 95 } | |
| 43 } | 96 } |
| 44 | 97 |
| 45 | 98 |
| 46 RawFunction* DartFrame::LookupDartFunction() const { | 99 RawFunction* DartFrame::LookupDartFunction() const { |
| 47 // Get access to the code index table. | 100 const Code& code = Code::Handle(LookupDartCode()); |
| 48 ASSERT(Isolate::Current() != NULL); | 101 if (!code.IsNull()) { |
| 49 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 102 return code.function(); |
| 50 ASSERT(code_index_table != NULL); | 103 } |
| 51 return Code::Handle(code_index_table->LookupCode(pc())).function(); | 104 return Function::null(); |
| 52 } | 105 } |
| 53 | 106 |
| 54 | 107 |
| 55 RawCode* DartFrame::LookupDartCode() const { | 108 RawCode* DartFrame::LookupDartCode() const { |
| 56 // Get access to the code index table. | 109 // We add a no gc scope to ensure that the code below does not trigger |
| 57 ASSERT(Isolate::Current() != NULL); | 110 // a GC as we are handling raw object references here. It is possible |
| 58 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 111 // that the code is called while a GC is in progress, that is ok. |
| 59 ASSERT(code_index_table != NULL); | 112 NoGCScope no_gc; |
| 60 return code_index_table->LookupCode(pc()); | 113 Isolate* isolate = Isolate::Current(); |
| 114 RawCode* code = StackFrame::LookupCode(isolate, pc()); | |
| 115 ASSERT(code != Code::null() && code->ptr()->function_ != Function::null()); | |
| 116 return code; | |
| 61 } | 117 } |
| 62 | 118 |
| 63 | 119 |
| 64 bool DartFrame::FindExceptionHandler(uword* handler_pc) const { | 120 bool DartFrame::FindExceptionHandler(uword* handler_pc) const { |
| 65 const Code& code = Code::Handle(LookupDartCode()); | 121 const Code& code = Code::Handle(LookupDartCode()); |
| 66 ASSERT(!code.IsNull()); | 122 ASSERT(!code.IsNull()); |
| 67 | 123 |
| 68 // First try to find pc descriptor for the current pc. | 124 // First try to find pc descriptor for the current pc. |
| 69 intptr_t try_index = -1; | 125 intptr_t try_index = -1; |
| 70 const PcDescriptors& descriptors = | 126 const PcDescriptors& descriptors = |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 86 *handler_pc = handlers.HandlerPC(j); | 142 *handler_pc = handlers.HandlerPC(j); |
| 87 return true; | 143 return true; |
| 88 } | 144 } |
| 89 } | 145 } |
| 90 } | 146 } |
| 91 return false; | 147 return false; |
| 92 } | 148 } |
| 93 | 149 |
| 94 | 150 |
| 95 bool StubFrame::IsValid() const { | 151 bool StubFrame::IsValid() const { |
| 96 // Get access to the code index table. | 152 // We add a no gc scope to ensure that the code below does not trigger |
| 97 ASSERT(Isolate::Current() != NULL); | 153 // a GC as we are handling raw object references here. It is possible |
| 98 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 154 // that the code is called while a GC is in progress, that is ok. |
| 99 ASSERT(code_index_table != NULL); | 155 NoGCScope no_gc; |
| 100 return Code::Handle(code_index_table->LookupCode(pc())).IsNull(); | 156 Isolate* isolate = Isolate::Current(); |
| 157 if (Dart::vm_isolate()->heap()->CodeContains(pc())) { | |
| 158 return true; // Common stub code is generated in the VM heap. | |
| 159 } | |
| 160 RawCode* code = StackFrame::LookupCode(isolate, pc()); | |
| 161 return (code != Code::null() && code->ptr()->function_ == Function::null()); | |
| 101 } | 162 } |
| 102 | 163 |
| 103 | 164 |
| 104 void StubFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 165 void StubFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 105 // Visit objects between SP and FP. | 166 // Visit objects between SP and FP. |
| 106 ASSERT(visitor != NULL); | 167 ASSERT(visitor != NULL); |
| 107 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), | 168 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), |
| 108 reinterpret_cast<RawObject**>(fp() - kWordSize)); | 169 reinterpret_cast<RawObject**>(fp() - kWordSize)); |
| 109 } | 170 } |
| 110 | 171 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 EntryFrame* StackFrameIterator::NextEntryFrame() { | 248 EntryFrame* StackFrameIterator::NextEntryFrame() { |
| 188 ASSERT(!frames_.HasNext()); | 249 ASSERT(!frames_.HasNext()); |
| 189 entry_.sp_ = frames_.sp_; | 250 entry_.sp_ = frames_.sp_; |
| 190 entry_.fp_ = frames_.fp_; | 251 entry_.fp_ = frames_.fp_; |
| 191 SetupNextExitFrameData(); // Setup data for next exit frame in chain. | 252 SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
| 192 ASSERT(entry_.IsValid()); | 253 ASSERT(entry_.IsValid()); |
| 193 return &entry_; | 254 return &entry_; |
| 194 } | 255 } |
| 195 | 256 |
| 196 } // namespace dart | 257 } // namespace dart |
| OLD | NEW |