Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: vm/stack_frame.cc

Issue 10173008: Simplify representation of stack frames. Remove the special types DartFrame/StubFrame and instead u… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « vm/stack_frame.h ('k') | vm/stack_frame_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/isolate.h" 7 #include "vm/isolate.h"
8 #include "vm/object.h" 8 #include "vm/object.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 #include "vm/os.h" 10 #include "vm/os.h"
11 #include "vm/raw_object.h" 11 #include "vm/raw_object.h"
12 #include "vm/stub_code.h" 12 #include "vm/stub_code.h"
13 #include "vm/visitor.h" 13 #include "vm/visitor.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 bool StackFrame::FindRawCodeVisitor::FindObject(RawObject* obj) { 17 bool StackFrame::FindRawCodeVisitor::FindObject(RawObject* obj) {
18 return RawInstructions::ContainsPC(obj, pc_); 18 return RawInstructions::ContainsPC(obj, pc_);
19 } 19 }
20 20
21 21
22 bool StackFrame::IsStubFrame() const {
23 if (Dart::vm_isolate()->heap()->CodeContains(pc())) {
24 return true; // Common stub code is generated in the VM heap.
25 }
26 // We add a no gc scope to ensure that the code below does not trigger
27 // a GC as we are handling raw object references here. It is possible
28 // that the code is called while a GC is in progress, that is ok.
29 NoGCScope no_gc;
30 Isolate* isolate = Isolate::Current();
31 RawCode* code = StackFrame::LookupCode(isolate, pc());
32 return ((code != Code::null()) &&
33 (code->ptr()->function_ == Function::null()));
34 }
35
36
22 void StackFrame::Print() const { 37 void StackFrame::Print() const {
23 OS::Print("[%-8s : sp(%p) ]\n", GetName(), sp()); 38 OS::Print("[%-8s : sp(%p) ]\n", GetName(), sp());
24 } 39 }
25 40
26 41
27 RawCode* StackFrame::LookupCode(Isolate* isolate, uword pc) { 42 RawCode* StackFrame::LookupCode(Isolate* isolate, uword pc) {
28 // TODO(asiva): Need to add a data structure for storing a (pc, code 43 // 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 44 // object) map in order to do a quick lookup and avoid having to
30 // traverse the code heap. 45 // traverse the code heap.
31 ASSERT(isolate != NULL); 46 ASSERT(isolate != NULL);
(...skipping 18 matching lines...) Expand all
50 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 65 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
51 // Visit objects between SP and (FP - callee_save_area). 66 // Visit objects between SP and (FP - callee_save_area).
52 ASSERT(visitor != NULL); 67 ASSERT(visitor != NULL);
53 RawObject** start = reinterpret_cast<RawObject**>(sp()); 68 RawObject** start = reinterpret_cast<RawObject**>(sp());
54 RawObject** end = reinterpret_cast<RawObject**>( 69 RawObject** end = reinterpret_cast<RawObject**>(
55 fp() - kWordSize + ExitLinkOffset()); 70 fp() - kWordSize + ExitLinkOffset());
56 visitor->VisitPointers(start, end); 71 visitor->VisitPointers(start, end);
57 } 72 }
58 73
59 74
60 void DartFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { 75 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
61 // NOTE: This code runs while GC is in progress and runs within 76 // NOTE: This code runs while GC is in progress and runs within
62 // a NoHandleScope block. Hence it is not ok to use regular Zone or 77 // a NoHandleScope block. Hence it is not ok to use regular Zone or
63 // Scope handles. We use direct stack handles, the raw pointers in 78 // Scope handles. We use direct stack handles, the raw pointers in
64 // these handles are not traversed. The use of handles is mainly to 79 // these handles are not traversed. The use of handles is mainly to
65 // be able to reuse the handle based code and avoid having to add 80 // be able to reuse the handle based code and avoid having to add
66 // helper functions to the raw object interface. 81 // helper functions to the raw object interface.
67 NoGCScope no_gc; 82 NoGCScope no_gc;
68 Code code; 83 Code code;
69 code = LookupDartCode(); 84 code = LookupDartCode();
70 ASSERT(!code.IsNull()); 85 if (!code.IsNull()) {
71 Array maps; 86 Array maps;
72 maps = Array::null(); 87 maps = Array::null();
73 Stackmap map; 88 Stackmap map;
74 map = code.GetStackmap(pc(), &maps, &map); 89 map = code.GetStackmap(pc(), &maps, &map);
75 if (map.IsNull()) { 90 if (!map.IsNull()) {
76 // No stack maps are present in the code object which means this 91 // A stack map is present in the code object, use the stack map to visit
77 // frame relies on tagged pointers and hence we visit each entry 92 // frame slots which are marked as having objects.
78 // on the frame between SP and FP. 93 intptr_t bit_offset = map.MinimumBitOffset();
79 ASSERT(visitor != NULL); 94 intptr_t end_bit_offset = map.MaximumBitOffset();
80 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()), 95 while (bit_offset <= end_bit_offset) {
81 reinterpret_cast<RawObject**>(fp() - kWordSize)); 96 uword addr = (fp() - ((bit_offset + 1) * kWordSize));
82 return; 97 ASSERT(addr >= sp());
98 if (map.IsObject(bit_offset)) {
99 visitor->VisitPointer(reinterpret_cast<RawObject**>(addr));
100 }
101 bit_offset += 1;
102 }
103 return;
104 }
83 } 105 }
84 // A stack map is present in the code object, use the stack map to visit 106 // No stack maps are present in the code object which means this
85 // frame slots which are marked as having objects. 107 // frame relies on tagged pointers and hence we visit each entry
86 intptr_t bit_offset = map.MinimumBitOffset(); 108 // on the frame between SP and FP.
87 intptr_t end_bit_offset = map.MaximumBitOffset(); 109 ASSERT(visitor != NULL);
88 while (bit_offset <= end_bit_offset) { 110 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()),
89 uword addr = (fp() - ((bit_offset + 1) * kWordSize)); 111 reinterpret_cast<RawObject**>(fp() - 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 } 112 }
97 113
98 114
99 RawFunction* DartFrame::LookupDartFunction() const { 115 RawFunction* StackFrame::LookupDartFunction() const {
100 const Code& code = Code::Handle(LookupDartCode()); 116 const Code& code = Code::Handle(LookupDartCode());
101 if (!code.IsNull()) { 117 if (!code.IsNull()) {
102 return code.function(); 118 return code.function();
103 } 119 }
104 return Function::null(); 120 return Function::null();
105 } 121 }
106 122
107 123
108 RawCode* DartFrame::LookupDartCode() const { 124 RawCode* StackFrame::LookupDartCode() const {
109 // We add a no gc scope to ensure that the code below does not trigger 125 // We add a no gc scope to ensure that the code below does not trigger
110 // a GC as we are handling raw object references here. It is possible 126 // a GC as we are handling raw object references here. It is possible
111 // that the code is called while a GC is in progress, that is ok. 127 // that the code is called while a GC is in progress, that is ok.
112 NoGCScope no_gc; 128 NoGCScope no_gc;
113 Isolate* isolate = Isolate::Current(); 129 Isolate* isolate = Isolate::Current();
114 RawCode* code = StackFrame::LookupCode(isolate, pc()); 130 RawCode* code = StackFrame::LookupCode(isolate, pc());
115 ASSERT(code != Code::null() && code->ptr()->function_ != Function::null()); 131 if ((code != Code::null()) && (code->ptr()->function_ != Function::null())) {
116 return code; 132 return code;
133 }
134 return Code::null();
117 } 135 }
118 136
119 137
120 bool DartFrame::FindExceptionHandler(uword* handler_pc) const { 138 bool StackFrame::FindExceptionHandler(uword* handler_pc) const {
121 const Code& code = Code::Handle(LookupDartCode()); 139 const Code& code = Code::Handle(LookupDartCode());
122 ASSERT(!code.IsNull()); 140 if (code.IsNull()) {
141 return false; // Stub frames do not have exception handlers.
142 }
123 143
124 // First try to find pc descriptor for the current pc. 144 // First try to find pc descriptor for the current pc.
125 intptr_t try_index = -1; 145 intptr_t try_index = -1;
126 const PcDescriptors& descriptors = 146 const PcDescriptors& descriptors =
127 PcDescriptors::Handle(code.pc_descriptors()); 147 PcDescriptors::Handle(code.pc_descriptors());
128 for (intptr_t i = 0; i < descriptors.Length(); i++) { 148 for (intptr_t i = 0; i < descriptors.Length(); i++) {
129 if (static_cast<uword>(descriptors.PC(i)) == pc() && 149 if (static_cast<uword>(descriptors.PC(i)) == pc() &&
130 descriptors.TryIndex(i) != -1) { 150 descriptors.TryIndex(i) != -1) {
131 try_index = descriptors.TryIndex(i); 151 try_index = descriptors.TryIndex(i);
132 break; 152 break;
133 } 153 }
134 } 154 }
135 if (try_index != -1) { 155 if (try_index != -1) {
136 // We found a pc descriptor, now try to see if we have an 156 // We found a pc descriptor, now try to see if we have an
137 // exception catch handler for this try index. 157 // exception catch handler for this try index.
138 const ExceptionHandlers& handlers = 158 const ExceptionHandlers& handlers =
139 ExceptionHandlers::Handle(code.exception_handlers()); 159 ExceptionHandlers::Handle(code.exception_handlers());
140 for (intptr_t j = 0; j < handlers.Length(); j++) { 160 for (intptr_t j = 0; j < handlers.Length(); j++) {
141 if (handlers.TryIndex(j) == try_index) { 161 if (handlers.TryIndex(j) == try_index) {
142 *handler_pc = handlers.HandlerPC(j); 162 *handler_pc = handlers.HandlerPC(j);
143 return true; 163 return true;
144 } 164 }
145 } 165 }
146 } 166 }
147 return false; 167 return false;
148 } 168 }
149 169
150 170
151 bool StubFrame::IsValid() const { 171 bool StackFrame::IsValid() const {
152 // We add a no gc scope to ensure that the code below does not trigger 172 if (IsEntryFrame() || IsExitFrame()) {
153 // a GC as we are handling raw object references here. It is possible 173 return true;
154 // that the code is called while a GC is in progress, that is ok. 174 }
155 NoGCScope no_gc;
156 Isolate* isolate = Isolate::Current();
157 if (Dart::vm_isolate()->heap()->CodeContains(pc())) { 175 if (Dart::vm_isolate()->heap()->CodeContains(pc())) {
158 return true; // Common stub code is generated in the VM heap. 176 return true; // Common stub code is generated in the VM heap.
159 } 177 }
160 RawCode* code = StackFrame::LookupCode(isolate, pc()); 178 return (StackFrame::LookupCode(Isolate::Current(), pc()) != Code::null());
161 return (code != Code::null() && code->ptr()->function_ == Function::null());
162 }
163
164
165 void StubFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
166 // Visit objects between SP and FP.
167 ASSERT(visitor != NULL);
168 visitor->VisitPointers(reinterpret_cast<RawObject**>(sp()),
169 reinterpret_cast<RawObject**>(fp() - kWordSize));
170 } 179 }
171 180
172 181
173 StackFrameIterator::StackFrameIterator(bool validate) 182 StackFrameIterator::StackFrameIterator(bool validate)
174 : validate_(validate), entry_(), exit_(), current_frame_(NULL) { 183 : validate_(validate), entry_(), exit_(), current_frame_(NULL) {
175 SetupLastExitFrameData(); // Setup data for last exit frame. 184 SetupLastExitFrameData(); // Setup data for last exit frame.
176 } 185 }
177 186
178 187
179 StackFrame* StackFrameIterator::NextFrame() { 188 StackFrame* StackFrameIterator::NextFrame() {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // corresponding entry frame for that set of dart/stub frames. 222 // corresponding entry frame for that set of dart/stub frames.
214 current_frame_ = 223 current_frame_ =
215 (frames_.HasNext()) ? frames_.NextFrame(validate_) : NextEntryFrame(); 224 (frames_.HasNext()) ? frames_.NextFrame(validate_) : NextEntryFrame();
216 return current_frame_; 225 return current_frame_;
217 } 226 }
218 227
219 228
220 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) { 229 StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) {
221 StackFrame* frame; 230 StackFrame* frame;
222 ASSERT(HasNext()); 231 ASSERT(HasNext());
223 if (from_stub_exitframe_) { 232 frame = &stack_frame_;
224 frame = &stub_frame_;
225 } else {
226 frame = &dart_frame_;
227 }
228 frame->sp_ = sp_; 233 frame->sp_ = sp_;
229 frame->fp_ = fp_; 234 frame->fp_ = fp_;
230 sp_ = frame->GetCallerSp(); 235 sp_ = frame->GetCallerSp();
231 fp_ = frame->GetCallerFp(); 236 fp_ = frame->GetCallerFp();
232 from_stub_exitframe_ = false;
233 ASSERT((validate == kDontValidateFrames) || frame->IsValid()); 237 ASSERT((validate == kDontValidateFrames) || frame->IsValid());
234 return frame; 238 return frame;
235 } 239 }
236 240
237 241
238 ExitFrame* StackFrameIterator::NextExitFrame() { 242 ExitFrame* StackFrameIterator::NextExitFrame() {
239 exit_.sp_ = frames_.sp_; 243 exit_.sp_ = frames_.sp_;
240 exit_.fp_ = frames_.fp_; 244 exit_.fp_ = frames_.fp_;
241 frames_.sp_ = exit_.GetCallerSp(); 245 frames_.sp_ = exit_.GetCallerSp();
242 frames_.fp_ = exit_.GetCallerFp(); 246 frames_.fp_ = exit_.GetCallerFp();
243 ASSERT(exit_.IsValid()); 247 ASSERT(exit_.IsValid());
244 return &exit_; 248 return &exit_;
245 } 249 }
246 250
247 251
248 EntryFrame* StackFrameIterator::NextEntryFrame() { 252 EntryFrame* StackFrameIterator::NextEntryFrame() {
249 ASSERT(!frames_.HasNext()); 253 ASSERT(!frames_.HasNext());
250 entry_.sp_ = frames_.sp_; 254 entry_.sp_ = frames_.sp_;
251 entry_.fp_ = frames_.fp_; 255 entry_.fp_ = frames_.fp_;
252 SetupNextExitFrameData(); // Setup data for next exit frame in chain. 256 SetupNextExitFrameData(); // Setup data for next exit frame in chain.
253 ASSERT(entry_.IsValid()); 257 ASSERT(entry_.IsValid());
254 return &entry_; 258 return &entry_;
255 } 259 }
256 260
257 } // namespace dart 261 } // namespace dart
OLDNEW
« no previous file with comments | « vm/stack_frame.h ('k') | vm/stack_frame_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698