430 #endif |
430 #endif |
431 |
431 |
432 int offset = code_offset(); |
432 int offset = code_offset(); |
433 |
433 |
434 // Fetch the exception from TLS and clear out exception related thread state |
434 // Fetch the exception from TLS and clear out exception related thread state |
435 __ get_thread(rsi); |
435 Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread); |
436 __ movptr(rax, Address(rsi, JavaThread::exception_oop_offset())); |
436 NOT_LP64(__ get_thread(rsi)); |
437 __ movptr(Address(rsi, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD); |
437 __ movptr(rax, Address(thread, JavaThread::exception_oop_offset())); |
438 __ movptr(Address(rsi, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD); |
438 __ movptr(Address(thread, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD); |
|
439 __ movptr(Address(thread, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD); |
439 |
440 |
440 __ bind(_unwind_handler_entry); |
441 __ bind(_unwind_handler_entry); |
441 __ verify_not_null_oop(rax); |
442 __ verify_not_null_oop(rax); |
442 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
443 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
443 __ mov(rsi, rax); // Preserve the exception |
444 __ mov(rbx, rax); // Preserve the exception (rbx is always callee-saved) |
444 } |
445 } |
445 |
446 |
446 // Preform needed unlocking |
447 // Preform needed unlocking |
447 MonitorExitStub* stub = NULL; |
448 MonitorExitStub* stub = NULL; |
448 if (method()->is_synchronized()) { |
449 if (method()->is_synchronized()) { |
449 monitor_address(0, FrameMap::rax_opr); |
450 monitor_address(0, FrameMap::rax_opr); |
450 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); |
451 stub = new MonitorExitStub(FrameMap::rax_opr, true, 0); |
451 __ unlock_object(rdi, rbx, rax, *stub->entry()); |
452 __ unlock_object(rdi, rsi, rax, *stub->entry()); |
452 __ bind(*stub->continuation()); |
453 __ bind(*stub->continuation()); |
453 } |
454 } |
454 |
455 |
455 if (compilation()->env()->dtrace_method_probes()) { |
456 if (compilation()->env()->dtrace_method_probes()) { |
|
457 #ifdef _LP64 |
|
458 __ mov(rdi, r15_thread); |
|
459 __ mov_metadata(rsi, method()->constant_encoding()); |
|
460 #else |
456 __ get_thread(rax); |
461 __ get_thread(rax); |
457 __ movptr(Address(rsp, 0), rax); |
462 __ movptr(Address(rsp, 0), rax); |
458 __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding()); |
463 __ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding()); |
|
464 #endif |
459 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); |
465 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit))); |
460 } |
466 } |
461 |
467 |
462 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
468 if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) { |
463 __ mov(rax, rsi); // Restore the exception |
469 __ mov(rax, rbx); // Restore the exception |
464 } |
470 } |
465 |
471 |
466 // remove the activation and dispatch to the unwind handler |
472 // remove the activation and dispatch to the unwind handler |
467 __ remove_frame(initial_frame_size_in_bytes()); |
473 __ remove_frame(initial_frame_size_in_bytes()); |
468 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); |
474 __ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id))); |