< prev index next >

src/hotspot/cpu/x86/frame_x86.inline.hpp

Print this page

  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef CPU_X86_FRAME_X86_INLINE_HPP
 26 #define CPU_X86_FRAME_X86_INLINE_HPP
 27 
 28 #include "code/codeCache.hpp"
 29 #include "code/vmreg.inline.hpp"




 30 #include "runtime/registerMap.hpp"
 31 
 32 // Inline functions for Intel frames:
 33 
 34 // Constructors:
 35 
 36 inline frame::frame() {
 37   _pc = NULL;
 38   _sp = NULL;
 39   _unextended_sp = NULL;
 40   _fp = NULL;
 41   _cb = NULL;
 42   _deopt_state = unknown;

 43 }
 44 
 45 inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
 46   _sp = sp;
 47   _unextended_sp = sp;
 48   _fp = fp;
 49   _pc = pc;
 50   assert(pc != NULL, "no pc?");
 51   _cb = CodeCache::find_blob(pc);







 52   adjust_unextended_sp();
 53 
 54   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 55   if (original_pc != NULL) {
 56     _pc = original_pc;
 57     _deopt_state = is_deoptimized;


 58   } else {
 59     _deopt_state = not_deoptimized;




 60   }
 61 }
 62 
 63 inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
 64   init(sp, fp, pc);
 65 }
 66 
 67 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
 68   _sp = sp;
 69   _unextended_sp = unextended_sp;
 70   _fp = fp;
 71   _pc = pc;
 72   assert(pc != NULL, "no pc?");
 73   _cb = CodeCache::find_blob(pc);
 74   adjust_unextended_sp();

 75 
 76   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 77   if (original_pc != NULL) {
 78     _pc = original_pc;
 79     assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
 80            "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 81     _deopt_state = is_deoptimized;
 82   } else {
 83     if (_cb->is_deoptimization_stub()) {
 84       _deopt_state = is_deoptimized;
 85     } else {
 86       _deopt_state = not_deoptimized;
 87     }


















 88   }

 89 }
 90 















 91 inline frame::frame(intptr_t* sp, intptr_t* fp) {
 92   _sp = sp;
 93   _unextended_sp = sp;
 94   _fp = fp;
 95   _pc = (address)(sp[-1]);
 96 
 97   // Here's a sticky one. This constructor can be called via AsyncGetCallTrace
 98   // when last_Java_sp is non-null but the pc fetched is junk. If we are truly
 99   // unlucky the junk value could be to a zombied method and we'll die on the
100   // find_blob call. This is also why we can have no asserts on the validity
101   // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
102   // -> pd_last_frame should use a specialized version of pd_last_frame which could
103   // call a specialized frame constructor instead of this one.
104   // Then we could use the assert below. However this assert is of somewhat dubious
105   // value.
106   // UPDATE: this constructor is only used by trace_method_handle_stub() now.
107   // assert(_pc != NULL, "no pc?");
108 
109   _cb = CodeCache::find_blob(_pc);
110   adjust_unextended_sp();
111 
112   address original_pc = CompiledMethod::get_deopt_original_pc(this);
113   if (original_pc != NULL) {
114     _pc = original_pc;
115     _deopt_state = is_deoptimized;
116   } else {
117     _deopt_state = not_deoptimized;
118   }

119 }
120 
121 // Accessors
122 
123 inline bool frame::equal(frame other) const {
124   bool ret =  sp() == other.sp()
125               && unextended_sp() == other.unextended_sp()
126               && fp() == other.fp()
127               && pc() == other.pc();
128   assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
129   return ret;
130 }
131 
132 // Return unique id for this frame. The id must have a value where we can distinguish
133 // identity and younger/older relationship. NULL represents an invalid (incomparable)
134 // frame.
135 inline intptr_t* frame::id(void) const { return unextended_sp(); }
136 
137 // Return true if the frame is older (less recent activation) than the frame represented by id
138 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
139                                                     return this->id() > id ; }
140 
141 
142 
143 inline intptr_t* frame::link() const              { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
144 
145 inline intptr_t* frame::unextended_sp() const     { return _unextended_sp; }
146 















































































147 // Return address:
148 
149 inline address* frame::sender_pc_addr()      const { return (address*) addr_at( return_addr_offset); }
150 inline address  frame::sender_pc()           const { return *sender_pc_addr(); }
151 
152 inline intptr_t*    frame::sender_sp()        const { return            addr_at(   sender_sp_offset); }
153 
154 inline intptr_t** frame::interpreter_frame_locals_addr() const {
155   return (intptr_t**)addr_at(interpreter_frame_locals_offset);
156 }
157 

158 inline intptr_t* frame::interpreter_frame_last_sp() const {
159   return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset);
160 }
161 
162 inline intptr_t* frame::interpreter_frame_bcp_addr() const {
163   return (intptr_t*)addr_at(interpreter_frame_bcp_offset);
164 }
165 
166 
167 inline intptr_t* frame::interpreter_frame_mdp_addr() const {
168   return (intptr_t*)addr_at(interpreter_frame_mdp_offset);
169 }
170 
171 
172 
173 // Constant pool cache
174 
175 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
176   return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset);
177 }
178 
179 // Method
180 
181 inline Method** frame::interpreter_frame_method_addr() const {
182   return (Method**)addr_at(interpreter_frame_method_offset);
183 }
184 
185 // Mirror
186 
187 inline oop* frame::interpreter_frame_mirror_addr() const {
188   return (oop*)addr_at(interpreter_frame_mirror_offset);
189 }
190 
191 // top of expression stack

192 inline intptr_t* frame::interpreter_frame_tos_address() const {
193   intptr_t* last_sp = interpreter_frame_last_sp();
194   if (last_sp == NULL) {
195     return sp();
196   } else {
197     // sp() may have been extended or shrunk by an adapter.  At least
198     // check that we don't fall behind the legal region.
199     // For top deoptimized frame last_sp == interpreter_frame_monitor_end.
200     assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
201     return last_sp;
202   }
203 }
204 
205 inline oop* frame::interpreter_frame_temp_oop_addr() const {
206   return (oop *)(fp() + interpreter_frame_oop_temp_offset);
207 }
208 
209 inline int frame::interpreter_frame_monitor_size() {
210   return BasicObjectLock::size();
211 }
212 
213 
214 // expression stack
215 // (the max_stack arguments are used by the GC; see class FrameClosure)
216 

217 inline intptr_t* frame::interpreter_frame_expression_stack() const {
218   intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
219   return monitor_end-1;
220 }
221 
222 // Entry frames
223 
224 inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
225  return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
226 }
227 
228 // Compiled frames
229 
230 // Register is a class, but it would be assigned numerical value.
231 // "0" is assigned for rax. Thus we need to ignore -Wnonnull.
232 PRAGMA_DIAG_PUSH
233 PRAGMA_NONNULL_IGNORED
234 inline oop frame::saved_oop_result(RegisterMap* map) const {
235   oop* result_adr = (oop *)map->location(rax->as_VMReg());
236   guarantee(result_adr != NULL, "bad register save location");

237 
238   return (*result_adr);



239 }
240 
241 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
242   oop* result_adr = (oop *)map->location(rax->as_VMReg());
243   guarantee(result_adr != NULL, "bad register save location");
244 
245   *result_adr = obj;
246 }
247 PRAGMA_DIAG_POP
248 






































































































249 #endif // CPU_X86_FRAME_X86_INLINE_HPP

  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef CPU_X86_FRAME_X86_INLINE_HPP
 26 #define CPU_X86_FRAME_X86_INLINE_HPP
 27 
 28 #include "code/codeCache.inline.hpp"
 29 #include "code/vmreg.inline.hpp"
 30 #include "compiler/oopMap.inline.hpp"
 31 #include "interpreter/interpreter.hpp"
 32 #include "interpreter/oopMapCache.hpp"
 33 #include "runtime/sharedRuntime.hpp"
 34 #include "runtime/registerMap.hpp"
 35 
 36 // Inline functions for Intel frames:
 37 
 38 // Constructors:
 39 
 40 inline frame::frame() {
 41   _pc = NULL;
 42   _sp = NULL;
 43   _unextended_sp = NULL;
 44   _fp = NULL;
 45   _cb = NULL;
 46   _deopt_state = unknown;
 47   _oop_map = NULL;
 48 }
 49 
 50 inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
 51   _sp = sp;
 52   _unextended_sp = sp;
 53   _fp = fp;
 54   _pc = pc;
 55   assert(pc != NULL, "no pc?");
 56   _cb = CodeCache::find_blob(pc); // not fast because this constructor can be used on native frames
 57   
 58   setup(pc);
 59 
 60   _oop_map = NULL;
 61 }
 62 
 63 inline void frame::setup(address pc) {
 64   adjust_unextended_sp();
 65 
 66   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 67   if (original_pc != NULL) {
 68     _pc = original_pc;
 69     _deopt_state = is_deoptimized;
 70     assert(_cb == NULL || _cb->as_compiled_method()->insts_contains_inclusive(_pc),
 71            "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 72   } else {
 73     if (_cb == SharedRuntime::deopt_blob()) {
 74       _deopt_state = is_deoptimized;
 75     } else {
 76       _deopt_state = not_deoptimized;
 77     }
 78   }
 79 }
 80 
 81 inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
 82   init(sp, fp, pc);
 83 }
 84 
 85 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb) {
 86   _sp = sp;
 87   _unextended_sp = unextended_sp;
 88   _fp = fp;
 89   _pc = pc;
 90   assert(pc != NULL, "no pc?");
 91   _cb = cb;
 92   _oop_map = NULL;
 93   assert(_cb != NULL, "pc: " INTPTR_FORMAT, p2i(pc));
 94 
 95   setup(pc);
 96 }
 97 
 98 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map) {
 99   _sp = sp;
100   _unextended_sp = unextended_sp;
101   _fp = fp;
102   _pc = pc;
103   assert(pc != NULL, "no pc?");
104   _cb = cb;
105   _oop_map = oop_map;
106   assert(_cb != NULL, "pc: " INTPTR_FORMAT, p2i(pc));
107 
108   setup(pc);
109 }
110 
111 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map, bool dummy) {
112   _sp = sp;
113   _unextended_sp = unextended_sp;
114   _fp = fp;
115   _pc = pc;
116   _cb = cb;
117   _oop_map = oop_map;
118   _deopt_state = not_deoptimized;
119 #ifdef ASSERT
120   // The following assertion has been disabled because it would sometime trap for Continuation.run, which is not *in* a continuation
121   // and therefore does not clear the _cont_fastpath flag, but this is benign even in fast mode (see Freeze::setup_jump)
122   if (cb != NULL) {
123     setup(pc);
124     assert(_pc == pc && _deopt_state == not_deoptimized, "");
125   }
126 #endif
127 }
128 
129 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
130   _sp = sp;
131   _unextended_sp = unextended_sp;
132   _fp = fp;
133   _pc = pc;
134   assert(pc != NULL, "no pc?");
135   _cb = CodeCache::find_blob_fast(pc);
136   _oop_map = NULL;
137   assert(_cb != NULL, "pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " unextended_sp: " INTPTR_FORMAT " fp: " INTPTR_FORMAT, p2i(pc), p2i(sp), p2i(unextended_sp), p2i(fp));
138 
139   setup(pc);
140 }
141 
142 inline frame::frame(intptr_t* sp) : frame(sp, sp, *(intptr_t**)(sp - frame::sender_sp_offset), *(address*)(sp - 1)) {}
143 
144 inline frame::frame(intptr_t* sp, intptr_t* fp) {
145   _sp = sp;
146   _unextended_sp = sp;
147   _fp = fp;
148   _pc = (address)(sp[-1]);
149 
150   // Here's a sticky one. This constructor can be called via AsyncGetCallTrace
151   // when last_Java_sp is non-null but the pc fetched is junk. If we are truly
152   // unlucky the junk value could be to a zombied method and we'll die on the
153   // find_blob call. This is also why we can have no asserts on the validity
154   // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
155   // -> pd_last_frame should use a specialized version of pd_last_frame which could
156   // call a specialized frame constructor instead of this one.
157   // Then we could use the assert below. However this assert is of somewhat dubious
158   // value.
159   // UPDATE: this constructor is only used by trace_method_handle_stub() now.
160   // assert(_pc != NULL, "no pc?");
161 
162   _cb = CodeCache::find_blob(_pc);
163   adjust_unextended_sp();
164 
165   address original_pc = CompiledMethod::get_deopt_original_pc(this);
166   if (original_pc != NULL) {
167     _pc = original_pc;
168     _deopt_state = is_deoptimized;
169   } else {
170     _deopt_state = not_deoptimized;
171   }
172   _oop_map = NULL;
173 }
174 
175 // Accessors
176 
177 inline bool frame::equal(frame other) const {
178   bool ret =  sp() == other.sp()
179               && unextended_sp() == other.unextended_sp()
180               && fp() == other.fp()
181               && pc() == other.pc();
182   assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
183   return ret;
184 }
185 
186 // Return unique id for this frame. The id must have a value where we can distinguish
187 // identity and younger/older relationship. NULL represents an invalid (incomparable)
188 // frame.
189 inline intptr_t* frame::id(void) const { return unextended_sp(); }
190 
191 // Return true if the frame is older (less recent activation) than the frame represented by id
192 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
193                                                     return this->id() > id ; }
194 
195 
196 
197 inline intptr_t* frame::link() const              { return *(intptr_t **)addr_at(link_offset); }
198 
199 inline intptr_t* frame::unextended_sp() const     { return _unextended_sp; }
200 
201 inline void frame::set_unextended_sp(intptr_t* value) { _unextended_sp = value; }
202 
203 inline int frame::offset_unextended_sp() const { return (int)(intptr_t)_unextended_sp; }
204 inline void frame::set_offset_unextended_sp(int value) { _unextended_sp = (intptr_t*)(intptr_t)value; }
205 
206 
207 inline intptr_t* frame::real_fp() const {
208   if (_cb != NULL) {
209     // use the frame size if valid
210     int size = _cb->frame_size();
211     if (size > 0) {
212       return unextended_sp() + size;
213     }
214   }
215   // else rely on fp()
216   assert(! is_compiled_frame(), "unknown compiled frame size");
217   return fp();
218 }
219 
220 inline int frame::frame_size() const {
221   return is_interpreted_frame()
222     ? sender_sp() - sp()
223     : cb()->frame_size();
224 }
225 
226 inline int frame::num_oops() const {
227   assert (!is_interpreted_frame(), "interpreted");
228   assert (oop_map() != NULL, "");
229   return oop_map()->num_oops() ;
230 }
231 
232 inline int frame::compiled_frame_stack_argsize() const {
233   assert (cb()->is_compiled(), "");
234   return (cb()->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord;
235 }
236 
237 inline void frame::interpreted_frame_oop_map(InterpreterOopMap* mask) const {
238   assert (mask != NULL, "");
239   Method* m = interpreter_frame_method();
240   int   bci = interpreter_frame_bci();
241   m->mask_for(bci, mask); // OopMapCache::compute_one_oop_map(m, bci, mask);
242 }
243 
244 
245 inline int frame::interpreted_frame_num_oops(InterpreterOopMap* mask) const {
246   return   mask->num_oops()
247         + 1 // for the mirror oop
248         + ((intptr_t*)interpreter_frame_monitor_begin() - (intptr_t*)interpreter_frame_monitor_end())/BasicObjectLock::size();
249 }
250 
251 // helper to update a map with callee-saved RBP
252 
253 template <typename RegisterMapT>
254 void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr) {
255   // The interpreter and compiler(s) always save EBP/RBP in a known
256   // location on entry. We must record where that location is
257   // so this if EBP/RBP was live on callout from c2 we can find
258   // the saved copy no matter what it called.
259 
260   // Since the interpreter always saves EBP/RBP if we record where it is then
261   // we don't have to always save EBP/RBP on entry and exit to c2 compiled
262   // code, on entry will be enough.
263   map->set_location(rbp->as_VMReg(), (address) link_addr);
264 #ifdef AMD64
265   // this is weird "H" ought to be at a higher address however the
266   // oopMaps seems to have the "H" regs at the same address and the
267   // vanilla register.
268   // XXXX make this go away
269   if (true) {
270     map->set_location(rbp->as_VMReg()->next(), (address) link_addr);
271   }
272 #endif // AMD64
273 }
274 
275 template <typename RegisterMapT>
276 intptr_t** frame::saved_link_address(const RegisterMapT* map) {
277   return (intptr_t**)map->location(rbp->as_VMReg());
278 }
279 
280 // Return address:
281 
282 inline address* frame::sender_pc_addr()      const { return (address*) addr_at(return_addr_offset); }
283 inline address  frame::sender_pc()           const { return *sender_pc_addr(); }
284 
285 inline intptr_t* frame::sender_sp()          const { return            addr_at(sender_sp_offset); }
286 
287 inline intptr_t** frame::interpreter_frame_locals_addr() const {
288   return (intptr_t**)addr_at(interpreter_frame_locals_offset);
289 }
290 
291 template <bool relative>
292 inline intptr_t* frame::interpreter_frame_last_sp() const {
293   return (intptr_t*)at<relative>(interpreter_frame_last_sp_offset);
294 }
295 
296 inline intptr_t* frame::interpreter_frame_bcp_addr() const {
297   return (intptr_t*)addr_at(interpreter_frame_bcp_offset);
298 }
299 

300 inline intptr_t* frame::interpreter_frame_mdp_addr() const {
301   return (intptr_t*)addr_at(interpreter_frame_mdp_offset);
302 }
303 
304 
305 
306 // Constant pool cache
307 
308 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
309   return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset);
310 }
311 
312 // Method
313 
314 inline Method** frame::interpreter_frame_method_addr() const {
315   return (Method**)addr_at(interpreter_frame_method_offset);
316 }
317 
318 // Mirror
319 
320 inline oop* frame::interpreter_frame_mirror_addr() const {
321   return (oop*)addr_at(interpreter_frame_mirror_offset);
322 }
323 
324 // top of expression stack
325 template <bool relative>
326 inline intptr_t* frame::interpreter_frame_tos_address() const {
327   intptr_t* last_sp = interpreter_frame_last_sp<relative>();
328   if (last_sp == NULL) {
329     return sp();
330   } else {
331     // sp() may have been extended or shrunk by an adapter.  At least
332     // check that we don't fall behind the legal region.
333     // For top deoptimized frame last_sp == interpreter_frame_monitor_end.
334     assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end<relative>(), "bad tos");
335     return last_sp;
336   }
337 }
338 
339 inline oop* frame::interpreter_frame_temp_oop_addr() const {
340   return (oop *)(fp() + interpreter_frame_oop_temp_offset);
341 }
342 
343 inline int frame::interpreter_frame_monitor_size() {
344   return BasicObjectLock::size();
345 }
346 
347 
348 // expression stack
349 // (the max_stack arguments are used by the GC; see class FrameClosure)
350 
351 template <bool relative>
352 inline intptr_t* frame::interpreter_frame_expression_stack() const {
353   intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end<relative>();
354   return monitor_end-1;
355 }
356 
357 // Entry frames
358 
359 inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
360  return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
361 }
362 
363 // Compiled frames
364 
365 // Register is a class, but it would be assigned numerical value.
366 // "0" is assigned for rax. Thus we need to ignore -Wnonnull.
367 PRAGMA_DIAG_PUSH
368 PRAGMA_NONNULL_IGNORED
369 inline oop frame::saved_oop_result(RegisterMap* map) const {
370   oop* result_adr = (oop *)map->location(rax->as_VMReg(), sp());
371   guarantee(result_adr != NULL, "bad register save location");
372   oop result = *result_adr;
373 
374   // TODO: Erik: remove after integration with concurrent stack scanning
375   result = NativeAccess<>::oop_load(&result);
376 
377   return result;
378 }
379 
380 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
381   oop* result_adr = (oop *)map->location(rax->as_VMReg(), sp());
382   guarantee(result_adr != NULL, "bad register save location");
383 
384   *result_adr = obj;
385 }
386 PRAGMA_DIAG_POP
387 
388 inline bool frame::is_interpreted_frame() const {
389   return Interpreter::contains(pc());
390 }
391 
392 inline int frame::sender_sp_ret_address_offset() {
393   return frame::sender_sp_offset - frame::return_addr_offset;
394 }
395 
396 inline const ImmutableOopMap* frame::get_oop_map() const {
397   if (_cb == NULL) return NULL;
398   if (_cb->oop_maps() != NULL) {
399     NativePostCallNop* nop = nativePostCallNop_at(_pc);
400     if (nop != NULL && nop->displacement() != 0) {
401       int slot = ((nop->displacement() >> 24) & 0xff);
402       return _cb->oop_map_for_slot(slot, _pc);
403     }
404     const ImmutableOopMap* oop_map = OopMapSet::find_map(this);
405     return oop_map;
406   }
407   return NULL;
408 }
409 
410 inline frame frame::sender_raw(RegisterMap* map) const {
411   // Default is we done have to follow them. The sender_for_xxx will
412   // update it accordingly
413   map->set_include_argument_oops(false);
414 
415   if (map->in_cont()) { // already in an h-stack
416     return map->stack_chunk()->sender(*this, map);
417   }
418 
419   if (is_entry_frame())           return sender_for_entry_frame(map);
420   if (is_optimized_entry_frame()) return sender_for_optimized_entry_frame(map);
421   if (is_interpreted_frame())     return sender_for_interpreter_frame(map);
422 
423   assert(_cb == CodeCache::find_blob(pc()), "Must be the same");
424 
425   if (_cb != NULL) {
426     return _cb->is_compiled() ? sender_for_compiled_frame<false>(map) : sender_for_compiled_frame<true>(map);
427   }
428   // Must be native-compiled frame, i.e. the marshaling code for native
429   // methods that exists in the core system.
430   return frame(sender_sp(), link(), sender_pc());
431 }
432 
433 template <bool stub>
434 frame frame::sender_for_compiled_frame(RegisterMap* map) const {
435   assert(map != NULL, "map must be set");
436 
437   // frame owned by optimizing compiler
438   assert(_cb->frame_size() >= 0, "must have non-zero frame size");
439   intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
440   assert (sender_sp == real_fp(), "");
441 
442   // On Intel the return_address is always the word on the stack
443   address sender_pc = (address) *(sender_sp-1);
444 
445   // This is the saved value of EBP which may or may not really be an FP.
446   // It is only an FP if the sender is an interpreter frame (or C1?).
447   // saved_fp_addr should be correct even for a bottom thawed frame (with a return barrier)
448   intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
449 
450   if (map->update_map()) {
451     // Tell GC to use argument oopmaps for some runtime stubs that need it.
452     // For C1, the runtime stub might not have oop maps, so set this flag
453     // outside of update_register_map.
454     if (stub) { // compiled frames do not use callee-saved registers
455       map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
456       if (oop_map() != NULL) { 
457         _oop_map->update_register_map(this, map);
458       }
459     } else {
460       assert (!_cb->caller_must_gc_arguments(map->thread()), "");
461       assert (!map->include_argument_oops(), "");
462       assert (oop_map() == NULL || !oop_map()->has_any(OopMapValue::callee_saved_value), "callee-saved value in compiled frame");
463     }
464 
465     // Since the prolog does the save and restore of EBP there is no oopmap
466     // for it so we must fill in its location as if there was an oopmap entry
467     // since if our caller was compiled code there could be live jvm state in it.
468     update_map_with_saved_link(map, saved_fp_addr);
469   }
470 
471   assert(sender_sp != sp(), "must have changed");
472 
473   if (Continuation::is_return_barrier_entry(sender_pc)) {	
474     if (map->walk_cont()) { // about to walk into an h-stack 	
475       return Continuation::top_frame(*this, map);	
476     } else {
477       Continuation::fix_continuation_bottom_sender(map->thread(), *this, &sender_pc, &sender_sp);	
478     }
479   }
480 
481   intptr_t* unextended_sp = sender_sp;
482   CodeBlob* sender_cb = CodeCache::find_blob_fast(sender_pc);
483   if (sender_cb != NULL) {
484     return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc, sender_cb);
485   }
486   // tty->print_cr(">>>> NO CB sender_pc: %p", sender_pc); os::print_location(tty, (intptr_t)sender_pc); print_on(tty);
487   return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
488 }
489 
490 #endif // CPU_X86_FRAME_X86_INLINE_HPP
< prev index next >