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>
200 if (is_interpreted()) {
201 return interpreter_frame_num_oops(map);
202 } else if (is_compiled()) {
203 return oopmap()->num_oops();
204 } else {
205 assert(is_stub(), "invariant");
206 return 0;
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()) {
|
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>
204 if (is_interpreted()) {
205 return interpreter_frame_num_oops(map);
206 } else if (is_compiled()) {
207 return oopmap()->num_oops();
208 } else {
209 assert(is_stub(), "invariant");
210 return 0;
211 }
212 }
213
214 template <ChunkFrames frame_kind>
215 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
216 update_reg_map_pd(map);
217 }
218
219 template <ChunkFrames frame_kind>
220 template <typename RegisterMapT>
221 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
222 update_reg_map(map);
223 bool is_runtime_stub = is_stub();
224 _callee_augmented = false;
225 if (frame_kind == ChunkFrames::Mixed) {
226 if (is_interpreted()) {
227 next_for_interpreter_frame();
228 } else {
229 _sp = _unextended_sp + cb()->frame_size();
230 if (_sp >= _end - frame::metadata_words) {
231 _sp = _end;
232 }
233 if (is_interpreted()) {
234 _unextended_sp = unextended_sp_for_interpreter_frame();
235 } else if (cb()->is_nmethod() && cb()->as_nmethod()->needs_stack_repair()) {
236 _unextended_sp = frame::repair_sender_sp(cb()->as_nmethod(), _unextended_sp, (intptr_t**)(_sp - frame::sender_sp_offset));
237 _callee_augmented = _unextended_sp != _sp;
238 } else {
239 _unextended_sp = _sp;
240 }
241 }
242 assert(_unextended_sp >= _sp - frame::metadata_words, "");
243 } else {
244 _sp = _unextended_sp + cb()->frame_size();
245 if (cb()->is_nmethod() && cb()->as_nmethod()->needs_stack_repair()) {
246 _unextended_sp = frame::repair_sender_sp(cb()->as_nmethod(), _unextended_sp, (intptr_t**)(_sp - frame::sender_sp_offset));
247 _callee_augmented = _unextended_sp != _sp;
248 } else {
249 _unextended_sp = _sp;
250 }
251 }
252 assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
253
254 DEBUG_ONLY(_index++;)
255 if (stop) {
256 return;
257 }
258
259 get_cb();
260 update_reg_map_pd(map);
261 if (is_runtime_stub && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
262 // caller could have been deoptimized so use orig_pc()
263 _oopmap = cb()->oop_map_for_return_address(orig_pc());
264 }
265 }
266
267 template <ChunkFrames frame_kind>
268 inline void StackChunkFrameStream<frame_kind>::get_cb() {
269 _oopmap = nullptr;
270 if (is_done() || is_interpreted()) {
|