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 |