| 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 RUNTIME_VM_STACK_FRAME_H_ | 5 #ifndef RUNTIME_VM_STACK_FRAME_H_ |
| 6 #define RUNTIME_VM_STACK_FRAME_H_ | 6 #define RUNTIME_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 11 matching lines...) Expand all Loading... |
| 22 #else | 22 #else |
| 23 #error Unknown architecture. | 23 #error Unknown architecture. |
| 24 #endif | 24 #endif |
| 25 | 25 |
| 26 namespace dart { | 26 namespace dart { |
| 27 | 27 |
| 28 // Forward declarations. | 28 // Forward declarations. |
| 29 class ObjectPointerVisitor; | 29 class ObjectPointerVisitor; |
| 30 class RawContext; | 30 class RawContext; |
| 31 | 31 |
| 32 | |
| 33 // Generic stack frame. | 32 // Generic stack frame. |
| 34 class StackFrame : public ValueObject { | 33 class StackFrame : public ValueObject { |
| 35 public: | 34 public: |
| 36 virtual ~StackFrame() {} | 35 virtual ~StackFrame() {} |
| 37 | 36 |
| 38 // Accessors to get the pc, sp and fp of a frame. | 37 // Accessors to get the pc, sp and fp of a frame. |
| 39 uword sp() const { return sp_; } | 38 uword sp() const { return sp_; } |
| 40 uword fp() const { return fp_; } | 39 uword fp() const { return fp_; } |
| 41 uword pc() const { return pc_; } | 40 uword pc() const { return pc_; } |
| 42 | 41 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 Thread* thread_; | 142 Thread* thread_; |
| 144 | 143 |
| 145 // The iterators FrameSetIterator and StackFrameIterator set the private | 144 // The iterators FrameSetIterator and StackFrameIterator set the private |
| 146 // fields fp_ and sp_ when they return the respective frame objects. | 145 // fields fp_ and sp_ when they return the respective frame objects. |
| 147 friend class FrameSetIterator; | 146 friend class FrameSetIterator; |
| 148 friend class StackFrameIterator; | 147 friend class StackFrameIterator; |
| 149 friend class ProfilerDartStackWalker; | 148 friend class ProfilerDartStackWalker; |
| 150 DISALLOW_COPY_AND_ASSIGN(StackFrame); | 149 DISALLOW_COPY_AND_ASSIGN(StackFrame); |
| 151 }; | 150 }; |
| 152 | 151 |
| 153 | |
| 154 // Exit frame is used to mark the transition from dart code into dart VM | 152 // Exit frame is used to mark the transition from dart code into dart VM |
| 155 // runtime code. | 153 // runtime code. |
| 156 class ExitFrame : public StackFrame { | 154 class ExitFrame : public StackFrame { |
| 157 public: | 155 public: |
| 158 bool IsValid() const { return sp() == 0; } | 156 bool IsValid() const { return sp() == 0; } |
| 159 bool IsDartFrame(bool validate = true) const { return false; } | 157 bool IsDartFrame(bool validate = true) const { return false; } |
| 160 bool IsStubFrame() const { return false; } | 158 bool IsStubFrame() const { return false; } |
| 161 bool IsExitFrame() const { return true; } | 159 bool IsExitFrame() const { return true; } |
| 162 | 160 |
| 163 // Visit objects in the frame. | 161 // Visit objects in the frame. |
| 164 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | 162 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 165 | 163 |
| 166 protected: | 164 protected: |
| 167 virtual const char* GetName() const { return "exit"; } | 165 virtual const char* GetName() const { return "exit"; } |
| 168 | 166 |
| 169 private: | 167 private: |
| 170 explicit ExitFrame(Thread* thread) : StackFrame(thread) {} | 168 explicit ExitFrame(Thread* thread) : StackFrame(thread) {} |
| 171 | 169 |
| 172 friend class StackFrameIterator; | 170 friend class StackFrameIterator; |
| 173 DISALLOW_COPY_AND_ASSIGN(ExitFrame); | 171 DISALLOW_COPY_AND_ASSIGN(ExitFrame); |
| 174 }; | 172 }; |
| 175 | 173 |
| 176 | |
| 177 // Entry Frame is used to mark the transition from dart VM runtime code into | 174 // Entry Frame is used to mark the transition from dart VM runtime code into |
| 178 // dart code. | 175 // dart code. |
| 179 class EntryFrame : public StackFrame { | 176 class EntryFrame : public StackFrame { |
| 180 public: | 177 public: |
| 181 bool IsValid() const { return StubCode::InInvocationStub(pc()); } | 178 bool IsValid() const { return StubCode::InInvocationStub(pc()); } |
| 182 bool IsDartFrame(bool validate = true) const { return false; } | 179 bool IsDartFrame(bool validate = true) const { return false; } |
| 183 bool IsStubFrame() const { return false; } | 180 bool IsStubFrame() const { return false; } |
| 184 bool IsEntryFrame() const { return true; } | 181 bool IsEntryFrame() const { return true; } |
| 185 | 182 |
| 186 // Visit objects in the frame. | 183 // Visit objects in the frame. |
| 187 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); | 184 virtual void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 188 | 185 |
| 189 protected: | 186 protected: |
| 190 virtual const char* GetName() const { return "entry"; } | 187 virtual const char* GetName() const { return "entry"; } |
| 191 | 188 |
| 192 private: | 189 private: |
| 193 explicit EntryFrame(Thread* thread) : StackFrame(thread) {} | 190 explicit EntryFrame(Thread* thread) : StackFrame(thread) {} |
| 194 | 191 |
| 195 friend class StackFrameIterator; | 192 friend class StackFrameIterator; |
| 196 DISALLOW_COPY_AND_ASSIGN(EntryFrame); | 193 DISALLOW_COPY_AND_ASSIGN(EntryFrame); |
| 197 }; | 194 }; |
| 198 | 195 |
| 199 | |
| 200 // A StackFrameIterator can be initialized with a thread other than the | 196 // A StackFrameIterator can be initialized with a thread other than the |
| 201 // current thread. Because this is generally a bad idea, it is only allowed on | 197 // current thread. Because this is generally a bad idea, it is only allowed on |
| 202 // Windows- where it is needed for the profiler. It is the responsibility of | 198 // Windows- where it is needed for the profiler. It is the responsibility of |
| 203 // users of StackFrameIterator to ensure that the thread given is not running | 199 // users of StackFrameIterator to ensure that the thread given is not running |
| 204 // concurrently. | 200 // concurrently. |
| 205 class StackFrameIterator : public ValueObject { | 201 class StackFrameIterator : public ValueObject { |
| 206 public: | 202 public: |
| 207 enum ValidationPolicy { | 203 enum ValidationPolicy { |
| 208 kValidateFrames = 0, | 204 kValidateFrames = 0, |
| 209 kDontValidateFrames = 1, | 205 kDontValidateFrames = 1, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 EntryFrame entry_; // Singleton entry frame returned by NextEntryFrame(). | 288 EntryFrame entry_; // Singleton entry frame returned by NextEntryFrame(). |
| 293 ExitFrame exit_; // Singleton exit frame returned by NextExitFrame(). | 289 ExitFrame exit_; // Singleton exit frame returned by NextExitFrame(). |
| 294 FrameSetIterator frames_; | 290 FrameSetIterator frames_; |
| 295 StackFrame* current_frame_; // Points to the current frame in the iterator. | 291 StackFrame* current_frame_; // Points to the current frame in the iterator. |
| 296 Thread* thread_; | 292 Thread* thread_; |
| 297 | 293 |
| 298 friend class ProfilerDartStackWalker; | 294 friend class ProfilerDartStackWalker; |
| 299 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); | 295 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator); |
| 300 }; | 296 }; |
| 301 | 297 |
| 302 | |
| 303 // Iterator for iterating over all dart frames (skips over exit frames, | 298 // Iterator for iterating over all dart frames (skips over exit frames, |
| 304 // entry frames and stub frames). | 299 // entry frames and stub frames). |
| 305 // A DartFrameIterator can be initialized with an isolate other than the | 300 // A DartFrameIterator can be initialized with an isolate other than the |
| 306 // current thread's isolate. Because this is generally a bad idea, | 301 // current thread's isolate. Because this is generally a bad idea, |
| 307 // it is only allowed on Windows- where it is needed for the profiler. | 302 // it is only allowed on Windows- where it is needed for the profiler. |
| 308 // It is the responsibility of users of DartFrameIterator to ensure that the | 303 // It is the responsibility of users of DartFrameIterator to ensure that the |
| 309 // isolate given is not running concurrently on another thread. | 304 // isolate given is not running concurrently on another thread. |
| 310 class DartFrameIterator : public ValueObject { | 305 class DartFrameIterator : public ValueObject { |
| 311 public: | 306 public: |
| 312 explicit DartFrameIterator( | 307 explicit DartFrameIterator( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 } | 341 } |
| 347 return frame; | 342 return frame; |
| 348 } | 343 } |
| 349 | 344 |
| 350 private: | 345 private: |
| 351 StackFrameIterator frames_; | 346 StackFrameIterator frames_; |
| 352 | 347 |
| 353 DISALLOW_COPY_AND_ASSIGN(DartFrameIterator); | 348 DISALLOW_COPY_AND_ASSIGN(DartFrameIterator); |
| 354 }; | 349 }; |
| 355 | 350 |
| 356 | |
| 357 // Iterator for iterating over all inlined dart functions in an optimized | 351 // Iterator for iterating over all inlined dart functions in an optimized |
| 358 // dart frame (the iteration includes the function that is inlining the | 352 // dart frame (the iteration includes the function that is inlining the |
| 359 // other functions). | 353 // other functions). |
| 360 class InlinedFunctionsIterator : public ValueObject { | 354 class InlinedFunctionsIterator : public ValueObject { |
| 361 public: | 355 public: |
| 362 InlinedFunctionsIterator(const Code& code, uword pc); | 356 InlinedFunctionsIterator(const Code& code, uword pc); |
| 363 bool Done() const { return index_ == -1; } | 357 bool Done() const { return index_ == -1; } |
| 364 void Advance(); | 358 void Advance(); |
| 365 | 359 |
| 366 RawFunction* function() const { | 360 RawFunction* function() const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 389 Code& code_; | 383 Code& code_; |
| 390 TypedData& deopt_info_; | 384 TypedData& deopt_info_; |
| 391 Function& function_; | 385 Function& function_; |
| 392 uword pc_; | 386 uword pc_; |
| 393 GrowableArray<DeoptInstr*> deopt_instructions_; | 387 GrowableArray<DeoptInstr*> deopt_instructions_; |
| 394 ObjectPool& object_table_; | 388 ObjectPool& object_table_; |
| 395 | 389 |
| 396 DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator); | 390 DISALLOW_COPY_AND_ASSIGN(InlinedFunctionsIterator); |
| 397 }; | 391 }; |
| 398 | 392 |
| 399 | |
| 400 #if defined(DEBUG) | 393 #if defined(DEBUG) |
| 401 void ValidateFrames(); | 394 void ValidateFrames(); |
| 402 #endif | 395 #endif |
| 403 | 396 |
| 404 | |
| 405 #if !defined(TARGET_ARCH_DBC) | 397 #if !defined(TARGET_ARCH_DBC) |
| 406 DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset, | 398 DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset, |
| 407 intptr_t var_index) { | 399 intptr_t var_index) { |
| 408 return fp_offset + var_index; | 400 return fp_offset + var_index; |
| 409 } | 401 } |
| 410 | 402 |
| 411 | |
| 412 DART_FORCE_INLINE static uword ParamAddress(uword fp, intptr_t reverse_index) { | 403 DART_FORCE_INLINE static uword ParamAddress(uword fp, intptr_t reverse_index) { |
| 413 return fp + (kParamEndSlotFromFp * kWordSize) + (reverse_index * kWordSize); | 404 return fp + (kParamEndSlotFromFp * kWordSize) + (reverse_index * kWordSize); |
| 414 } | 405 } |
| 415 | 406 |
| 416 | |
| 417 DART_FORCE_INLINE static bool IsCalleeFrameOf(uword fp, uword other_fp) { | 407 DART_FORCE_INLINE static bool IsCalleeFrameOf(uword fp, uword other_fp) { |
| 418 return other_fp < fp; | 408 return other_fp < fp; |
| 419 } | 409 } |
| 420 | 410 |
| 421 // Value for stack limit that is used to cause an interrupt. | 411 // Value for stack limit that is used to cause an interrupt. |
| 422 // Note that on DBC stack is growing upwards so interrupt limit is 0 unlike | 412 // Note that on DBC stack is growing upwards so interrupt limit is 0 unlike |
| 423 // on all other architectures. | 413 // on all other architectures. |
| 424 static const uword kInterruptStackLimit = ~static_cast<uword>(0); | 414 static const uword kInterruptStackLimit = ~static_cast<uword>(0); |
| 425 #endif | 415 #endif |
| 426 | 416 |
| 427 | |
| 428 DART_FORCE_INLINE static uword LocalVarAddress(uword fp, intptr_t index) { | 417 DART_FORCE_INLINE static uword LocalVarAddress(uword fp, intptr_t index) { |
| 429 return fp + LocalVarIndex(0, index) * kWordSize; | 418 return fp + LocalVarIndex(0, index) * kWordSize; |
| 430 } | 419 } |
| 431 | 420 |
| 432 | |
| 433 } // namespace dart | 421 } // namespace dart |
| 434 | 422 |
| 435 #endif // RUNTIME_VM_STACK_FRAME_H_ | 423 #endif // RUNTIME_VM_STACK_FRAME_H_ |
| OLD | NEW |