comparison src/cpu/x86/vm/frame_x86.cpp @ 23050:e8260b6328fb

8068945: Use RBP register as proper frame pointer in JIT compiled code on x86 Summary: Introduce the PreserveFramePointer flag to control if RBP is used as the frame pointer or as a general purpose register. Reviewed-by: kvn, roland, dlong, enevill, shade
author zmajo
date Fri, 29 May 2015 10:58:45 +0200
parents f43fad8786fc
children dd9cc155639c
comparison
equal deleted inserted replaced
23049:a1642365d69f 23050:e8260b6328fb
214 } 214 }
215 215
216 if (sender_blob->is_nmethod()) { 216 if (sender_blob->is_nmethod()) {
217 nmethod* nm = sender_blob->as_nmethod_or_null(); 217 nmethod* nm = sender_blob->as_nmethod_or_null();
218 if (nm != NULL) { 218 if (nm != NULL) {
219 if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) { 219 if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
220 nm->method()->is_method_handle_intrinsic()) {
220 return false; 221 return false;
221 } 222 }
222 } 223 }
223 } 224 }
224 225
381 382
382 //------------------------------------------------------------------------------ 383 //------------------------------------------------------------------------------
383 // frame::verify_deopt_original_pc 384 // frame::verify_deopt_original_pc
384 // 385 //
385 // Verifies the calculated original PC of a deoptimization PC for the 386 // Verifies the calculated original PC of a deoptimization PC for the
386 // given unextended SP. The unextended SP might also be the saved SP 387 // given unextended SP.
387 // for MethodHandle call sites.
388 #ifdef ASSERT 388 #ifdef ASSERT
389 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { 389 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) {
390 frame fr; 390 frame fr;
391 391
392 // This is ugly but it's better than to change {get,set}_original_pc 392 // This is ugly but it's better than to change {get,set}_original_pc
393 // to take an SP value as argument. And it's only a debugging 393 // to take an SP value as argument. And it's only a debugging
394 // method anyway. 394 // method anyway.
395 fr._unextended_sp = unextended_sp; 395 fr._unextended_sp = unextended_sp;
396 396
397 address original_pc = nm->get_original_pc(&fr); 397 address original_pc = nm->get_original_pc(&fr);
398 assert(nm->insts_contains(original_pc), "original PC must be in nmethod"); 398 assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
399 assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
400 } 399 }
401 #endif 400 #endif
402 401
403 //------------------------------------------------------------------------------ 402 //------------------------------------------------------------------------------
404 // frame::adjust_unextended_sp 403 // frame::adjust_unextended_sp
405 void frame::adjust_unextended_sp() { 404 void frame::adjust_unextended_sp() {
406 // If we are returning to a compiled MethodHandle call site, the 405 // On x86, sites calling method handle intrinsics and lambda forms are treated
407 // saved_fp will in fact be a saved value of the unextended SP. The 406 // as any other call site. Therefore, no special action is needed when we are
408 // simplest way to tell whether we are returning to such a call site 407 // returning to any of these call sites.
409 // is as follows:
410 408
411 nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null(); 409 nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
412 if (sender_nm != NULL) { 410 if (sender_nm != NULL) {
413 // If the sender PC is a deoptimization point, get the original 411 // If the sender PC is a deoptimization point, get the original PC.
414 // PC. For MethodHandle call site the unextended_sp is stored in 412 if (sender_nm->is_deopt_entry(_pc) ||
415 // saved_fp. 413 sender_nm->is_deopt_mh_entry(_pc)) {
416 if (sender_nm->is_deopt_mh_entry(_pc)) {
417 DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp));
418 _unextended_sp = _fp;
419 }
420 else if (sender_nm->is_deopt_entry(_pc)) {
421 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp)); 414 DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
422 }
423 else if (sender_nm->is_method_handle_return(_pc)) {
424 _unextended_sp = _fp;
425 } 415 }
426 } 416 }
427 } 417 }
428 418
429 //------------------------------------------------------------------------------ 419 //------------------------------------------------------------------------------