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 RawObject* obj = isolate->heap()->FindObjectInCodeSpace(&visitor); | |
38 if (obj != Object::null()) { | |
39 RawInstructions* instr = reinterpret_cast<RawInstructions*>(obj); | |
40 return instr->ptr()->code_; | |
41 } | |
42 return Code::null(); | |
43 } | |
44 | |
45 | |
23 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 46 void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
24 // There are no objects to visit in this frame. | 47 // There are no objects to visit in this frame. |
25 } | 48 } |
26 | 49 |
27 | 50 |
28 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 51 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
29 // Visit objects between SP and (FP - callee_save_area). | 52 // Visit objects between SP and (FP - callee_save_area). |
30 ASSERT(visitor != NULL); | 53 ASSERT(visitor != NULL); |
31 RawObject** start = reinterpret_cast<RawObject**>(sp()); | 54 RawObject** start = reinterpret_cast<RawObject**>(sp()); |
32 RawObject** end = reinterpret_cast<RawObject**>( | 55 RawObject** end = reinterpret_cast<RawObject**>( |
33 fp() - kWordSize + ExitLinkOffset()); | 56 fp() - kWordSize + ExitLinkOffset()); |
34 visitor->VisitPointers(start, end); | 57 visitor->VisitPointers(start, end); |
35 } | 58 } |
36 | 59 |
37 | 60 |
38 void DartFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 61 void DartFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
39 // Visit objects between SP and FP. | 62 RawCode* code = LookupDartCode(); |
40 ASSERT(visitor != NULL); | 63 ASSERT(code != Code::null()); |
41 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), | 64 RawStackmap* map = code->GetStackmap(pc()); |
42 reinterpret_cast<RawObject**>(fp() - kWordSize)); | 65 |
66 // First visit the code object corresponding to this frame. | |
67 visitor->VisitPointer(reinterpret_cast<RawObject**>(&code)); | |
68 | |
69 // Now visit all objects on the frame. | |
70 if (map == Stackmap::null()) { | |
71 // No stack maps are present in the code object which means this | |
72 // frame relies on tagged pointers and hence we visit each entry | |
73 // on the frame between SP and FP. | |
74 ASSERT(visitor != NULL); | |
75 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), | |
76 reinterpret_cast<RawObject**>(fp() - kWordSize)); | |
77 return; | |
78 } | |
79 // A stack map is present in the code object, use the stack map to visit | |
80 // frame slots which are marked as having objects. | |
srdjan
2012/03/28 21:56:36
Can this part be tested?
siva
2012/03/29 19:01:27
Added a unit test case for this by generating a st
| |
81 intptr_t size_in_bits = map->SizeInBits(); | |
82 intptr_t bit_offset = 0; | |
83 uword addr = (fp() + (bit_offset * kWordSize)); | |
84 while (bit_offset < size_in_bits) { | |
85 ASSERT(addr <= sp()); | |
86 if (map->IsObject(bit_offset)) { | |
87 visitor->VisitPointer(reinterpret_cast<RawObject**>(addr)); | |
88 } | |
89 bit_offset += 1; | |
90 addr = (fp() + (bit_offset * kWordSize)); | |
91 } | |
43 } | 92 } |
44 | 93 |
45 | 94 |
46 RawFunction* DartFrame::LookupDartFunction() const { | 95 RawFunction* DartFrame::LookupDartFunction() const { |
47 // Get access to the code index table. | 96 const Code& code = Code::Handle(LookupDartCode()); |
48 ASSERT(Isolate::Current() != NULL); | 97 if (!code.IsNull()) { |
49 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 98 return code.function(); |
50 ASSERT(code_index_table != NULL); | 99 } |
51 return Code::Handle(code_index_table->LookupCode(pc())).function(); | 100 return Function::null(); |
52 } | 101 } |
53 | 102 |
54 | 103 |
55 RawCode* DartFrame::LookupDartCode() const { | 104 RawCode* DartFrame::LookupDartCode() const { |
56 // Get access to the code index table. | 105 // We add a no gc scope to ensure that the code below does not trigger |
57 ASSERT(Isolate::Current() != NULL); | 106 // a GC as we are handling raw object references here. It is possible |
58 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 107 // that the code is called while a GC is in progress, that is ok. |
59 ASSERT(code_index_table != NULL); | 108 NoGCScope no_gc; |
60 return code_index_table->LookupCode(pc()); | 109 Isolate* isolate = Isolate::Current(); |
110 RawCode* code = StackFrame::LookupCode(isolate, pc()); | |
111 ASSERT(code != Code::null() && code->ptr()->function_ != Function::null()); | |
112 return code; | |
61 } | 113 } |
62 | 114 |
63 | 115 |
64 bool DartFrame::FindExceptionHandler(uword* handler_pc) const { | 116 bool DartFrame::FindExceptionHandler(uword* handler_pc) const { |
65 const Code& code = Code::Handle(LookupDartCode()); | 117 const Code& code = Code::Handle(LookupDartCode()); |
66 ASSERT(!code.IsNull()); | 118 ASSERT(!code.IsNull()); |
67 | 119 |
68 // First try to find pc descriptor for the current pc. | 120 // First try to find pc descriptor for the current pc. |
69 intptr_t try_index = -1; | 121 intptr_t try_index = -1; |
70 const PcDescriptors& descriptors = | 122 const PcDescriptors& descriptors = |
(...skipping 15 matching lines...) Expand all Loading... | |
86 *handler_pc = handlers.HandlerPC(j); | 138 *handler_pc = handlers.HandlerPC(j); |
87 return true; | 139 return true; |
88 } | 140 } |
89 } | 141 } |
90 } | 142 } |
91 return false; | 143 return false; |
92 } | 144 } |
93 | 145 |
94 | 146 |
95 bool StubFrame::IsValid() const { | 147 bool StubFrame::IsValid() const { |
96 // Get access to the code index table. | 148 // We add a no gc scope to ensure that the code below does not trigger |
97 ASSERT(Isolate::Current() != NULL); | 149 // a GC as we are handling raw object references here. It is possible |
98 CodeIndexTable* code_index_table = Isolate::Current()->code_index_table(); | 150 // that the code is called while a GC is in progress, that is ok. |
99 ASSERT(code_index_table != NULL); | 151 NoGCScope no_gc; |
100 return Code::Handle(code_index_table->LookupCode(pc())).IsNull(); | 152 Isolate* isolate = Isolate::Current(); |
153 RawCode* code = StackFrame::LookupCode(isolate, pc()); | |
154 return (code != Code::null() && code->ptr()->function_ == Function::null()); | |
101 } | 155 } |
102 | 156 |
103 | 157 |
104 void StubFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 158 void StubFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
105 // Visit objects between SP and FP. | 159 // Visit objects between SP and FP. |
106 ASSERT(visitor != NULL); | 160 ASSERT(visitor != NULL); |
107 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), | 161 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), |
108 reinterpret_cast<RawObject**>(fp() - kWordSize)); | 162 reinterpret_cast<RawObject**>(fp() - kWordSize)); |
109 } | 163 } |
110 | 164 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 EntryFrame* StackFrameIterator::NextEntryFrame() { | 241 EntryFrame* StackFrameIterator::NextEntryFrame() { |
188 ASSERT(!frames_.HasNext()); | 242 ASSERT(!frames_.HasNext()); |
189 entry_.sp_ = frames_.sp_; | 243 entry_.sp_ = frames_.sp_; |
190 entry_.fp_ = frames_.fp_; | 244 entry_.fp_ = frames_.fp_; |
191 SetupNextExitFrameData(); // Setup data for next exit frame in chain. | 245 SetupNextExitFrameData(); // Setup data for next exit frame in chain. |
192 ASSERT(entry_.IsValid()); | 246 ASSERT(entry_.IsValid()); |
193 return &entry_; | 247 return &entry_; |
194 } | 248 } |
195 | 249 |
196 } // namespace dart | 250 } // namespace dart |
OLD | NEW |