src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54717 b39365cebb73
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
   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) {