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