387 |
388 |
388 //------------------------------------------------------------------------------ |
389 //------------------------------------------------------------------------------ |
389 // frame::verify_deopt_original_pc |
390 // frame::verify_deopt_original_pc |
390 // |
391 // |
391 // Verifies the calculated original PC of a deoptimization PC for the |
392 // 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 // given unextended SP. |
393 // for MethodHandle call sites. |
|
394 #ifdef ASSERT |
394 #ifdef ASSERT |
395 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) { |
395 void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) { |
396 frame fr; |
396 frame fr; |
397 |
397 |
398 // This is ugly but it's better than to change {get,set}_original_pc |
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 |
399 // to take an SP value as argument. And it's only a debugging |
400 // method anyway. |
400 // method anyway. |
401 fr._unextended_sp = unextended_sp; |
401 fr._unextended_sp = unextended_sp; |
402 |
402 |
403 address original_pc = nm->get_original_pc(&fr); |
403 address original_pc = nm->get_original_pc(&fr); |
404 assert(nm->insts_contains(original_pc), "original PC must be in nmethod"); |
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 } |
405 } |
407 #endif |
406 #endif |
408 |
407 |
409 //------------------------------------------------------------------------------ |
408 //------------------------------------------------------------------------------ |
410 // frame::adjust_unextended_sp |
409 // frame::adjust_unextended_sp |
411 void frame::adjust_unextended_sp() { |
410 void frame::adjust_unextended_sp() { |
412 // If we are returning to a compiled MethodHandle call site, the |
411 // On aarch64, sites calling method handle intrinsics and lambda forms are treated |
413 // saved_fp will in fact be a saved value of the unextended SP. The |
412 // as any other call site. Therefore, no special action is needed when we are |
414 // simplest way to tell whether we are returning to such a call site |
413 // returning to any of these call sites. |
415 // is as follows: |
|
416 |
414 |
417 nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null(); |
415 nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null(); |
418 if (sender_nm != NULL) { |
416 if (sender_nm != NULL) { |
419 // If the sender PC is a deoptimization point, get the original |
417 // If the sender PC is a deoptimization point, get the original PC. |
420 // PC. For MethodHandle call site the unextended_sp is stored in |
418 if (sender_nm->is_deopt_entry(_pc) || |
421 // saved_fp. |
419 sender_nm->is_deopt_mh_entry(_pc)) { |
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)); |
420 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 } |
421 } |
432 } |
422 } |
433 } |
423 } |
434 |
424 |
435 //------------------------------------------------------------------------------ |
425 //------------------------------------------------------------------------------ |