< prev index next >

src/cpu/aarch64/vm/frame_aarch64.cpp

Print this page
rev 8300 : 8079564: Use FP register as proper frame pointer in JIT compiled code on aarch64
Summary: Add support for PreserveFramePointer for debug/profile
Reviewed-by: duke


 206 
 207       if (!saved_fp_safe) {
 208         return false;
 209       }
 210 
 211       // construct the potential sender
 212 
 213       frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
 214 
 215       // Validate the JavaCallWrapper an entry frame must have
 216       address jcw = (address)sender.entry_frame_call_wrapper();
 217 
 218       bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
 219 
 220       return jcw_safe;
 221     }
 222 
 223     if (sender_blob->is_nmethod()) {
 224         nmethod* nm = sender_blob->as_nmethod_or_null();
 225         if (nm != NULL) {
 226             if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {

 227                 return false;
 228             }
 229         }
 230     }
 231 
 232     // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
 233     // because the return address counts against the callee's frame.
 234 
 235     if (sender_blob->frame_size() <= 0) {
 236       assert(!sender_blob->is_nmethod(), "should count return address at least");
 237       return false;
 238     }
 239 
 240     // We should never be able to see anything here except an nmethod. If something in the
 241     // code cache (current frame) is called by an entity within the code cache that entity
 242     // should not be anything but the call stub (already covered), the interpreter (already covered)
 243     // or an nmethod.
 244 
 245     if (!sender_blob->is_nmethod()) {
 246         return false;


 372   assert(map != NULL, "map must be set");
 373   // Java frame called from C; skip all C frames and return top C
 374   // frame of that chunk as the sender
 375   JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
 376   assert(!entry_frame_is_first(), "next Java fp must be non zero");
 377   assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
 378   map->clear();
 379   assert(map->include_argument_oops(), "should be set by clear");
 380   if (jfa->last_Java_pc() != NULL ) {
 381     frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
 382     return fr;
 383   }
 384   frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
 385   return fr;
 386 }
 387 
 388 //------------------------------------------------------------------------------
 389 // frame::verify_deopt_original_pc
 390 //
 391 // Verifies the calculated original PC of a deoptimization PC for the
 392 // given unextended SP.  The unextended SP might also be the saved SP
 393 // for MethodHandle call sites.
 394 #ifdef ASSERT
 395 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
 396   frame fr;
 397 
 398   // This is ugly but it's better than to change {get,set}_original_pc
 399   // to take an SP value as argument.  And it's only a debugging
 400   // method anyway.
 401   fr._unextended_sp = unextended_sp;
 402 
 403   address original_pc = nm->get_original_pc(&fr);
 404   assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
 405   assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
 406 }
 407 #endif
 408 
 409 //------------------------------------------------------------------------------
 410 // frame::adjust_unextended_sp
 411 void frame::adjust_unextended_sp() {
 412   // If we are returning to a compiled MethodHandle call site, the
 413   // saved_fp will in fact be a saved value of the unextended SP.  The
 414   // simplest way to tell whether we are returning to such a call site
 415   // is as follows:
 416 
 417   nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
 418   if (sender_nm != NULL) {
 419     // If the sender PC is a deoptimization point, get the original
 420     // PC.  For MethodHandle call site the unextended_sp is stored in
 421     // saved_fp.
 422     if (sender_nm->is_deopt_mh_entry(_pc)) {
 423       DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp));
 424       _unextended_sp = _fp;
 425     }
 426     else if (sender_nm->is_deopt_entry(_pc)) {
 427       DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
 428     }
 429     else if (sender_nm->is_method_handle_return(_pc)) {
 430       _unextended_sp = _fp;
 431     }
 432   }
 433 }
 434 
 435 //------------------------------------------------------------------------------
 436 // frame::update_map_with_saved_link
 437 void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) {
 438   // The interpreter and compiler(s) always save fp in a known
 439   // location on entry. We must record where that location is
 440   // so that if fp was live on callout from c2 we can find
 441   // the saved copy no matter what it called.
 442 
 443   // Since the interpreter always saves fp if we record where it is then
 444   // we don't have to always save fp on entry and exit to c2 compiled
 445   // code, on entry will be enough.
 446   map->set_location(rfp->as_VMReg(), (address) link_addr);
 447   // this is weird "H" ought to be at a higher address however the
 448   // oopMaps seems to have the "H" regs at the same address and the
 449   // vanilla register.
 450   // XXXX make this go away




 206 
 207       if (!saved_fp_safe) {
 208         return false;
 209       }
 210 
 211       // construct the potential sender
 212 
 213       frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
 214 
 215       // Validate the JavaCallWrapper an entry frame must have
 216       address jcw = (address)sender.entry_frame_call_wrapper();
 217 
 218       bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
 219 
 220       return jcw_safe;
 221     }
 222 
 223     if (sender_blob->is_nmethod()) {
 224         nmethod* nm = sender_blob->as_nmethod_or_null();
 225         if (nm != NULL) {
 226             if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
 227                 nm->method()->is_method_handle_intrinsic()) {
 228                 return false;
 229             }
 230         }
 231     }
 232 
 233     // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
 234     // because the return address counts against the callee's frame.
 235 
 236     if (sender_blob->frame_size() <= 0) {
 237       assert(!sender_blob->is_nmethod(), "should count return address at least");
 238       return false;
 239     }
 240 
 241     // We should never be able to see anything here except an nmethod. If something in the
 242     // code cache (current frame) is called by an entity within the code cache that entity
 243     // should not be anything but the call stub (already covered), the interpreter (already covered)
 244     // or an nmethod.
 245 
 246     if (!sender_blob->is_nmethod()) {
 247         return false;


 373   assert(map != NULL, "map must be set");
 374   // Java frame called from C; skip all C frames and return top C
 375   // frame of that chunk as the sender
 376   JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();
 377   assert(!entry_frame_is_first(), "next Java fp must be non zero");
 378   assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack");
 379   map->clear();
 380   assert(map->include_argument_oops(), "should be set by clear");
 381   if (jfa->last_Java_pc() != NULL ) {
 382     frame fr(jfa->last_Java_sp(), jfa->last_Java_fp(), jfa->last_Java_pc());
 383     return fr;
 384   }
 385   frame fr(jfa->last_Java_sp(), jfa->last_Java_fp());
 386   return fr;
 387 }
 388 
 389 //------------------------------------------------------------------------------
 390 // frame::verify_deopt_original_pc
 391 //
 392 // Verifies the calculated original PC of a deoptimization PC for the
 393 // given unextended SP.

 394 #ifdef ASSERT
 395 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) {
 396   frame fr;
 397 
 398   // This is ugly but it's better than to change {get,set}_original_pc
 399   // to take an SP value as argument.  And it's only a debugging
 400   // method anyway.
 401   fr._unextended_sp = unextended_sp;
 402 
 403   address original_pc = nm->get_original_pc(&fr);
 404   assert(nm->insts_contains(original_pc), "original PC must be in nmethod");

 405 }
 406 #endif
 407 
 408 //------------------------------------------------------------------------------
 409 // frame::adjust_unextended_sp
 410 void frame::adjust_unextended_sp() {
 411   // On aarch64, sites calling method handle intrinsics and lambda forms are treated
 412   // as any other call site. Therefore, no special action is needed when we are
 413   // returning to any of these call sites.

 414 
 415   nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
 416   if (sender_nm != NULL) {
 417     // If the sender PC is a deoptimization point, get the original PC.
 418     if (sender_nm->is_deopt_entry(_pc) ||
 419         sender_nm->is_deopt_mh_entry(_pc)) {





 420       DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));



 421     }
 422   }
 423 }
 424 
 425 //------------------------------------------------------------------------------
 426 // frame::update_map_with_saved_link
 427 void frame::update_map_with_saved_link(RegisterMap* map, intptr_t** link_addr) {
 428   // The interpreter and compiler(s) always save fp in a known
 429   // location on entry. We must record where that location is
 430   // so that if fp was live on callout from c2 we can find
 431   // the saved copy no matter what it called.
 432 
 433   // Since the interpreter always saves fp if we record where it is then
 434   // we don't have to always save fp on entry and exit to c2 compiled
 435   // code, on entry will be enough.
 436   map->set_location(rfp->as_VMReg(), (address) link_addr);
 437   // this is weird "H" ought to be at a higher address however the
 438   // oopMaps seems to have the "H" regs at the same address and the
 439   // vanilla register.
 440   // XXXX make this go away


< prev index next >