Yesterday's patch was broken in that it trashed LR, which breaks traps from leaf functions. This patch is simpler and returns directly from the fault handler to the instruction after the fault, preserving LR. Andrew. # HG changeset patch # User aph # Date 1389981621 18000 # Fri Jan 17 13:00:21 2014 -0500 # Node ID ebe1eb322f481c62c29ee8a823a6be8a9e7508d8 # Parent e11bc6e52e678ca5cb6c7d7688838221ed55fe92 Implement handler for unsafe access by returning directly just after the faulting insn. diff -r e11bc6e52e67 -r ebe1eb322f48 src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp --- a/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Fri Jan 17 12:58:25 2014 -0500 +++ b/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp Fri Jan 17 13:00:21 2014 -0500 @@ -211,6 +211,23 @@ extern "C" void FetchNResume () ; #endif +// An operation in Unsafe has faulted. We're going to return to the +// instruction after the faulting load or store. We also set +// pending_unsafe_access_error so that at some point in the future our +// user will get a helpful message. +static address handle_unsafe_access(JavaThread* thread, address pc) { + // pc is the instruction which we must emulate + // doing a no-op is fine: return garbage from the load + // therefore, compute npc + address npc = pc + NativeCall::instruction_size; + + // request an async exception + thread->set_pending_unsafe_access_error(); + + // return address of next instruction to execute + return npc; +} + extern "C" JNIEXPORT int JVM_handle_linux_signal(int sig, siginfo_t* info, @@ -363,7 +380,7 @@ CodeBlob* cb = CodeCache::find_blob_unsafe(pc); nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL; if (nm != NULL && nm->has_unsafe_access()) { - stub = StubRoutines::handler_for_unsafe_access(); + stub = handle_unsafe_access(thread, pc); } } else @@ -384,7 +401,7 @@ } else if (thread->thread_state() == _thread_in_vm && sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ thread->doing_unsafe_access()) { - stub = StubRoutines::handler_for_unsafe_access(); + stub = handle_unsafe_access(thread, pc); } // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in