hotspot/src/share/vm/jvmci/jvmciRuntime.cpp
changeset 38133 78b95467b9f1
parent 37267 ad8c0e8de29f
child 38229 7d3bad8f8ec8
equal deleted inserted replaced
38132:ba888a4f352a 38133:78b95467b9f1
   218 // control the area where we can allow a safepoint. After we exit the safepoint area we can
   218 // control the area where we can allow a safepoint. After we exit the safepoint area we can
   219 // check to see if the handler we are going to return is now in a nmethod that has
   219 // check to see if the handler we are going to return is now in a nmethod that has
   220 // been deoptimized. If that is the case we return the deopt blob
   220 // been deoptimized. If that is the case we return the deopt blob
   221 // unpack_with_exception entry instead. This makes life for the exception blob easier
   221 // unpack_with_exception entry instead. This makes life for the exception blob easier
   222 // because making that same check and diverting is painful from assembly language.
   222 // because making that same check and diverting is painful from assembly language.
   223 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
   223 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, CompiledMethod*& cm))
   224   // Reset method handle flag.
   224   // Reset method handle flag.
   225   thread->set_is_method_handle_return(false);
   225   thread->set_is_method_handle_return(false);
   226 
   226 
   227   Handle exception(thread, ex);
   227   Handle exception(thread, ex);
   228   nm = CodeCache::find_nmethod(pc);
   228   cm = CodeCache::find_compiled(pc);
   229   assert(nm != NULL, "this is not a compiled method");
   229   assert(cm != NULL, "this is not a compiled method");
   230   // Adjust the pc as needed/
   230   // Adjust the pc as needed/
   231   if (nm->is_deopt_pc(pc)) {
   231   if (cm->is_deopt_pc(pc)) {
   232     RegisterMap map(thread, false);
   232     RegisterMap map(thread, false);
   233     frame exception_frame = thread->last_frame().sender(&map);
   233     frame exception_frame = thread->last_frame().sender(&map);
   234     // if the frame isn't deopted then pc must not correspond to the caller of last_frame
   234     // if the frame isn't deopted then pc must not correspond to the caller of last_frame
   235     assert(exception_frame.is_deoptimized_frame(), "must be deopted");
   235     assert(exception_frame.is_deoptimized_frame(), "must be deopted");
   236     pc = exception_frame.pc();
   236     pc = exception_frame.pc();
   273     return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   273     return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   274   }
   274   }
   275 
   275 
   276   // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
   276   // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
   277   if (guard_pages_enabled) {
   277   if (guard_pages_enabled) {
   278     address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
   278     address fast_continuation = cm->handler_for_exception_and_pc(exception, pc);
   279     if (fast_continuation != NULL) {
   279     if (fast_continuation != NULL) {
   280       // Set flag if return address is a method handle call site.
   280       // Set flag if return address is a method handle call site.
   281       thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
   281       thread->set_is_method_handle_return(cm->is_method_handle_return(pc));
   282       return fast_continuation;
   282       return fast_continuation;
   283     }
   283     }
   284   }
   284   }
   285 
   285 
   286   // If the stack guard pages are enabled, check whether there is a handler in
   286   // If the stack guard pages are enabled, check whether there is a handler in
   297     if (log_is_enabled(Info, exceptions)) {
   297     if (log_is_enabled(Info, exceptions)) {
   298       ResourceMark rm;
   298       ResourceMark rm;
   299       stringStream tempst;
   299       stringStream tempst;
   300       tempst.print("compiled method <%s>\n"
   300       tempst.print("compiled method <%s>\n"
   301                    " at PC" INTPTR_FORMAT " for thread " INTPTR_FORMAT,
   301                    " at PC" INTPTR_FORMAT " for thread " INTPTR_FORMAT,
   302                    nm->method()->print_value_string(), p2i(pc), p2i(thread));
   302                    cm->method()->print_value_string(), p2i(pc), p2i(thread));
   303       Exceptions::log_exception(exception, tempst);
   303       Exceptions::log_exception(exception, tempst);
   304     }
   304     }
   305     // for AbortVMOnException flag
   305     // for AbortVMOnException flag
   306     NOT_PRODUCT(Exceptions::debug_check_abort(exception));
   306     NOT_PRODUCT(Exceptions::debug_check_abort(exception));
   307 
   307 
   309     // exception handler can cause class loading, which might throw an
   309     // exception handler can cause class loading, which might throw an
   310     // exception and those fields are expected to be clear during
   310     // exception and those fields are expected to be clear during
   311     // normal bytecode execution.
   311     // normal bytecode execution.
   312     thread->clear_exception_oop_and_pc();
   312     thread->clear_exception_oop_and_pc();
   313 
   313 
   314     continuation = SharedRuntime::compute_compiled_exc_handler(nm, pc, exception, false, false);
   314     continuation = SharedRuntime::compute_compiled_exc_handler(cm, pc, exception, false, false);
   315     // If an exception was thrown during exception dispatch, the exception oop may have changed
   315     // If an exception was thrown during exception dispatch, the exception oop may have changed
   316     thread->set_exception_oop(exception());
   316     thread->set_exception_oop(exception());
   317     thread->set_exception_pc(pc);
   317     thread->set_exception_pc(pc);
   318 
   318 
   319     // the exception cache is used only by non-implicit exceptions
   319     // the exception cache is used only by non-implicit exceptions
   320     if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
   320     if (continuation != NULL && !SharedRuntime::deopt_blob()->contains(continuation)) {
   321       nm->add_handler_for_exception_and_pc(exception, pc, continuation);
   321       cm->add_handler_for_exception_and_pc(exception, pc, continuation);
   322     }
   322     }
   323   }
   323   }
   324 
   324 
   325   // Set flag if return address is a method handle call site.
   325   // Set flag if return address is a method handle call site.
   326   thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
   326   thread->set_is_method_handle_return(cm->is_method_handle_return(pc));
   327 
   327 
   328   if (log_is_enabled(Info, exceptions)) {
   328   if (log_is_enabled(Info, exceptions)) {
   329     ResourceMark rm;
   329     ResourceMark rm;
   330     log_info(exceptions)("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT
   330     log_info(exceptions)("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT
   331                          " for exception thrown at PC " PTR_FORMAT,
   331                          " for exception thrown at PC " PTR_FORMAT,
   343 address JVMCIRuntime::exception_handler_for_pc(JavaThread* thread) {
   343 address JVMCIRuntime::exception_handler_for_pc(JavaThread* thread) {
   344   oop exception = thread->exception_oop();
   344   oop exception = thread->exception_oop();
   345   address pc = thread->exception_pc();
   345   address pc = thread->exception_pc();
   346   // Still in Java mode
   346   // Still in Java mode
   347   DEBUG_ONLY(ResetNoHandleMark rnhm);
   347   DEBUG_ONLY(ResetNoHandleMark rnhm);
   348   nmethod* nm = NULL;
   348   CompiledMethod* cm = NULL;
   349   address continuation = NULL;
   349   address continuation = NULL;
   350   {
   350   {
   351     // Enter VM mode by calling the helper
   351     // Enter VM mode by calling the helper
   352     ResetNoHandleMark rnhm;
   352     ResetNoHandleMark rnhm;
   353     continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
   353     continuation = exception_handler_for_pc_helper(thread, exception, pc, cm);
   354   }
   354   }
   355   // Back in JAVA, use no oops DON'T safepoint
   355   // Back in JAVA, use no oops DON'T safepoint
   356 
   356 
   357   // Now check to see if the compiled method we were called from is now deoptimized.
   357   // Now check to see if the compiled method we were called from is now deoptimized.
   358   // If so we must return to the deopt blob and deoptimize the nmethod
   358   // If so we must return to the deopt blob and deoptimize the nmethod
   359   if (nm != NULL && caller_is_deopted()) {
   359   if (cm != NULL && caller_is_deopted()) {
   360     continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   360     continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
   361   }
   361   }
   362 
   362 
   363   assert(continuation != NULL, "no handler found");
   363   assert(continuation != NULL, "no handler found");
   364   return continuation;
   364   return continuation;