38 #include "runtime/frame.inline.hpp"
39 #include "utilities/debug.hpp"
40 #include "utilities/devirtualizer.inline.hpp"
41 #include "utilities/globalDefinitions.hpp"
42 #include "utilities/macros.hpp"
43 #include CPU_HEADER_INLINE(stackChunkFrameStream)
44
45 #ifdef ASSERT
46 extern "C" bool dbg_is_safe(const void* p, intptr_t errvalue);
47 #endif
48
49 template <ChunkFrames frame_kind>
50 StackChunkFrameStream<frame_kind>::StackChunkFrameStream(stackChunkOop chunk) DEBUG_ONLY(: _chunk(chunk)) {
51 assert(chunk->is_stackChunk_noinline(), "");
52 assert(frame_kind == ChunkFrames::Mixed || !chunk->has_mixed_frames(), "");
53
54 DEBUG_ONLY(_index = 0;)
55 _end = chunk->bottom_address();
56 _sp = chunk->start_address() + chunk->sp();
57 assert(_sp <= chunk->end_address() + frame::metadata_words, "");
58
59 get_cb();
60
61 if (frame_kind == ChunkFrames::Mixed) {
62 _unextended_sp = (!is_done() && is_interpreted()) ? unextended_sp_for_interpreter_frame() : _sp;
63 assert(_unextended_sp >= _sp - frame::metadata_words, "");
64 }
65 DEBUG_ONLY(else _unextended_sp = nullptr;)
66
67 if (is_stub()) {
68 get_oopmap(pc(), 0);
69 DEBUG_ONLY(_has_stub = true);
70 } DEBUG_ONLY(else _has_stub = false;)
71 }
72
73 template <ChunkFrames frame_kind>
74 StackChunkFrameStream<frame_kind>::StackChunkFrameStream(stackChunkOop chunk, const frame& f)
75 DEBUG_ONLY(: _chunk(chunk)) {
76 assert(chunk->is_stackChunk_noinline(), "");
77 assert(frame_kind == ChunkFrames::Mixed || !chunk->has_mixed_frames(), "");
78 // assert(!is_empty(), ""); -- allowed to be empty
79
80 DEBUG_ONLY(_index = 0;)
81
82 _end = chunk->bottom_address();
83
84 assert(chunk->is_in_chunk(f.sp()), "");
85 _sp = f.sp();
86 if (frame_kind == ChunkFrames::Mixed) {
87 _unextended_sp = f.unextended_sp();
88 assert(_unextended_sp >= _sp - frame::metadata_words, "");
89 }
90 DEBUG_ONLY(else _unextended_sp = nullptr;)
91 assert(_sp >= chunk->start_address(), "");
92 assert(_sp <= chunk->end_address() + frame::metadata_words, "");
93
94 if (f.cb() != nullptr) {
95 _oopmap = nullptr;
96 _cb = f.cb();
97 } else {
98 get_cb();
99 }
100
101 if (is_stub()) {
102 get_oopmap(pc(), 0);
103 DEBUG_ONLY(_has_stub = true);
104 } DEBUG_ONLY(else _has_stub = false;)
105 }
106
107 template <ChunkFrames frame_kind>
108 inline bool StackChunkFrameStream<frame_kind>::is_stub() const {
109 return cb() != nullptr && _cb->is_runtime_stub();
110 }
111
112 template <ChunkFrames frame_kind>
199 if (is_interpreted()) {
200 return interpreter_frame_num_oops();
201 } else if (is_compiled()) {
202 return oopmap()->num_oops();
203 } else {
204 assert(is_stub(), "invariant");
205 return 0;
206 }
207 }
208
209 template <ChunkFrames frame_kind>
210 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
211 update_reg_map_pd(map);
212 }
213
214 template <ChunkFrames frame_kind>
215 template <typename RegisterMapT>
216 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
217 update_reg_map(map);
218 bool is_runtime_stub = is_stub();
219 if (frame_kind == ChunkFrames::Mixed) {
220 if (is_interpreted()) {
221 next_for_interpreter_frame();
222 } else {
223 _sp = _unextended_sp + cb()->frame_size();
224 if (_sp >= _end - frame::metadata_words) {
225 _sp = _end;
226 }
227 _unextended_sp = is_interpreted() ? unextended_sp_for_interpreter_frame() : _sp;
228 }
229 assert(_unextended_sp >= _sp - frame::metadata_words, "");
230 } else {
231 _sp += cb()->frame_size();
232 }
233 assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
234
235 DEBUG_ONLY(_index++;)
236 if (stop) {
237 return;
238 }
239
240 get_cb();
241 update_reg_map_pd(map);
242 if (is_runtime_stub && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
243 // caller could have been deoptimized so use orig_pc()
244 _oopmap = cb()->oop_map_for_return_address(orig_pc());
245 }
246 }
247
248 template <ChunkFrames frame_kind>
249 inline void StackChunkFrameStream<frame_kind>::get_cb() {
250 _oopmap = nullptr;
251 if (is_done() || is_interpreted()) {
|
38 #include "runtime/frame.inline.hpp"
39 #include "utilities/debug.hpp"
40 #include "utilities/devirtualizer.inline.hpp"
41 #include "utilities/globalDefinitions.hpp"
42 #include "utilities/macros.hpp"
43 #include CPU_HEADER_INLINE(stackChunkFrameStream)
44
45 #ifdef ASSERT
46 extern "C" bool dbg_is_safe(const void* p, intptr_t errvalue);
47 #endif
48
49 template <ChunkFrames frame_kind>
50 StackChunkFrameStream<frame_kind>::StackChunkFrameStream(stackChunkOop chunk) DEBUG_ONLY(: _chunk(chunk)) {
51 assert(chunk->is_stackChunk_noinline(), "");
52 assert(frame_kind == ChunkFrames::Mixed || !chunk->has_mixed_frames(), "");
53
54 DEBUG_ONLY(_index = 0;)
55 _end = chunk->bottom_address();
56 _sp = chunk->start_address() + chunk->sp();
57 assert(_sp <= chunk->end_address() + frame::metadata_words, "");
58 _callee_augmented = false;
59
60 get_cb();
61
62 if (frame_kind == ChunkFrames::Mixed) {
63 _unextended_sp = (!is_done() && is_interpreted()) ? unextended_sp_for_interpreter_frame() : _sp;
64 assert(_unextended_sp >= _sp - frame::metadata_words, "");
65 } else {
66 _unextended_sp = _sp;
67 }
68
69 if (is_stub()) {
70 get_oopmap(pc(), 0);
71 DEBUG_ONLY(_has_stub = true);
72 } DEBUG_ONLY(else _has_stub = false;)
73 }
74
75 template <ChunkFrames frame_kind>
76 StackChunkFrameStream<frame_kind>::StackChunkFrameStream(stackChunkOop chunk, const frame& f)
77 DEBUG_ONLY(: _chunk(chunk)) {
78 assert(chunk->is_stackChunk_noinline(), "");
79 assert(frame_kind == ChunkFrames::Mixed || !chunk->has_mixed_frames(), "");
80 // assert(!is_empty(), ""); -- allowed to be empty
81
82 DEBUG_ONLY(_index = 0;)
83
84 _end = chunk->bottom_address();
85
86 assert(chunk->is_in_chunk(f.sp()), "");
87 _sp = f.sp();
88 if (frame_kind == ChunkFrames::Mixed) {
89 _unextended_sp = f.unextended_sp();
90 assert(_unextended_sp >= _sp - frame::metadata_words, "");
91 } else {
92 _unextended_sp = _sp;
93 }
94 assert(_sp >= chunk->start_address(), "");
95 assert(_sp <= chunk->end_address() + frame::metadata_words, "");
96 _callee_augmented = false;
97
98 if (f.cb() != nullptr) {
99 _oopmap = nullptr;
100 _cb = f.cb();
101 } else {
102 get_cb();
103 }
104
105 if (is_stub()) {
106 get_oopmap(pc(), 0);
107 DEBUG_ONLY(_has_stub = true);
108 } DEBUG_ONLY(else _has_stub = false;)
109 }
110
111 template <ChunkFrames frame_kind>
112 inline bool StackChunkFrameStream<frame_kind>::is_stub() const {
113 return cb() != nullptr && _cb->is_runtime_stub();
114 }
115
116 template <ChunkFrames frame_kind>
203 if (is_interpreted()) {
204 return interpreter_frame_num_oops();
205 } else if (is_compiled()) {
206 return oopmap()->num_oops();
207 } else {
208 assert(is_stub(), "invariant");
209 return 0;
210 }
211 }
212
213 template <ChunkFrames frame_kind>
214 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
215 update_reg_map_pd(map);
216 }
217
218 template <ChunkFrames frame_kind>
219 template <typename RegisterMapT>
220 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
221 update_reg_map(map);
222 bool is_runtime_stub = is_stub();
223 _callee_augmented = false;
224 if (frame_kind == ChunkFrames::Mixed) {
225 if (is_interpreted()) {
226 next_for_interpreter_frame();
227 } else {
228 _sp = _unextended_sp + cb()->frame_size();
229 if (_sp >= _end - frame::metadata_words) {
230 _sp = _end;
231 }
232 if (is_interpreted()) {
233 _unextended_sp = unextended_sp_for_interpreter_frame();
234 } else if (cb()->is_nmethod() && cb()->as_nmethod()->needs_stack_repair()) {
235 _unextended_sp = frame::repair_sender_sp(cb()->as_nmethod(), _unextended_sp, (intptr_t**)(_sp - frame::sender_sp_offset));
236 _callee_augmented = _unextended_sp != _sp;
237 } else {
238 _unextended_sp = _sp;
239 }
240 }
241 assert(_unextended_sp >= _sp - frame::metadata_words, "");
242 } else {
243 _sp = _unextended_sp + cb()->frame_size();
244 if (cb()->is_nmethod() && cb()->as_nmethod()->needs_stack_repair()) {
245 _unextended_sp = frame::repair_sender_sp(cb()->as_nmethod(), _unextended_sp, (intptr_t**)(_sp - frame::sender_sp_offset));
246 _callee_augmented = _unextended_sp != _sp;
247 } else {
248 _unextended_sp = _sp;
249 }
250 }
251 assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
252
253 DEBUG_ONLY(_index++;)
254 if (stop) {
255 return;
256 }
257
258 get_cb();
259 update_reg_map_pd(map);
260 if (is_runtime_stub && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
261 // caller could have been deoptimized so use orig_pc()
262 _oopmap = cb()->oop_map_for_return_address(orig_pc());
263 }
264 }
265
266 template <ChunkFrames frame_kind>
267 inline void StackChunkFrameStream<frame_kind>::get_cb() {
268 _oopmap = nullptr;
269 if (is_done() || is_interpreted()) {
|