269 } |
269 } |
270 } |
270 } |
271 |
271 |
272 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT |
272 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT |
273 if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { |
273 if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { |
274 handle_assert_poison_fault(ucVoid, info->si_addr); |
274 if (handle_assert_poison_fault(ucVoid, info->si_addr)) { |
275 return 1; |
275 return 1; |
|
276 } |
276 } |
277 } |
277 #endif |
278 #endif |
278 |
279 |
279 JavaThread* thread = NULL; |
280 JavaThread* thread = NULL; |
280 VMThread* vmthread = NULL; |
281 VMThread* vmthread = NULL; |
467 else if (sig == SIGBUS) { |
468 else if (sig == SIGBUS) { |
468 // BugId 4454115: A read from a MappedByteBuffer can fault here if the |
469 // BugId 4454115: A read from a MappedByteBuffer can fault here if the |
469 // underlying file has been truncated. Do not crash the VM in such a case. |
470 // underlying file has been truncated. Do not crash the VM in such a case. |
470 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
471 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
471 CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; |
472 CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL; |
472 if (nm != NULL && nm->has_unsafe_access()) { |
473 bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc)); |
|
474 if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) { |
473 address next_pc = pc + 4; |
475 address next_pc = pc + 4; |
|
476 if (is_unsafe_arraycopy) { |
|
477 next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); |
|
478 } |
474 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
479 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
475 os::Linux::ucontext_set_pc(uc, next_pc); |
480 os::Linux::ucontext_set_pc(uc, next_pc); |
476 return true; |
481 return true; |
477 } |
482 } |
478 } |
483 } |
483 // SIGILL must be caused by VM_Version::determine_features(). |
488 // SIGILL must be caused by VM_Version::determine_features(). |
484 *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL, |
489 *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL, |
485 // flushing of icache is not necessary. |
490 // flushing of icache is not necessary. |
486 stub = pc + 4; // continue with next instruction. |
491 stub = pc + 4; // continue with next instruction. |
487 } |
492 } |
488 else if (thread->thread_state() == _thread_in_vm && |
493 else if ((thread->thread_state() == _thread_in_vm || |
|
494 thread->thread_state() == _thread_in_native) && |
489 sig == SIGBUS && thread->doing_unsafe_access()) { |
495 sig == SIGBUS && thread->doing_unsafe_access()) { |
490 address next_pc = pc + 4; |
496 address next_pc = pc + 4; |
|
497 if (UnsafeCopyMemory::contains_pc(pc)) { |
|
498 next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); |
|
499 } |
491 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
500 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
492 os::Linux::ucontext_set_pc(uc, pc + 4); |
501 os::Linux::ucontext_set_pc(uc, next_pc); |
493 return true; |
502 return true; |
|
503 } |
|
504 } |
|
505 |
|
506 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in |
|
507 // and the heap gets shrunk before the field access. |
|
508 if ((sig == SIGSEGV) || (sig == SIGBUS)) { |
|
509 address addr = JNI_FastGetField::find_slowcase_pc(pc); |
|
510 if (addr != (address)-1) { |
|
511 stub = addr; |
494 } |
512 } |
495 } |
513 } |
496 } |
514 } |
497 |
515 |
498 if (stub != NULL) { |
516 if (stub != NULL) { |