equal
deleted
inserted
replaced
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; |
470 } |
478 } |
471 } |
479 } |