1 /* |
1 /* |
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * Copyright (c) 2012, 2018 SAP SE. All rights reserved. |
3 * Copyright (c) 2012, 2018 SAP SE. All rights reserved. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
5 * |
5 * |
6 * This code is free software; you can redistribute it and/or modify it |
6 * This code is free software; you can redistribute it and/or modify it |
7 * under the terms of the GNU General Public License version 2 only, as |
7 * under the terms of the GNU General Public License version 2 only, as |
439 else if (sig == SIGBUS) { |
439 else if (sig == SIGBUS) { |
440 // BugId 4454115: A read from a MappedByteBuffer can fault here if the |
440 // BugId 4454115: A read from a MappedByteBuffer can fault here if the |
441 // underlying file has been truncated. Do not crash the VM in such a case. |
441 // underlying file has been truncated. Do not crash the VM in such a case. |
442 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
442 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); |
443 CompiledMethod* nm = cb->as_compiled_method_or_null(); |
443 CompiledMethod* nm = cb->as_compiled_method_or_null(); |
444 if (nm != NULL && nm->has_unsafe_access()) { |
444 bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc)); |
|
445 if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) { |
445 address next_pc = pc + 4; |
446 address next_pc = pc + 4; |
|
447 if (is_unsafe_arraycopy) { |
|
448 next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); |
|
449 } |
446 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
450 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
447 os::Aix::ucontext_set_pc(uc, next_pc); |
451 os::Aix::ucontext_set_pc(uc, next_pc); |
448 return 1; |
452 return 1; |
449 } |
453 } |
450 } |
454 } |
459 *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL, |
463 *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL, |
460 // flushing of icache is not necessary. |
464 // flushing of icache is not necessary. |
461 stub = pc + 4; // continue with next instruction. |
465 stub = pc + 4; // continue with next instruction. |
462 goto run_stub; |
466 goto run_stub; |
463 } |
467 } |
464 else if (thread->thread_state() == _thread_in_vm && |
468 else if ((thread->thread_state() == _thread_in_vm || |
|
469 thread->thread_state() == _thread_in_native) && |
465 sig == SIGBUS && thread->doing_unsafe_access()) { |
470 sig == SIGBUS && thread->doing_unsafe_access()) { |
466 address next_pc = pc + 4; |
471 address next_pc = pc + 4; |
|
472 if (UnsafeCopyMemory::contains_pc(pc)) { |
|
473 next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); |
|
474 } |
467 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
475 next_pc = SharedRuntime::handle_unsafe_access(thread, next_pc); |
468 os::Aix::ucontext_set_pc(uc, next_pc); |
476 os::Aix::ucontext_set_pc(uc, next_pc); |
469 return 1; |
477 return 1; |
|
478 } |
|
479 } |
|
480 |
|
481 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in |
|
482 // and the heap gets shrunk before the field access. |
|
483 if ((sig == SIGSEGV) || (sig == SIGBUS)) { |
|
484 address addr = JNI_FastGetField::find_slowcase_pc(pc); |
|
485 if (addr != (address)-1) { |
|
486 stub = addr; |
470 } |
487 } |
471 } |
488 } |
472 } |
489 } |
473 |
490 |
474 run_stub: |
491 run_stub: |