| 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 |