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