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