< prev index next >

src/hotspot/share/runtime/stackChunkFrameStream.inline.hpp

Print this page

 88   }
 89   DEBUG_ONLY(else _unextended_sp = nullptr;)
 90   assert(_sp >= chunk->start_address(), "");
 91   assert(_sp <= chunk->end_address() + frame::metadata_words, "");
 92 
 93   if (f.cb() != nullptr) {
 94     _oopmap = nullptr;
 95     _cb = f.cb();
 96   } else {
 97     get_cb();
 98   }
 99 
100   if (is_stub()) {
101     get_oopmap(pc(), 0);
102     DEBUG_ONLY(_has_stub = true);
103   } DEBUG_ONLY(else _has_stub = false;)
104 }
105 
106 template <ChunkFrames frame_kind>
107 inline bool StackChunkFrameStream<frame_kind>::is_stub() const {
108   return cb() != nullptr && (_cb->is_safepoint_stub() || _cb->is_runtime_stub());
109 }
110 
111 template <ChunkFrames frame_kind>
112 inline bool StackChunkFrameStream<frame_kind>::is_compiled() const {
113   return cb() != nullptr && _cb->is_compiled();
114 }
115 
116 template <>
117 inline bool StackChunkFrameStream<ChunkFrames::Mixed>::is_interpreted() const {
118   return !is_done() && Interpreter::contains(pc());
119 }
120 
121 template <>
122 inline bool StackChunkFrameStream<ChunkFrames::CompiledOnly>::is_interpreted() const {
123   return false;
124 }
125 
126 // StackChunkFrameStream<frame_kind>::frame_size() returns the words required to
127 // store the given frame as the only frame in a StackChunk. This is the size of the
128 // frame itself plus its stack arguments plus metadata at the caller's frame top (1)

178   return is_interpreted() ? interpreter_frame_size()
179                           : cb()->frame_size() + stack_argsize() + frame::metadata_words_at_top;
180 }
181 
182 template <ChunkFrames frame_kind>
183 inline int StackChunkFrameStream<frame_kind>::stack_argsize() const {
184   if (is_interpreted()) {
185     return interpreter_frame_stack_argsize();
186   }
187   if (is_stub()) {
188     return 0;
189   }
190   assert(cb() != nullptr, "");
191   assert(cb()->is_compiled(), "");
192   assert(cb()->as_compiled_method()->method() != nullptr, "");
193   return (cb()->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord;
194 }
195 
196 template <ChunkFrames frame_kind>
197 inline int StackChunkFrameStream<frame_kind>::num_oops() const {
198   return is_interpreted() ? interpreter_frame_num_oops() : oopmap()->num_oops();







199 }
200 
201 template <ChunkFrames frame_kind>
202 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
203   update_reg_map_pd(map);
204 }
205 
206 template <ChunkFrames frame_kind>
207 template <typename RegisterMapT>
208 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
209   update_reg_map(map);
210   bool safepoint = is_stub();
211   if (frame_kind == ChunkFrames::Mixed) {
212     if (is_interpreted()) {
213       next_for_interpreter_frame();
214     } else {
215       _sp = _unextended_sp + cb()->frame_size();
216       if (_sp >= _end - frame::metadata_words) {
217         _sp = _end;
218       }
219       _unextended_sp = is_interpreted() ? unextended_sp_for_interpreter_frame() : _sp;
220     }
221     assert(_unextended_sp >= _sp - frame::metadata_words, "");
222   } else {
223     _sp += cb()->frame_size();
224   }
225   assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
226 
227   DEBUG_ONLY(_index++;)
228   if (stop) {
229     return;
230   }
231 
232   get_cb();
233   update_reg_map_pd(map);
234   if (safepoint && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
235     _oopmap = cb()->oop_map_for_return_address(pc());
236   }
237 }
238 
239 template <ChunkFrames frame_kind>
240 inline void StackChunkFrameStream<frame_kind>::get_cb() {
241   _oopmap = nullptr;
242   if (is_done() || is_interpreted()) {
243     _cb = nullptr;
244     return;
245   }
246 
247   assert(pc() != nullptr, "");
248   assert(dbg_is_safe(pc(), -1), "");
249 
250   _cb = CodeCache::find_blob_fast(pc());
251 
252   assert(_cb != nullptr, "");
253   assert(is_interpreted() || ((is_stub() || is_compiled()) && _cb->frame_size() > 0), "");
254 }
255 

282 template <typename RegisterMapT>
283 inline void* StackChunkFrameStream<frame_kind>::reg_to_loc(VMReg reg, const RegisterMapT* map) const {
284   assert(!is_done(), "");
285   return reg->is_reg() ? (void*)map->location(reg, sp()) // see frame::update_map_with_saved_link(&map, link_addr);
286                        : (void*)((address)unextended_sp() + (reg->reg2stack() * VMRegImpl::stack_slot_size));
287 }
288 
289 template<>
290 template<>
291 inline void StackChunkFrameStream<ChunkFrames::Mixed>::update_reg_map(RegisterMap* map) {
292   assert(!map->in_cont() || map->stack_chunk() == _chunk, "");
293   if (map->update_map() && is_stub()) {
294     frame f = to_frame();
295     oopmap()->update_register_map(&f, map); // we have callee-save registers in this case
296   }
297 }
298 
299 template<>
300 template<>
301 inline void StackChunkFrameStream<ChunkFrames::CompiledOnly>::update_reg_map(RegisterMap* map) {
302   assert(map->in_cont(), "");
303   assert(map->stack_chunk()() == _chunk, "");
304   if (map->update_map()) {
305     frame f = to_frame();
306     oopmap()->update_register_map(&f, map); // we have callee-save registers in this case
307   }
308 }
309 
310 template <ChunkFrames frame_kind>
311 template <typename RegisterMapT>
312 inline void StackChunkFrameStream<frame_kind>::update_reg_map(RegisterMapT* map) {}
313 
314 template <ChunkFrames frame_kind>
315 inline address StackChunkFrameStream<frame_kind>::orig_pc() const {
316   address pc1 = pc();
317   if (is_interpreted() || is_stub()) {
318     return pc1;
319   }
320   CompiledMethod* cm = cb()->as_compiled_method();
321   if (cm->is_deopt_pc(pc1)) {
322     pc1 = *(address*)((address)unextended_sp() + cm->orig_pc_offset());
323   }
324 

 88   }
 89   DEBUG_ONLY(else _unextended_sp = nullptr;)
 90   assert(_sp >= chunk->start_address(), "");
 91   assert(_sp <= chunk->end_address() + frame::metadata_words, "");
 92 
 93   if (f.cb() != nullptr) {
 94     _oopmap = nullptr;
 95     _cb = f.cb();
 96   } else {
 97     get_cb();
 98   }
 99 
100   if (is_stub()) {
101     get_oopmap(pc(), 0);
102     DEBUG_ONLY(_has_stub = true);
103   } DEBUG_ONLY(else _has_stub = false;)
104 }
105 
106 template <ChunkFrames frame_kind>
107 inline bool StackChunkFrameStream<frame_kind>::is_stub() const {
108   return cb() != nullptr && _cb->is_runtime_stub();
109 }
110 
111 template <ChunkFrames frame_kind>
112 inline bool StackChunkFrameStream<frame_kind>::is_compiled() const {
113   return cb() != nullptr && _cb->is_compiled();
114 }
115 
116 template <>
117 inline bool StackChunkFrameStream<ChunkFrames::Mixed>::is_interpreted() const {
118   return !is_done() && Interpreter::contains(pc());
119 }
120 
121 template <>
122 inline bool StackChunkFrameStream<ChunkFrames::CompiledOnly>::is_interpreted() const {
123   return false;
124 }
125 
126 // StackChunkFrameStream<frame_kind>::frame_size() returns the words required to
127 // store the given frame as the only frame in a StackChunk. This is the size of the
128 // frame itself plus its stack arguments plus metadata at the caller's frame top (1)

178   return is_interpreted() ? interpreter_frame_size()
179                           : cb()->frame_size() + stack_argsize() + frame::metadata_words_at_top;
180 }
181 
182 template <ChunkFrames frame_kind>
183 inline int StackChunkFrameStream<frame_kind>::stack_argsize() const {
184   if (is_interpreted()) {
185     return interpreter_frame_stack_argsize();
186   }
187   if (is_stub()) {
188     return 0;
189   }
190   assert(cb() != nullptr, "");
191   assert(cb()->is_compiled(), "");
192   assert(cb()->as_compiled_method()->method() != nullptr, "");
193   return (cb()->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord;
194 }
195 
196 template <ChunkFrames frame_kind>
197 inline int StackChunkFrameStream<frame_kind>::num_oops() const {
198   if (is_interpreted()) {
199     return interpreter_frame_num_oops();
200   } else if (is_compiled()) {
201     return oopmap()->num_oops();
202   } else {
203     assert(is_stub(), "invariant");
204     return 0;
205   }
206 }
207 
208 template <ChunkFrames frame_kind>
209 inline void StackChunkFrameStream<frame_kind>::initialize_register_map(RegisterMap* map) {
210   update_reg_map_pd(map);
211 }
212 
213 template <ChunkFrames frame_kind>
214 template <typename RegisterMapT>
215 inline void StackChunkFrameStream<frame_kind>::next(RegisterMapT* map, bool stop) {
216   update_reg_map(map);
217   bool safepoint = is_stub();
218   if (frame_kind == ChunkFrames::Mixed) {
219     if (is_interpreted()) {
220       next_for_interpreter_frame();
221     } else {
222       _sp = _unextended_sp + cb()->frame_size();
223       if (_sp >= _end - frame::metadata_words) {
224         _sp = _end;
225       }
226       _unextended_sp = is_interpreted() ? unextended_sp_for_interpreter_frame() : _sp;
227     }
228     assert(_unextended_sp >= _sp - frame::metadata_words, "");
229   } else {
230     _sp += cb()->frame_size();
231   }
232   assert(!is_interpreted() || _unextended_sp == unextended_sp_for_interpreter_frame(), "");
233 
234   DEBUG_ONLY(_index++;)
235   if (stop) {
236     return;
237   }
238 
239   get_cb();
240   update_reg_map_pd(map);
241   if (safepoint && cb() != nullptr) { // there's no post-call nop and no fast oopmap lookup
242     _oopmap = cb()->oop_map_for_return_address(orig_pc());
243   }
244 }
245 
246 template <ChunkFrames frame_kind>
247 inline void StackChunkFrameStream<frame_kind>::get_cb() {
248   _oopmap = nullptr;
249   if (is_done() || is_interpreted()) {
250     _cb = nullptr;
251     return;
252   }
253 
254   assert(pc() != nullptr, "");
255   assert(dbg_is_safe(pc(), -1), "");
256 
257   _cb = CodeCache::find_blob_fast(pc());
258 
259   assert(_cb != nullptr, "");
260   assert(is_interpreted() || ((is_stub() || is_compiled()) && _cb->frame_size() > 0), "");
261 }
262 

289 template <typename RegisterMapT>
290 inline void* StackChunkFrameStream<frame_kind>::reg_to_loc(VMReg reg, const RegisterMapT* map) const {
291   assert(!is_done(), "");
292   return reg->is_reg() ? (void*)map->location(reg, sp()) // see frame::update_map_with_saved_link(&map, link_addr);
293                        : (void*)((address)unextended_sp() + (reg->reg2stack() * VMRegImpl::stack_slot_size));
294 }
295 
296 template<>
297 template<>
298 inline void StackChunkFrameStream<ChunkFrames::Mixed>::update_reg_map(RegisterMap* map) {
299   assert(!map->in_cont() || map->stack_chunk() == _chunk, "");
300   if (map->update_map() && is_stub()) {
301     frame f = to_frame();
302     oopmap()->update_register_map(&f, map); // we have callee-save registers in this case
303   }
304 }
305 
306 template<>
307 template<>
308 inline void StackChunkFrameStream<ChunkFrames::CompiledOnly>::update_reg_map(RegisterMap* map) {
309   assert(!map->in_cont() || map->stack_chunk() == _chunk, "");
310   if (map->update_map() && is_stub()) {

311     frame f = to_frame();
312     oopmap()->update_register_map(&f, map); // we have callee-save registers in this case
313   }
314 }
315 
316 template <ChunkFrames frame_kind>
317 template <typename RegisterMapT>
318 inline void StackChunkFrameStream<frame_kind>::update_reg_map(RegisterMapT* map) {}
319 
320 template <ChunkFrames frame_kind>
321 inline address StackChunkFrameStream<frame_kind>::orig_pc() const {
322   address pc1 = pc();
323   if (is_interpreted() || is_stub()) {
324     return pc1;
325   }
326   CompiledMethod* cm = cb()->as_compiled_method();
327   if (cm->is_deopt_pc(pc1)) {
328     pc1 = *(address*)((address)unextended_sp() + cm->orig_pc_offset());
329   }
330 
< prev index next >