src/os_cpu/linux_x86/vm/os_linux_x86.cpp

Print this page
rev 4810 : 8016697: PPC64 (part 5): Use stubs to implement safefetch
Summary: Implement Safefetch as stub routines. This reduces compiler and os dependencies.
Reviewed-by: twisti, kvn


 192 frame os::current_frame() {
 193   intptr_t* fp = _get_previous_fp();
 194   frame myframe((intptr_t*)os::current_stack_pointer(),
 195                 (intptr_t*)fp,
 196                 CAST_FROM_FN_PTR(address, os::current_frame));
 197   if (os::is_first_C_frame(&myframe)) {
 198     // stack is not walkable
 199     return frame();
 200   } else {
 201     return os::get_sender_for_C_frame(&myframe);
 202   }
 203 }
 204 
 205 // Utility functions
 206 
 207 // From IA32 System Programming Guide
 208 enum {
 209   trap_page_fault = 0xE
 210 };
 211 
 212 extern "C" void Fetch32PFI () ;
 213 extern "C" void Fetch32Resume () ;
 214 #ifdef AMD64
 215 extern "C" void FetchNPFI () ;
 216 extern "C" void FetchNResume () ;
 217 #endif // AMD64
 218 
 219 extern "C" JNIEXPORT int
 220 JVM_handle_linux_signal(int sig,
 221                         siginfo_t* info,
 222                         void* ucVoid,
 223                         int abort_if_unrecognized) {
 224   ucontext_t* uc = (ucontext_t*) ucVoid;
 225 
 226   Thread* t = ThreadLocalStorage::get_thread_slow();
 227 
 228   SignalHandlerMark shm(t);
 229 
 230   // Note: it's not uncommon that JNI code uses signal/sigset to install
 231   // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
 232   // or have a SIGILL handler when detecting CPU type). When that happens,
 233   // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
 234   // avoid unnecessary crash when libjsig is not preloaded, try handle signals
 235   // that do not require siginfo/ucontext first.
 236 
 237   if (sig == SIGPIPE || sig == SIGXFSZ) {
 238     // allow chained handler to go first


 261     }
 262   }
 263 /*
 264   NOTE: does not seem to work on linux.
 265   if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
 266     // can't decode this kind of signal
 267     info = NULL;
 268   } else {
 269     assert(sig == info->si_signo, "bad siginfo");
 270   }
 271 */
 272   // decide if this trap can be handled by a stub
 273   address stub = NULL;
 274 
 275   address pc          = NULL;
 276 
 277   //%note os_trap_1
 278   if (info != NULL && uc != NULL && thread != NULL) {
 279     pc = (address) os::Linux::ucontext_get_pc(uc);
 280 
 281     if (pc == (address) Fetch32PFI) {
 282        uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
 283        return 1 ;
 284     }
 285 #ifdef AMD64
 286     if (pc == (address) FetchNPFI) {
 287        uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ;
 288        return 1 ;
 289     }
 290 #endif // AMD64
 291 
 292     // Handle ALL stack overflow variations here
 293     if (sig == SIGSEGV) {
 294       address addr = (address) info->si_addr;
 295 
 296       // check if fault address is within thread stack
 297       if (addr < thread->stack_base() &&
 298           addr >= thread->stack_base() - thread->stack_size()) {
 299         // stack overflow
 300         if (thread->in_stack_yellow_zone(addr)) {
 301           thread->disable_stack_yellow_zone();
 302           if (thread->thread_state() == _thread_in_Java) {
 303             // Throw a stack overflow exception.  Guard pages will be reenabled
 304             // while unwinding the stack.
 305             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 306           } else {
 307             // Thread was in the vm or native code.  Return and try to finish.
 308             return 1;
 309           }
 310         } else if (thread->in_stack_red_zone(addr)) {




 192 frame os::current_frame() {
 193   intptr_t* fp = _get_previous_fp();
 194   frame myframe((intptr_t*)os::current_stack_pointer(),
 195                 (intptr_t*)fp,
 196                 CAST_FROM_FN_PTR(address, os::current_frame));
 197   if (os::is_first_C_frame(&myframe)) {
 198     // stack is not walkable
 199     return frame();
 200   } else {
 201     return os::get_sender_for_C_frame(&myframe);
 202   }
 203 }
 204 
 205 // Utility functions
 206 
 207 // From IA32 System Programming Guide
 208 enum {
 209   trap_page_fault = 0xE
 210 };
 211 







 212 extern "C" JNIEXPORT int
 213 JVM_handle_linux_signal(int sig,
 214                         siginfo_t* info,
 215                         void* ucVoid,
 216                         int abort_if_unrecognized) {
 217   ucontext_t* uc = (ucontext_t*) ucVoid;
 218 
 219   Thread* t = ThreadLocalStorage::get_thread_slow();
 220 
 221   SignalHandlerMark shm(t);
 222 
 223   // Note: it's not uncommon that JNI code uses signal/sigset to install
 224   // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
 225   // or have a SIGILL handler when detecting CPU type). When that happens,
 226   // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
 227   // avoid unnecessary crash when libjsig is not preloaded, try handle signals
 228   // that do not require siginfo/ucontext first.
 229 
 230   if (sig == SIGPIPE || sig == SIGXFSZ) {
 231     // allow chained handler to go first


 254     }
 255   }
 256 /*
 257   NOTE: does not seem to work on linux.
 258   if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
 259     // can't decode this kind of signal
 260     info = NULL;
 261   } else {
 262     assert(sig == info->si_signo, "bad siginfo");
 263   }
 264 */
 265   // decide if this trap can be handled by a stub
 266   address stub = NULL;
 267 
 268   address pc          = NULL;
 269 
 270   //%note os_trap_1
 271   if (info != NULL && uc != NULL && thread != NULL) {
 272     pc = (address) os::Linux::ucontext_get_pc(uc);
 273 
 274     if (StubRoutines::is_safefetch_fault(pc)) {
 275       uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
 276       return 1;





 277     }

 278 
 279     // Handle ALL stack overflow variations here
 280     if (sig == SIGSEGV) {
 281       address addr = (address) info->si_addr;
 282 
 283       // check if fault address is within thread stack
 284       if (addr < thread->stack_base() &&
 285           addr >= thread->stack_base() - thread->stack_size()) {
 286         // stack overflow
 287         if (thread->in_stack_yellow_zone(addr)) {
 288           thread->disable_stack_yellow_zone();
 289           if (thread->thread_state() == _thread_in_Java) {
 290             // Throw a stack overflow exception.  Guard pages will be reenabled
 291             // while unwinding the stack.
 292             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 293           } else {
 294             // Thread was in the vm or native code.  Return and try to finish.
 295             return 1;
 296           }
 297         } else if (thread->in_stack_red_zone(addr)) {