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; |