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