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 #ifndef VM_STACK_FRAME_H_ | 5 #ifndef VM_STACK_FRAME_H_ |
6 #define VM_STACK_FRAME_H_ | 6 #define VM_STACK_FRAME_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/stub_code.h" | 10 #include "vm/stub_code.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 RawFunction* LookupDartFunction() const; | 78 RawFunction* LookupDartFunction() const; |
79 RawCode* LookupDartCode() const; | 79 RawCode* LookupDartCode() const; |
80 bool FindExceptionHandler(Thread* thread, | 80 bool FindExceptionHandler(Thread* thread, |
81 uword* handler_pc, | 81 uword* handler_pc, |
82 bool* needs_stacktrace, | 82 bool* needs_stacktrace, |
83 bool* is_catch_all) const; | 83 bool* is_catch_all) const; |
84 // Returns token_pos of the pc(), or -1 if none exists. | 84 // Returns token_pos of the pc(), or -1 if none exists. |
85 intptr_t GetTokenPos() const; | 85 intptr_t GetTokenPos() const; |
86 | 86 |
87 protected: | 87 protected: |
88 explicit StackFrame(Isolate* isolate) | 88 explicit StackFrame(Thread* thread) |
89 : fp_(0), sp_(0), pc_(0), isolate_(isolate) { } | 89 : fp_(0), sp_(0), pc_(0), thread_(thread) { } |
90 | 90 |
91 // Name of the frame, used for generic frame printing functionality. | 91 // Name of the frame, used for generic frame printing functionality. |
92 virtual const char* GetName() const { return IsStubFrame()? "stub" : "dart"; } | 92 virtual const char* GetName() const { return IsStubFrame()? "stub" : "dart"; } |
93 | 93 |
94 Isolate* isolate() const { return isolate_; } | 94 Isolate* isolate() const { return thread_->isolate(); } |
| 95 |
| 96 Thread* thread() const { return thread_; } |
95 | 97 |
96 private: | 98 private: |
97 RawCode* GetCodeObject() const; | 99 RawCode* GetCodeObject() const; |
98 | 100 |
99 uword GetCallerSp() const { | 101 uword GetCallerSp() const { |
100 return fp() + (kCallerSpSlotFromFp * kWordSize); | 102 return fp() + (kCallerSpSlotFromFp * kWordSize); |
101 } | 103 } |
102 uword GetCallerFp() const { | 104 uword GetCallerFp() const { |
103 return *(reinterpret_cast<uword*>( | 105 return *(reinterpret_cast<uword*>( |
104 fp() + (kSavedCallerFpSlotFromFp * kWordSize))); | 106 fp() + (kSavedCallerFpSlotFromFp * kWordSize))); |
105 } | 107 } |
106 uword GetCallerPc() const { | 108 uword GetCallerPc() const { |
107 return *(reinterpret_cast<uword*>( | 109 return *(reinterpret_cast<uword*>( |
108 fp() + (kSavedCallerPcSlotFromFp * kWordSize))); | 110 fp() + (kSavedCallerPcSlotFromFp * kWordSize))); |
109 } | 111 } |
110 | 112 |
111 uword fp_; | 113 uword fp_; |
112 uword sp_; | 114 uword sp_; |
113 uword pc_; | 115 uword pc_; |
114 Isolate* isolate_; | 116 Thread* thread_; |
115 | 117 |
116 // The iterators FrameSetIterator and StackFrameIterator set the private | 118 // The iterators FrameSetIterator and StackFrameIterator set the private |
117 // fields fp_ and sp_ when they return the respective frame objects. | 119 // fields fp_ and sp_ when they return the respective frame objects. |
118 friend class FrameSetIterator; | 120 friend class FrameSetIterator; |
119 friend class StackFrameIterator; | 121 friend class StackFrameIterator; |
120 DISALLOW_COPY_AND_ASSIGN(StackFrame); | 122 DISALLOW_COPY_AND_ASSIGN(StackFrame); |
121 }; | 123 }; |
122 | 124 |
123 | 125 |
124 // Exit frame is used to mark the transition from dart code into dart VM | 126 // Exit frame is used to mark the transition from dart code into dart VM |
125 // runtime code. | 127 // runtime code. |
126 class ExitFrame : public StackFrame { | 128 class ExitFrame : public StackFrame { |
127 public: | 129 public: |
128 bool IsValid() const { return sp() == 0; } | 130 bool IsValid() const { return sp() == 0; } |
129 bool IsDartFrame(bool validate = true) const { return false; } | 131 bool IsDartFrame(bool validate = true) const { return false; } |
130 bool IsStubFrame() const { return false; } | 132 bool IsStubFrame() const { return false; } |
131 bool IsExitFrame() const { return true; } | 133 bool IsExitFrame() const { return true; } |
132 | 134 |
133 // Visit objects in the frame. | 135 // Visit objects in the frame. |
134 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | 136 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
135 | 137 |
136 protected: | 138 protected: |
137 virtual const char* GetName() const { return "exit"; } | 139 virtual const char* GetName() const { return "exit"; } |
138 | 140 |
139 private: | 141 private: |
140 explicit ExitFrame(Isolate* isolate) : StackFrame(isolate) { } | 142 explicit ExitFrame(Thread* thread) : StackFrame(thread) { } |
141 | 143 |
142 friend class StackFrameIterator; | 144 friend class StackFrameIterator; |
143 DISALLOW_COPY_AND_ASSIGN(ExitFrame); | 145 DISALLOW_COPY_AND_ASSIGN(ExitFrame); |
144 }; | 146 }; |
145 | 147 |
146 | 148 |
147 // Entry Frame is used to mark the transition from dart VM runtime code into | 149 // Entry Frame is used to mark the transition from dart VM runtime code into |
148 // dart code. | 150 // dart code. |
149 class EntryFrame : public StackFrame { | 151 class EntryFrame : public StackFrame { |
150 public: | 152 public: |
151 bool IsValid() const { | 153 bool IsValid() const { |
152 return StubCode::InInvocationStub(pc()); | 154 return StubCode::InInvocationStub(pc()); |
153 } | 155 } |
154 bool IsDartFrame(bool validate = true) const { return false; } | 156 bool IsDartFrame(bool validate = true) const { return false; } |
155 bool IsStubFrame() const { return false; } | 157 bool IsStubFrame() const { return false; } |
156 bool IsEntryFrame() const { return true; } | 158 bool IsEntryFrame() const { return true; } |
157 | 159 |
158 // Visit objects in the frame. | 160 // Visit objects in the frame. |
159 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | 161 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
160 | 162 |
161 protected: | 163 protected: |
162 virtual const char* GetName() const { return "entry"; } | 164 virtual const char* GetName() const { return "entry"; } |
163 | 165 |
164 private: | 166 private: |
165 explicit EntryFrame(Isolate* isolate) : StackFrame(isolate) { } | 167 explicit EntryFrame(Thread* thread) : StackFrame(thread) { } |
166 | 168 |
167 friend class StackFrameIterator; | 169 friend class StackFrameIterator; |
168 DISALLOW_COPY_AND_ASSIGN(EntryFrame); | 170 DISALLOW_COPY_AND_ASSIGN(EntryFrame); |
169 }; | 171 }; |
170 | 172 |
171 | 173 |
172 // A StackFrameIterator can be initialized with an isolate other than the | 174 // A StackFrameIterator can be initialized with a thread other than the |
173 // current thread's isolate. Because this is generally a bad idea, | 175 // current thread. Because this is generally a bad idea, it is only allowed on |
174 // it is only allowed on Windows- where it is needed for the profiler. | 176 // Windows- where it is needed for the profiler. It is the responsibility of |
175 // It is the responsibility of users of StackFrameIterator to ensure that the | 177 // users of StackFrameIterator to ensure that the thread given is not running |
176 // isolate given is not running concurrently on another thread. | 178 // concurrently. |
177 class StackFrameIterator : public ValueObject { | 179 class StackFrameIterator : public ValueObject { |
178 public: | 180 public: |
179 static const bool kValidateFrames = true; | 181 static const bool kValidateFrames = true; |
180 static const bool kDontValidateFrames = false; | 182 static const bool kDontValidateFrames = false; |
181 | 183 |
182 // Iterators for iterating over all frames from the last ExitFrame to the | 184 // Iterators for iterating over all frames from the last ExitFrame to the |
183 // first EntryFrame. | 185 // first EntryFrame. |
184 explicit StackFrameIterator(bool validate, | 186 StackFrameIterator(bool validate, |
185 Isolate* isolate = Isolate::Current()); | 187 Thread* thread = Thread::Current()); |
186 StackFrameIterator(uword last_fp, bool validate, | 188 StackFrameIterator(uword last_fp, bool validate, |
187 Isolate* isolate = Isolate::Current()); | 189 Thread* thread = Thread::Current()); |
188 | 190 |
189 // Iterator for iterating over all frames from the current frame (given by its | 191 // Iterator for iterating over all frames from the current frame (given by its |
190 // fp, sp, and pc) to the first EntryFrame. | 192 // fp, sp, and pc) to the first EntryFrame. |
191 StackFrameIterator(uword fp, uword sp, uword pc, bool validate, | 193 StackFrameIterator(uword fp, uword sp, uword pc, bool validate, |
192 Isolate* isolate = Isolate::Current()); | 194 Thread* thread = Thread::Current()); |
193 | 195 |
194 // Checks if a next frame exists. | 196 // Checks if a next frame exists. |
195 bool HasNextFrame() const { return frames_.fp_ != 0; } | 197 bool HasNextFrame() const { return frames_.fp_ != 0; } |
196 | 198 |
197 // Get next frame. | 199 // Get next frame. |
198 StackFrame* NextFrame(); | 200 StackFrame* NextFrame(); |
199 | 201 |
200 bool validate() const { return validate_; } | 202 bool validate() const { return validate_; } |
201 | 203 |
202 private: | 204 private: |
203 // Iterator for iterating over the set of frames (dart or stub) which exist | 205 // Iterator for iterating over the set of frames (dart or stub) which exist |
204 // in one EntryFrame and ExitFrame block. | 206 // in one EntryFrame and ExitFrame block. |
205 class FrameSetIterator : public ValueObject { | 207 class FrameSetIterator : public ValueObject { |
206 public: | 208 public: |
207 // Checks if a next non entry/exit frame exists in the set. | 209 // Checks if a next non entry/exit frame exists in the set. |
208 bool HasNext() const { | 210 bool HasNext() const { |
209 if (fp_ == 0) { | 211 if (fp_ == 0) { |
210 return false; | 212 return false; |
211 } | 213 } |
212 const uword pc = *(reinterpret_cast<uword*>( | 214 const uword pc = *(reinterpret_cast<uword*>( |
213 sp_ + (kSavedPcSlotFromSp * kWordSize))); | 215 sp_ + (kSavedPcSlotFromSp * kWordSize))); |
214 return !StubCode::InInvocationStub(pc); | 216 return !StubCode::InInvocationStub(pc); |
215 } | 217 } |
216 | 218 |
217 // Get next non entry/exit frame in the set (assumes a next frame exists). | 219 // Get next non entry/exit frame in the set (assumes a next frame exists). |
218 StackFrame* NextFrame(bool validate); | 220 StackFrame* NextFrame(bool validate); |
219 | 221 |
220 private: | 222 private: |
221 explicit FrameSetIterator(Isolate* isolate) | 223 explicit FrameSetIterator(Thread* thread) |
222 : fp_(0), sp_(0), pc_(0), stack_frame_(isolate), isolate_(isolate) { } | 224 : fp_(0), sp_(0), pc_(0), stack_frame_(thread), thread_(thread) { } |
223 uword fp_; | 225 uword fp_; |
224 uword sp_; | 226 uword sp_; |
225 uword pc_; | 227 uword pc_; |
226 StackFrame stack_frame_; // Singleton frame returned by NextFrame(). | 228 StackFrame stack_frame_; // Singleton frame returned by NextFrame(). |
227 Isolate* isolate_; | 229 Thread* thread_; |
228 | 230 |
229 friend class StackFrameIterator; | 231 friend class StackFrameIterator; |
230 DISALLOW_COPY_AND_ASSIGN(FrameSetIterator); | 232 DISALLOW_COPY_AND_ASSIGN(FrameSetIterator); |
231 }; | 233 }; |
232 | 234 |
233 // Get next exit frame. | 235 // Get next exit frame. |
234 ExitFrame* NextExitFrame(); | 236 ExitFrame* NextExitFrame(); |
235 | 237 |
236 // Get next entry frame. | 238 // Get next entry frame. |
237 EntryFrame* NextEntryFrame(); | 239 EntryFrame* NextEntryFrame(); |
238 | 240 |
239 // Get an iterator to the next set of frames between an entry and exit | 241 // Get an iterator to the next set of frames between an entry and exit |
240 // frame. | 242 // frame. |
241 FrameSetIterator* NextFrameSet() { return &frames_; } | 243 FrameSetIterator* NextFrameSet() { return &frames_; } |
242 | 244 |
243 // Setup last or next exit frames so that we are ready to iterate over | 245 // Setup last or next exit frames so that we are ready to iterate over |
244 // stack frames. | 246 // stack frames. |
245 void SetupLastExitFrameData(); | 247 void SetupLastExitFrameData(); |
246 void SetupNextExitFrameData(); | 248 void SetupNextExitFrameData(); |
247 | 249 |
248 bool validate_; // Validate each frame as we traverse the frames. | 250 bool validate_; // Validate each frame as we traverse the frames. |
249 EntryFrame entry_; // Singleton entry frame returned by NextEntryFrame(). | 251 EntryFrame entry_; // Singleton entry frame returned by NextEntryFrame(). |
250 ExitFrame exit_; // Singleton exit frame returned by NextExitFrame(). | 252 ExitFrame exit_; // Singleton exit frame returned by NextExitFrame(). |
251 FrameSetIterator frames_; | 253 FrameSetIterator frames_; |
252 StackFrame* current_frame_; // Points to the current frame in the iterator. | 254 StackFrame* current_frame_; // Points to the current frame in the iterator. |
253 Isolate* isolate_; | 255 Thread* thread_; |
254 | 256 |
255 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); | 257 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); |
256 }; | 258 }; |
257 | 259 |
258 | 260 |
259 // Iterator for iterating over all dart frames (skips over exit frames, | 261 // Iterator for iterating over all dart frames (skips over exit frames, |
260 // entry frames and stub frames). | 262 // entry frames and stub frames). |
261 // A DartFrameIterator can be initialized with an isolate other than the | 263 // A DartFrameIterator can be initialized with an isolate other than the |
262 // current thread's isolate. Because this is generally a bad idea, | 264 // current thread's isolate. Because this is generally a bad idea, |
263 // it is only allowed on Windows- where it is needed for the profiler. | 265 // it is only allowed on Windows- where it is needed for the profiler. |
264 // It is the responsibility of users of DartFrameIterator to ensure that the | 266 // It is the responsibility of users of DartFrameIterator to ensure that the |
265 // isolate given is not running concurrently on another thread. | 267 // isolate given is not running concurrently on another thread. |
266 class DartFrameIterator : public ValueObject { | 268 class DartFrameIterator : public ValueObject { |
267 public: | 269 public: |
268 explicit DartFrameIterator(Isolate* isolate = Isolate::Current()) | 270 explicit DartFrameIterator(Thread* thread = Thread::Current()) |
269 : frames_(StackFrameIterator::kDontValidateFrames, isolate) { } | 271 : frames_(StackFrameIterator::kDontValidateFrames, thread) { } |
270 DartFrameIterator(uword last_fp, | 272 DartFrameIterator(uword last_fp, |
271 Isolate* isolate = Isolate::Current()) | 273 Thread* thread = Thread::Current()) |
272 : frames_(last_fp, StackFrameIterator::kDontValidateFrames, isolate) { } | 274 : frames_(last_fp, StackFrameIterator::kDontValidateFrames, thread) { } |
273 DartFrameIterator(uword fp, | 275 DartFrameIterator(uword fp, |
274 uword sp, | 276 uword sp, |
275 uword pc, | 277 uword pc, |
276 Isolate* isolate = Isolate::Current()) | 278 Thread* thread = Thread::Current()) |
277 : frames_(fp, sp, pc, StackFrameIterator::kDontValidateFrames, isolate) { | 279 : frames_(fp, sp, pc, |
| 280 StackFrameIterator::kDontValidateFrames, thread) { |
278 } | 281 } |
279 // Get next dart frame. | 282 // Get next dart frame. |
280 StackFrame* NextFrame() { | 283 StackFrame* NextFrame() { |
281 StackFrame* frame = frames_.NextFrame(); | 284 StackFrame* frame = frames_.NextFrame(); |
282 while (frame != NULL && !frame->IsDartFrame(frames_.validate())) { | 285 while (frame != NULL && !frame->IsDartFrame(frames_.validate())) { |
283 frame = frames_.NextFrame(); | 286 frame = frames_.NextFrame(); |
284 } | 287 } |
285 return frame; | 288 return frame; |
286 } | 289 } |
287 | 290 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
329 uword pc_; | 332 uword pc_; |
330 GrowableArray<DeoptInstr*> deopt_instructions_; | 333 GrowableArray<DeoptInstr*> deopt_instructions_; |
331 ObjectPool& object_table_; | 334 ObjectPool& object_table_; |
332 | 335 |
333 DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator); | 336 DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator); |
334 }; | 337 }; |
335 | 338 |
336 } // namespace dart | 339 } // namespace dart |
337 | 340 |
338 #endif // VM_STACK_FRAME_H_ | 341 #endif // VM_STACK_FRAME_H_ |
OLD | NEW |