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 }
207 }
208 }
209
210 template <ChunkFrames frame_kind>
211 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
212 update_reg_map_pd(map);
213 }
214
215 template <ChunkFrames frame_kind>
216 template <typename RegisterMapT>
217 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
218 update_reg_map(map);
219 bool is_runtime_stub = is_stub();
220 if (frame_kind == ChunkFrames::Mixed) {
221 if (is_interpreted()) {
222 next_for_interpreter_frame();
223 } else {
224 _sp = _unextended_sp + cb()->frame_size();
225 if (_sp >= _end - frame::metadata_words) {
226 _sp = _end;
227 }
228 _unextended_sp = is_interpreted() ? unextended_sp_for_interpreter_frame() : _sp;
229 }
230 assert(_unextended_sp >= _sp - frame::metadata_words, "");
231 } else {
232 _sp += cb()->frame_size();
233 }
234 assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
235
236 DEBUG_ONLY(_index++;)
237 if (stop) {
238 return;
239 }
240
241 get_cb();
242 update_reg_map_pd(map);
243 if (is_runtime_stub && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
244 // caller could have been deoptimized so use orig_pc()
245 _oopmap = cb()->oop_map_for_return_address(orig_pc());
246 }
247 }
248
249 template <ChunkFrames frame_kind>
250 inline void StackChunkFrameStream<frame_kind>::get_cb() {
251 _oopmap = nullptr;
252 if (is_done() || is_interpreted()) {
|
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 } else {
65 _unextended_sp = _sp;
66 }
67
68 if (is_stub()) {
69 get_oopmap(pc(), 0);
70 DEBUG_ONLY(_has_stub = true);
71 } DEBUG_ONLY(else _has_stub = false;)
72 }
73
74 template <ChunkFrames frame_kind>
75 StackChunkFrameStream<frame_kind>::StackChunkFrameStream(stackChunkOop chunk, const frame& f)
76 DEBUG_ONLY(: _chunk(chunk)) {
77 assert(chunk->is_stackChunk_noinline(), "");
78 assert(frame_kind == ChunkFrames::Mixed || !chunk->has_mixed_frames(), "");
79 // assert(!is_empty(), ""); -- allowed to be empty
80
81 DEBUG_ONLY(_index = 0;)
82
83 _end = chunk->bottom_address();
84
85 assert(chunk->is_in_chunk(f.sp()), "");
86 _sp = f.sp();
87 if (frame_kind == ChunkFrames::Mixed) {
88 _unextended_sp = f.unextended_sp();
89 assert(_unextended_sp >= _sp - frame::metadata_words, "");
90 } else {
91 _unextended_sp = _sp;
92 }
93 assert(_sp >= chunk->start_address(), "");
94 assert(_sp <= chunk->end_address() + frame::metadata_words, "");
95
96 if (f.cb() != nullptr) {
97 _oopmap = nullptr;
98 _cb = f.cb();
99 } else {
100 get_cb();
101 }
102
103 if (is_stub()) {
104 get_oopmap(pc(), 0);
105 DEBUG_ONLY(_has_stub = true);
106 } DEBUG_ONLY(else _has_stub = false;)
107 }
108
109 template <ChunkFrames frame_kind>
110 inline bool StackChunkFrameStream<frame_kind>::is_stub() const {
111 return cb() != nullptr && _cb->is_runtime_stub();
112 }
209 }
210 }
211
212 template <ChunkFrames frame_kind>
213 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
214 update_reg_map_pd(map);
215 }
216
217 template <ChunkFrames frame_kind>
218 template <typename RegisterMapT>
219 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
220 update_reg_map(map);
221 bool is_runtime_stub = is_stub();
222 if (frame_kind == ChunkFrames::Mixed) {
223 if (is_interpreted()) {
224 next_for_interpreter_frame();
225 } else {
226 _sp = _unextended_sp + cb()->frame_size();
227 if (_sp >= _end - frame::metadata_words) {
228 _sp = _end;
229 #ifndef ZERO
230 } else if (cb()->is_nmethod() && cb()->as_nmethod()->needs_stack_repair()) {
231 _sp = frame::repair_sender_sp(cb()->as_nmethod(), _unextended_sp, (intptr_t**)(_sp - frame::sender_sp_offset));
232 #endif
233 }
234 _unextended_sp = is_interpreted() ? unextended_sp_for_interpreter_frame() : _sp;
235 }
236 assert(_unextended_sp >= _sp - frame::metadata_words, "");
237 } else {
238 _sp = _unextended_sp + cb()->frame_size();
239 #ifndef ZERO
240 if (cb()->is_nmethod() && cb()->as_nmethod()->needs_stack_repair()) {
241 _sp = frame::repair_sender_sp(cb()->as_nmethod(), _unextended_sp, (intptr_t**)(_sp - frame::sender_sp_offset));
242 }
243 #endif
244 _unextended_sp = _sp;
245 }
246 assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
247
248 DEBUG_ONLY(_index++;)
249 if (stop) {
250 return;
251 }
252
253 get_cb();
254 update_reg_map_pd(map);
255 if (is_runtime_stub && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
256 // caller could have been deoptimized so use orig_pc()
257 _oopmap = cb()->oop_map_for_return_address(orig_pc());
258 }
259 }
260
261 template <ChunkFrames frame_kind>
262 inline void StackChunkFrameStream<frame_kind>::get_cb() {
263 _oopmap = nullptr;
264 if (is_done() || is_interpreted()) {
|