hotspot/src/share/vm/c1/c1_Runtime1.cpp
changeset 8495 a4959965eaa3
parent 8067 f5f4eac4c48f
child 8725 8c1e3dd5fe1b
equal deleted inserted replaced
8494:4258c78226d9 8495:a4959965eaa3
   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))