424 // control the area where we can allow a safepoint. After we exit the safepoint area we can |
424 // control the area where we can allow a safepoint. After we exit the safepoint area we can |
425 // check to see if the handler we are going to return is now in a nmethod that has |
425 // check to see if the handler we are going to return is now in a nmethod that has |
426 // been deoptimized. If that is the case we return the deopt blob |
426 // been deoptimized. If that is the case we return the deopt blob |
427 // unpack_with_exception entry instead. This makes life for the exception blob easier |
427 // unpack_with_exception entry instead. This makes life for the exception blob easier |
428 // because making that same check and diverting is painful from assembly language. |
428 // because making that same check and diverting is painful from assembly language. |
429 // |
|
430 |
|
431 |
|
432 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm)) |
429 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm)) |
|
430 // Reset method handle flag. |
|
431 thread->set_is_method_handle_return(false); |
433 |
432 |
434 Handle exception(thread, ex); |
433 Handle exception(thread, ex); |
435 nm = CodeCache::find_nmethod(pc); |
434 nm = CodeCache::find_nmethod(pc); |
436 assert(nm != NULL, "this is not an nmethod"); |
435 assert(nm != NULL, "this is not an nmethod"); |
437 // Adjust the pc as needed/ |
436 // Adjust the pc as needed/ |
478 assert(caller_is_deopted(), "Must be deoptimized"); |
477 assert(caller_is_deopted(), "Must be deoptimized"); |
479 |
478 |
480 return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); |
479 return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); |
481 } |
480 } |
482 |
481 |
483 // ExceptionCache is used only for exceptions at call and not for implicit exceptions |
482 // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions |
484 if (guard_pages_enabled) { |
483 if (guard_pages_enabled) { |
485 address fast_continuation = nm->handler_for_exception_and_pc(exception, pc); |
484 address fast_continuation = nm->handler_for_exception_and_pc(exception, pc); |
486 if (fast_continuation != NULL) { |
485 if (fast_continuation != NULL) { |
487 if (fast_continuation == ExceptionCache::unwind_handler()) fast_continuation = NULL; |
486 // Set flag if return address is a method handle call site. |
|
487 thread->set_is_method_handle_return(nm->is_method_handle_return(pc)); |
488 return fast_continuation; |
488 return fast_continuation; |
489 } |
489 } |
490 } |
490 } |
491 |
491 |
492 // If the stack guard pages are enabled, check whether there is a handler in |
492 // If the stack guard pages are enabled, check whether there is a handler in |
520 // If an exception was thrown during exception dispatch, the exception oop may have changed |
520 // If an exception was thrown during exception dispatch, the exception oop may have changed |
521 thread->set_exception_oop(exception()); |
521 thread->set_exception_oop(exception()); |
522 thread->set_exception_pc(pc); |
522 thread->set_exception_pc(pc); |
523 |
523 |
524 // the exception cache is used only by non-implicit exceptions |
524 // the exception cache is used only by non-implicit exceptions |
525 if (continuation == NULL) { |
525 if (continuation != NULL) { |
526 nm->add_handler_for_exception_and_pc(exception, pc, ExceptionCache::unwind_handler()); |
|
527 } else { |
|
528 nm->add_handler_for_exception_and_pc(exception, pc, continuation); |
526 nm->add_handler_for_exception_and_pc(exception, pc, continuation); |
529 } |
527 } |
530 } |
528 } |
531 |
529 |
532 thread->set_vm_result(exception()); |
530 thread->set_vm_result(exception()); |
|
531 // Set flag if return address is a method handle call site. |
|
532 thread->set_is_method_handle_return(nm->is_method_handle_return(pc)); |
533 |
533 |
534 if (TraceExceptions) { |
534 if (TraceExceptions) { |
535 ttyLocker ttyl; |
535 ttyLocker ttyl; |
536 ResourceMark rm; |
536 ResourceMark rm; |
537 tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT, |
537 tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT, |
540 |
540 |
541 return continuation; |
541 return continuation; |
542 JRT_END |
542 JRT_END |
543 |
543 |
544 // Enter this method from compiled code only if there is a Java exception handler |
544 // Enter this method from compiled code only if there is a Java exception handler |
545 // in the method handling the exception |
545 // in the method handling the exception. |
546 // We are entering here from exception stub. We don't do a normal VM transition here. |
546 // We are entering here from exception stub. We don't do a normal VM transition here. |
547 // We do it in a helper. This is so we can check to see if the nmethod we have just |
547 // We do it in a helper. This is so we can check to see if the nmethod we have just |
548 // searched for an exception handler has been deoptimized in the meantime. |
548 // searched for an exception handler has been deoptimized in the meantime. |
549 address Runtime1::exception_handler_for_pc(JavaThread* thread) { |
549 address Runtime1::exception_handler_for_pc(JavaThread* thread) { |
550 oop exception = thread->exception_oop(); |
550 oop exception = thread->exception_oop(); |
551 address pc = thread->exception_pc(); |
551 address pc = thread->exception_pc(); |
552 // Still in Java mode |
552 // Still in Java mode |
553 debug_only(ResetNoHandleMark rnhm); |
553 DEBUG_ONLY(ResetNoHandleMark rnhm); |
554 nmethod* nm = NULL; |
554 nmethod* nm = NULL; |
555 address continuation = NULL; |
555 address continuation = NULL; |
556 { |
556 { |
557 // Enter VM mode by calling the helper |
557 // Enter VM mode by calling the helper |
558 |
|
559 ResetNoHandleMark rnhm; |
558 ResetNoHandleMark rnhm; |
560 continuation = exception_handler_for_pc_helper(thread, exception, pc, nm); |
559 continuation = exception_handler_for_pc_helper(thread, exception, pc, nm); |
561 } |
560 } |
562 // Back in JAVA, use no oops DON'T safepoint |
561 // Back in JAVA, use no oops DON'T safepoint |
563 |
562 |
564 // Now check to see if the nmethod we were called from is now deoptimized. |
563 // Now check to see if the nmethod we were called from is now deoptimized. |
565 // If so we must return to the deopt blob and deoptimize the nmethod |
564 // If so we must return to the deopt blob and deoptimize the nmethod |
566 |
|
567 if (nm != NULL && caller_is_deopted()) { |
565 if (nm != NULL && caller_is_deopted()) { |
568 continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); |
566 continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); |
569 } |
567 } |
570 |
568 |
|
569 assert(continuation != NULL, "no handler found"); |
571 return continuation; |
570 return continuation; |
572 } |
571 } |
573 |
572 |
574 |
573 |
575 JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index)) |
574 JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index)) |