| 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" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 // Forward declarations. | 14 // Forward declarations. |
| 15 class ObjectPointerVisitor; | 15 class ObjectPointerVisitor; |
| 16 | 16 |
| 17 | 17 |
| 18 // Generic stack frame. | 18 // Generic stack frame. |
| 19 class StackFrame : public ValueObject { | 19 class StackFrame : public ValueObject { |
| 20 public: | 20 public: |
| 21 enum FrameType { | |
| 22 kDartFrame, | |
| 23 kStubFrame, | |
| 24 kEntryFrame, | |
| 25 kExitFrame, | |
| 26 kInvalidFrame, | |
| 27 }; | |
| 28 | |
| 29 virtual ~StackFrame() { } | 21 virtual ~StackFrame() { } |
| 30 | 22 |
| 31 // Accessors to get the pc, sp and fp of a frame. | 23 // Accessors to get the pc, sp and fp of a frame. |
| 32 uword sp() const { return sp_; } | 24 uword sp() const { return sp_; } |
| 33 uword fp() const { return fp_; } | 25 uword fp() const { return fp_; } |
| 34 uword pc() const { | 26 uword pc() const { |
| 35 return *reinterpret_cast<uword*>(sp_ + PcAddressOffsetFromSp()); | 27 return *reinterpret_cast<uword*>(sp_ + PcAddressOffsetFromSp()); |
| 36 } | 28 } |
| 37 | 29 |
| 38 void set_pc(uword value) { | 30 void set_pc(uword value) { |
| 39 *reinterpret_cast<uword*>(sp_ + PcAddressOffsetFromSp()) = value; | 31 *reinterpret_cast<uword*>(sp_ + PcAddressOffsetFromSp()) = value; |
| 40 } | 32 } |
| 41 | 33 |
| 42 // Visit objects in the frame. | 34 // Visit objects in the frame. |
| 43 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor) = 0; | 35 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 44 | 36 |
| 45 // Print a frame. | 37 // Print a frame. |
| 46 virtual void Print() const; | 38 virtual void Print() const; |
| 47 | 39 |
| 48 // Check validity of a frame, used for assertion purposes. | 40 // Check validity of a frame, used for assertion purposes. |
| 49 virtual bool IsValid() const { return false; } | 41 virtual bool IsValid() const; |
| 50 | 42 |
| 51 // Frame type. | 43 // Frame type. |
| 52 virtual bool IsDartFrame() const { return false; } | 44 virtual bool IsDartFrame() const { return LookupDartCode() != Code::null(); } |
| 53 virtual bool IsStubFrame() const { return false; } | 45 virtual bool IsStubFrame() const; |
| 54 virtual bool IsEntryFrame() const { return false; } | 46 virtual bool IsEntryFrame() const { return false; } |
| 55 virtual bool IsExitFrame() const { return false; } | 47 virtual bool IsExitFrame() const { return false; } |
| 56 | 48 |
| 57 // Find code object corresponding to pc (valid only for DartFrame and | 49 RawFunction* LookupDartFunction() const; |
| 58 // StubFrame. | 50 RawCode* LookupDartCode() const; |
| 51 bool FindExceptionHandler(uword* handler_pc) const; |
| 52 |
| 53 // Find code object corresponding to pc (only frames running dart code or |
| 54 // stub code will have a code object associated with them). |
| 59 static RawCode* LookupCode(Isolate* isolate, uword pc); | 55 static RawCode* LookupCode(Isolate* isolate, uword pc); |
| 60 | 56 |
| 61 protected: | 57 protected: |
| 62 StackFrame() : fp_(0), sp_(0) { } | 58 StackFrame() : fp_(0), sp_(0) { } |
| 63 | 59 |
| 64 // Name of the frame, used for generic frame printing functionality. | 60 // Name of the frame, used for generic frame printing functionality. |
| 65 virtual const char* GetName() const = 0; | 61 virtual const char* GetName() const { return IsStubFrame()? "stub" : "dart"; } |
| 66 | 62 |
| 67 private: | 63 private: |
| 68 // An object finder visitor interface. | 64 // An object finder visitor interface. |
| 69 class FindRawCodeVisitor : public FindObjectVisitor { | 65 class FindRawCodeVisitor : public FindObjectVisitor { |
| 70 public: | 66 public: |
| 71 explicit FindRawCodeVisitor(uword pc) : pc_(pc) { } | 67 explicit FindRawCodeVisitor(uword pc) : pc_(pc) { } |
| 72 virtual ~FindRawCodeVisitor() { } | 68 virtual ~FindRawCodeVisitor() { } |
| 73 | 69 |
| 74 // Check if object matches find condition. | 70 // Check if object matches find condition. |
| 75 virtual bool FindObject(RawObject* obj); | 71 virtual bool FindObject(RawObject* obj); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 94 friend class StackFrameIterator; | 90 friend class StackFrameIterator; |
| 95 DISALLOW_COPY_AND_ASSIGN(StackFrame); | 91 DISALLOW_COPY_AND_ASSIGN(StackFrame); |
| 96 }; | 92 }; |
| 97 | 93 |
| 98 | 94 |
| 99 // Exit frame is used to mark the transition from dart code into dart VM | 95 // Exit frame is used to mark the transition from dart code into dart VM |
| 100 // runtime code. | 96 // runtime code. |
| 101 class ExitFrame : public StackFrame { | 97 class ExitFrame : public StackFrame { |
| 102 public: | 98 public: |
| 103 bool IsValid() const { return sp() == 0; } | 99 bool IsValid() const { return sp() == 0; } |
| 100 bool IsDartFrame() const { return false; } |
| 101 bool IsStubFrame() const { return false; } |
| 104 bool IsExitFrame() const { return true; } | 102 bool IsExitFrame() const { return true; } |
| 105 | 103 |
| 106 // Visit objects in the frame. | 104 // Visit objects in the frame. |
| 107 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | 105 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 108 | 106 |
| 109 protected: | 107 protected: |
| 110 virtual const char* GetName() const { return "exit"; } | 108 virtual const char* GetName() const { return "exit"; } |
| 111 | 109 |
| 112 private: | 110 private: |
| 113 ExitFrame() { } | 111 ExitFrame() { } |
| 114 | 112 |
| 115 friend class StackFrameIterator; | 113 friend class StackFrameIterator; |
| 116 DISALLOW_COPY_AND_ASSIGN(ExitFrame); | 114 DISALLOW_COPY_AND_ASSIGN(ExitFrame); |
| 117 }; | 115 }; |
| 118 | 116 |
| 119 | 117 |
| 120 // Entry Frame is used to mark the transition from dart VM runtime code into | 118 // Entry Frame is used to mark the transition from dart VM runtime code into |
| 121 // dart code. | 119 // dart code. |
| 122 class EntryFrame : public StackFrame { | 120 class EntryFrame : public StackFrame { |
| 123 public: | 121 public: |
| 124 bool IsValid() const { return StubCode::InInvocationStub(pc()); } | 122 bool IsValid() const { return StubCode::InInvocationStub(pc()); } |
| 123 bool IsDartFrame() const { return false; } |
| 124 bool IsStubFrame() const { return false; } |
| 125 bool IsEntryFrame() const { return true; } | 125 bool IsEntryFrame() const { return true; } |
| 126 | 126 |
| 127 // Visit objects in the frame. | 127 // Visit objects in the frame. |
| 128 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | 128 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 129 | 129 |
| 130 protected: | 130 protected: |
| 131 virtual const char* GetName() const { return "entry"; } | 131 virtual const char* GetName() const { return "entry"; } |
| 132 | 132 |
| 133 private: | 133 private: |
| 134 EntryFrame() { } | 134 EntryFrame() { } |
| 135 intptr_t ExitLinkOffset(); | 135 intptr_t ExitLinkOffset(); |
| 136 | 136 |
| 137 friend class StackFrameIterator; | 137 friend class StackFrameIterator; |
| 138 DISALLOW_COPY_AND_ASSIGN(EntryFrame); | 138 DISALLOW_COPY_AND_ASSIGN(EntryFrame); |
| 139 }; | 139 }; |
| 140 | 140 |
| 141 | 141 |
| 142 // Regular dart frames, these exist between an EntryFrame and an ExitFrame. | |
| 143 class DartFrame : public StackFrame { | |
| 144 public: | |
| 145 bool IsValid() const { return (LookupDartFunction() != Function::null()); } | |
| 146 bool IsDartFrame() const { return true; } | |
| 147 | |
| 148 // Visit objects in the frame. | |
| 149 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | |
| 150 | |
| 151 // Get function object corresponding to pc for the frame. | |
| 152 RawFunction* LookupDartFunction() const; | |
| 153 | |
| 154 // Get code object corresponding to pc for the frame. | |
| 155 RawCode* LookupDartCode() const; | |
| 156 | |
| 157 // Find exception handler pc in frame if one exists. | |
| 158 bool FindExceptionHandler(uword* handler_pc) const; | |
| 159 | |
| 160 protected: | |
| 161 virtual const char* GetName() const { return "dart"; } | |
| 162 | |
| 163 private: | |
| 164 DartFrame() { } | |
| 165 | |
| 166 friend class StackFrameIterator; | |
| 167 DISALLOW_COPY_AND_ASSIGN(DartFrame); | |
| 168 }; | |
| 169 | |
| 170 | |
| 171 // Stub frames. | |
| 172 class StubFrame : public StackFrame { | |
| 173 public: | |
| 174 bool IsValid() const; | |
| 175 bool IsStubFrame() const { return true; } | |
| 176 | |
| 177 // Visit objects in the frame. | |
| 178 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | |
| 179 | |
| 180 protected: | |
| 181 virtual const char* GetName() const { return "stub"; } | |
| 182 | |
| 183 private: | |
| 184 StubFrame() { } | |
| 185 | |
| 186 friend class StackFrameIterator; | |
| 187 DISALLOW_COPY_AND_ASSIGN(StubFrame); | |
| 188 }; | |
| 189 | |
| 190 | |
| 191 // Iterator for iterating over all frames from the last ExitFrame to the | 142 // Iterator for iterating over all frames from the last ExitFrame to the |
| 192 // first EntryFrame. | 143 // first EntryFrame. |
| 193 class StackFrameIterator : public ValueObject { | 144 class StackFrameIterator : public ValueObject { |
| 194 public: | 145 public: |
| 195 static const bool kValidateFrames = true; | 146 static const bool kValidateFrames = true; |
| 196 static const bool kDontValidateFrames = false; | 147 static const bool kDontValidateFrames = false; |
| 197 | 148 |
| 198 explicit StackFrameIterator(bool validate); | 149 explicit StackFrameIterator(bool validate); |
| 199 | 150 |
| 200 // Checks if a next frame exists. | 151 // Checks if a next frame exists. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 215 } | 166 } |
| 216 intptr_t offset = StackFrame::PcAddressOffsetFromSp(); | 167 intptr_t offset = StackFrame::PcAddressOffsetFromSp(); |
| 217 uword pc = *(reinterpret_cast<uword*>(sp_ + offset)); | 168 uword pc = *(reinterpret_cast<uword*>(sp_ + offset)); |
| 218 return !StubCode::InInvocationStub(pc); | 169 return !StubCode::InInvocationStub(pc); |
| 219 } | 170 } |
| 220 | 171 |
| 221 // Get next non entry/exit frame in the set (assumes a next frame exists). | 172 // Get next non entry/exit frame in the set (assumes a next frame exists). |
| 222 StackFrame* NextFrame(bool validate); | 173 StackFrame* NextFrame(bool validate); |
| 223 | 174 |
| 224 private: | 175 private: |
| 225 FrameSetIterator() : fp_(0), sp_(0), from_stub_exitframe_(false), | 176 FrameSetIterator() : fp_(0), sp_(0), stack_frame_() { } |
| 226 dart_frame_(), stub_frame_() { } | |
| 227 | 177 |
| 228 uword fp_; | 178 uword fp_; |
| 229 uword sp_; | 179 uword sp_; |
| 230 bool from_stub_exitframe_; // Indicates if runtime called from stub frame. | 180 StackFrame stack_frame_; // Singleton frame returned by NextFrame(). |
| 231 DartFrame dart_frame_; // Singleton dart frame returned by NextFrame(). | |
| 232 StubFrame stub_frame_; // Singleton stub frame returned by NextFrame(). | |
| 233 | 181 |
| 234 friend class StackFrameIterator; | 182 friend class StackFrameIterator; |
| 235 DISALLOW_COPY_AND_ASSIGN(FrameSetIterator); | 183 DISALLOW_COPY_AND_ASSIGN(FrameSetIterator); |
| 236 }; | 184 }; |
| 237 | 185 |
| 238 // Get next exit frame. | 186 // Get next exit frame. |
| 239 ExitFrame* NextExitFrame(); | 187 ExitFrame* NextExitFrame(); |
| 240 | 188 |
| 241 // Get next entry frame. | 189 // Get next entry frame. |
| 242 EntryFrame* NextEntryFrame(); | 190 EntryFrame* NextEntryFrame(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 260 }; | 208 }; |
| 261 | 209 |
| 262 | 210 |
| 263 // Iterator for iterating over all dart frames (skips over exit frames, | 211 // Iterator for iterating over all dart frames (skips over exit frames, |
| 264 // entry frames and stub frames). | 212 // entry frames and stub frames). |
| 265 class DartFrameIterator : public ValueObject { | 213 class DartFrameIterator : public ValueObject { |
| 266 public: | 214 public: |
| 267 DartFrameIterator() : frames_(StackFrameIterator::kDontValidateFrames) { } | 215 DartFrameIterator() : frames_(StackFrameIterator::kDontValidateFrames) { } |
| 268 | 216 |
| 269 // Get next dart frame. | 217 // Get next dart frame. |
| 270 DartFrame* NextFrame() { | 218 StackFrame* NextFrame() { |
| 271 StackFrame* frame = frames_.NextFrame(); | 219 StackFrame* frame = frames_.NextFrame(); |
| 272 while (frame != NULL && !frame->IsDartFrame()) { | 220 while (frame != NULL && !frame->IsDartFrame()) { |
| 273 frame = frames_.NextFrame(); | 221 frame = frames_.NextFrame(); |
| 274 } | 222 } |
| 275 return reinterpret_cast<DartFrame*>(frame); | 223 return frame; |
| 276 } | 224 } |
| 277 | 225 |
| 278 private: | 226 private: |
| 279 StackFrameIterator frames_; | 227 StackFrameIterator frames_; |
| 280 | 228 |
| 281 DISALLOW_COPY_AND_ASSIGN(DartFrameIterator); | 229 DISALLOW_COPY_AND_ASSIGN(DartFrameIterator); |
| 282 }; | 230 }; |
| 283 | 231 |
| 284 } // namespace dart | 232 } // namespace dart |
| 285 | 233 |
| 286 #endif // VM_STACK_FRAME_H_ | 234 #endif // VM_STACK_FRAME_H_ |
| OLD | NEW |