hotspot/src/share/vm/prims/stackwalk.hpp
changeset 41280 74b314ad1e9a
parent 41095 97cca074c2be
child 43677 5228814c1da2
equal deleted inserted replaced
41279:5a7c83da4a2d 41280:74b314ad1e9a
    27 #define SHARE_VM_PRIMS_STACKWALK_HPP
    27 #define SHARE_VM_PRIMS_STACKWALK_HPP
    28 
    28 
    29 #include "oops/oop.hpp"
    29 #include "oops/oop.hpp"
    30 #include "runtime/vframe.hpp"
    30 #include "runtime/vframe.hpp"
    31 
    31 
    32 //
    32 // BaseFrameStream is an abstract base class for encapsulating the VM-side
    33 // JavaFrameStream is used by StackWalker to iterate through Java stack frames
    33 // implementation of the StackWalker API.  There are two concrete subclasses:
    34 // on the given JavaThread.
    34 // - JavaFrameStream:
    35 //
    35 //     -based on vframeStream; used in most instances
    36 class JavaFrameStream : public StackObj {
    36 // - LiveFrameStream:
       
    37 //     -based on javaVFrame; used for retrieving locals/monitors/operands for
       
    38 //      LiveStackFrame
       
    39 class BaseFrameStream : public StackObj {
    37 private:
    40 private:
    38   enum {
    41   enum {
    39     magic_pos = 0
    42     magic_pos = 0
    40   };
    43   };
    41 
    44 
    42   JavaThread*           _thread;
    45   JavaThread*           _thread;
    43   javaVFrame*           _jvf;
       
    44   jlong                 _anchor;
    46   jlong                 _anchor;
       
    47 protected:
       
    48   void fill_stackframe(Handle stackFrame, const methodHandle& method);
    45 public:
    49 public:
    46   JavaFrameStream(JavaThread* thread, RegisterMap* rm)
    50   BaseFrameStream(JavaThread* thread) : _thread(thread), _anchor(0L) {}
    47     : _thread(thread), _anchor(0L) {
       
    48     _jvf = _thread->last_java_vframe(rm);
       
    49   }
       
    50 
    51 
    51   javaVFrame*     java_frame()        { return _jvf; }
    52   virtual void    next()=0;
    52   void            next()              { _jvf = _jvf->java_sender(); }
    53   virtual bool    at_end()=0;
    53   bool            at_end()            { return _jvf == NULL; }
       
    54 
    54 
    55   Method* method()                    { return _jvf->method(); }
    55   virtual Method* method()=0;
    56   int bci()                           { return _jvf->bci(); }
    56   virtual int     bci()=0;
       
    57 
       
    58   virtual void    fill_frame(int index, objArrayHandle  frames_array,
       
    59                              const methodHandle& method, TRAPS)=0;
    57 
    60 
    58   void setup_magic_on_entry(objArrayHandle frames_array);
    61   void setup_magic_on_entry(objArrayHandle frames_array);
    59   bool check_magic(objArrayHandle frames_array);
    62   bool check_magic(objArrayHandle frames_array);
    60   bool cleanup_magic_on_exit(objArrayHandle frames_array);
    63   bool cleanup_magic_on_exit(objArrayHandle frames_array);
    61 
    64 
    65 
    68 
    66   jlong address_value() {
    69   jlong address_value() {
    67     return (jlong) castable_address(this);
    70     return (jlong) castable_address(this);
    68   }
    71   }
    69 
    72 
    70   static JavaFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array);
    73   static BaseFrameStream* from_current(JavaThread* thread, jlong magic, objArrayHandle frames_array);
       
    74 };
       
    75 
       
    76 class JavaFrameStream : public BaseFrameStream {
       
    77 private:
       
    78   vframeStream          _vfst;
       
    79   bool                  _need_method_info;
       
    80 public:
       
    81   JavaFrameStream(JavaThread* thread, int mode);
       
    82 
       
    83   void next()      { _vfst.next();}
       
    84   bool at_end()    { return _vfst.at_end(); }
       
    85 
       
    86   Method* method() { return _vfst.method(); }
       
    87   int bci()        { return _vfst.bci(); }
       
    88 
       
    89   void fill_frame(int index, objArrayHandle  frames_array,
       
    90                   const methodHandle& method, TRAPS);
       
    91 };
       
    92 
       
    93 class LiveFrameStream : public BaseFrameStream {
       
    94 private:
       
    95   javaVFrame*           _jvf;
       
    96 
       
    97   void fill_live_stackframe(Handle stackFrame, const methodHandle& method, TRAPS);
       
    98   static oop create_primitive_value_instance(StackValueCollection* values,
       
    99                                              int i, TRAPS);
       
   100   static objArrayHandle monitors_to_object_array(GrowableArray<MonitorInfo*>* monitors,
       
   101                                                  TRAPS);
       
   102   static objArrayHandle values_to_object_array(StackValueCollection* values, TRAPS);
       
   103 public:
       
   104   LiveFrameStream(JavaThread* thread, RegisterMap* rm) : BaseFrameStream(thread) {
       
   105     _jvf = thread->last_java_vframe(rm);
       
   106   }
       
   107 
       
   108   void next()      { _jvf = _jvf->java_sender(); }
       
   109   bool at_end()    { return _jvf == NULL; }
       
   110 
       
   111   Method* method() { return _jvf->method(); }
       
   112   int bci()        { return _jvf->bci(); }
       
   113 
       
   114   void fill_frame(int index, objArrayHandle  frames_array,
       
   115                   const methodHandle& method, TRAPS);
    71 };
   116 };
    72 
   117 
    73 class StackWalk : public AllStatic {
   118 class StackWalk : public AllStatic {
    74 private:
   119 private:
    75   static int fill_in_frames(jlong mode, JavaFrameStream& stream,
   120   static int fill_in_frames(jlong mode, BaseFrameStream& stream,
    76                             int max_nframes, int start_index,
   121                             int max_nframes, int start_index,
    77                             objArrayHandle frames_array,
   122                             objArrayHandle frames_array,
    78                             int& end_index, TRAPS);
   123                             int& end_index, TRAPS);
    79 
       
    80   static void fill_stackframe(Handle stackFrame, const methodHandle& method, int bci);
       
    81 
       
    82   static void fill_live_stackframe(Handle stackFrame, const methodHandle& method, int bci,
       
    83                                    javaVFrame* jvf, TRAPS);
       
    84 
   124 
    85   static inline bool get_caller_class(int mode) {
   125   static inline bool get_caller_class(int mode) {
    86     return (mode & JVM_STACKWALK_GET_CALLER_CLASS) != 0;
   126     return (mode & JVM_STACKWALK_GET_CALLER_CLASS) != 0;
    87   }
   127   }
    88   static inline bool skip_hidden_frames(int mode) {
   128   static inline bool skip_hidden_frames(int mode) {
    89     return (mode & JVM_STACKWALK_SHOW_HIDDEN_FRAMES) == 0;
   129     return (mode & JVM_STACKWALK_SHOW_HIDDEN_FRAMES) == 0;
    90   }
   130   }
    91   static inline bool need_method_info(int mode) {
       
    92     return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
       
    93   }
       
    94   static inline bool live_frame_info(int mode) {
   131   static inline bool live_frame_info(int mode) {
    95     return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
   132     return (mode & JVM_STACKWALK_FILL_LIVE_STACK_FRAMES) != 0;
    96   }
   133   }
    97 
   134 
    98 public:
   135 public:
       
   136   static inline bool need_method_info(int mode) {
       
   137     return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
       
   138   }
    99   static inline bool use_frames_array(int mode) {
   139   static inline bool use_frames_array(int mode) {
   100     return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
   140     return (mode & JVM_STACKWALK_FILL_CLASS_REFS_ONLY) == 0;
   101   }
   141   }
   102   static oop walk(Handle stackStream, jlong mode,
   142   static oop walk(Handle stackStream, jlong mode,
   103                   int skip_frames, int frame_count, int start_index,
   143                   int skip_frames, int frame_count, int start_index,
   104                   objArrayHandle frames_array,
   144                   objArrayHandle frames_array,
   105                   TRAPS);
   145                   TRAPS);
   106 
   146 
   107   static jint moreFrames(Handle stackStream, jlong mode, jlong magic,
   147   static oop fetchFirstBatch(BaseFrameStream& stream, Handle stackStream,
   108                          int frame_count, int start_index,
   148                              jlong mode, int skip_frames, int frame_count,
   109                          objArrayHandle frames_array,
   149                              int start_index, objArrayHandle frames_array, TRAPS);
   110                          TRAPS);
   150 
       
   151   static jint fetchNextBatch(Handle stackStream, jlong mode, jlong magic,
       
   152                              int frame_count, int start_index,
       
   153                              objArrayHandle frames_array, TRAPS);
   111 };
   154 };
   112 #endif // SHARE_VM_PRIMS_STACKWALK_HPP
   155 #endif // SHARE_VM_PRIMS_STACKWALK_HPP