src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp

Print this page




 218     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
 219     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
 220     if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
 221   } else {
 222     // construct empty ExtendedPC for return value checking
 223     epc = ExtendedPC(NULL);
 224     if (ret_sp) *ret_sp = (intptr_t *)NULL;
 225     if (ret_fp) *ret_fp = (intptr_t *)NULL;
 226   }
 227 
 228   return epc;
 229 }
 230 
 231 frame os::fetch_frame_from_context(void* ucVoid) {
 232   intptr_t* sp;
 233   intptr_t* fp;
 234   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
 235   return frame(sp, fp, epc.pc());
 236 }
 237 











































 238 frame os::get_sender_for_C_frame(frame* fr) {
 239   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 240 }
 241 
 242 extern "C" intptr_t *_get_current_sp();  // in .il file
 243 
 244 address os::current_stack_pointer() {
 245   return (address)_get_current_sp();
 246 }
 247 
 248 extern "C" intptr_t *_get_current_fp();  // in .il file
 249 
 250 frame os::current_frame() {
 251   intptr_t* fp = _get_current_fp();  // it's inlined so want current fp
 252   frame myframe((intptr_t*)os::current_stack_pointer(),
 253                 (intptr_t*)fp,
 254                 CAST_FROM_FN_PTR(address, os::current_frame));
 255   if (os::is_first_C_frame(&myframe)) {
 256     // stack is not walkable
 257     frame ret; // This will be a null useless frame


 406 
 407   // decide if this trap can be handled by a stub
 408   address stub = NULL;
 409 
 410   address pc          = NULL;
 411 
 412   //%note os_trap_1
 413   if (info != NULL && uc != NULL && thread != NULL) {
 414     // factor me: getPCfromContext
 415     pc = (address) uc->uc_mcontext.gregs[REG_PC];
 416 
 417     if (StubRoutines::is_safefetch_fault(pc)) {
 418       os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
 419       return true;
 420     }
 421 
 422     // Handle ALL stack overflow variations here
 423     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
 424       address addr = (address) info->si_addr;
 425       if (thread->in_stack_yellow_zone(addr)) {
 426         thread->disable_stack_yellow_zone();
 427         if (thread->thread_state() == _thread_in_Java) {

















 428           // Throw a stack overflow exception.  Guard pages will be reenabled
 429           // while unwinding the stack.

 430           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 431         } else {
 432           // Thread was in the vm or native code.  Return and try to finish.

 433           return true;
 434         }
 435       } else if (thread->in_stack_red_zone(addr)) {
 436         // Fatal red zone violation.  Disable the guard pages and fall through
 437         // to handle_unexpected_exception way down below.
 438         thread->disable_stack_red_zone();
 439         tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
 440       }
 441     }
 442 
 443     if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) {
 444       // Verify that OS save/restore AVX registers.
 445       stub = VM_Version::cpuinfo_cont_addr();
 446     }
 447 
 448     if (thread->thread_state() == _thread_in_vm) {
 449       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
 450         stub = StubRoutines::handler_for_unsafe_access();
 451       }
 452     }




 218     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
 219     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
 220     if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
 221   } else {
 222     // construct empty ExtendedPC for return value checking
 223     epc = ExtendedPC(NULL);
 224     if (ret_sp) *ret_sp = (intptr_t *)NULL;
 225     if (ret_fp) *ret_fp = (intptr_t *)NULL;
 226   }
 227 
 228   return epc;
 229 }
 230 
 231 frame os::fetch_frame_from_context(void* ucVoid) {
 232   intptr_t* sp;
 233   intptr_t* fp;
 234   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
 235   return frame(sp, fp, epc.pc());
 236 }
 237 
 238 frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
 239   intptr_t* sp;
 240   intptr_t* fp;
 241   ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
 242   return frame(sp, fp, epc.pc());
 243 }
 244 
 245 bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
 246  address pc = (address) os::Solaris::ucontext_get_pc(uc);
 247   if (Interpreter::contains(pc)) {
 248     // interpreter performs stack banging after the fixed frame header has
 249     // been generated while the compilers perform it before. To maintain
 250     // semantic consistency between interpreted and compiled frames, the
 251     // method returns the Java sender of the current frame.
 252     *fr = os::fetch_frame_from_ucontext(thread, uc);
 253     assert(fr->safe_for_sender(thread), "Safety check");
 254     if (!fr->is_first_java_frame()) {
 255       *fr = fr->java_sender();
 256     }
 257   } else {
 258     // more complex code with compiled code
 259     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
 260     CodeBlob* cb = CodeCache::find_blob(pc);
 261     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
 262       // Not sure where the pc points to, fallback to default 
 263       // stack overflow handling
 264       return false;
 265     } else {
 266       // in compiled code, the stack banging is performed just after the return pc
 267       // has been pushed on the stack
 268       intptr_t* fp = os::Solaris::ucontext_get_fp(uc);
 269       intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
 270       *fr = frame(sp + 1, fp, (address)*sp);
 271       if (!fr->is_java_frame()) {
 272         assert(fr->safe_for_sender(thread), "Safety check");
 273          *fr = fr->java_sender();
 274       }
 275     }
 276   }
 277   assert(fr->is_java_frame(), "Safety check");
 278   return true;
 279 }
 280 
 281 frame os::get_sender_for_C_frame(frame* fr) {
 282   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 283 }
 284 
 285 extern "C" intptr_t *_get_current_sp();  // in .il file
 286 
 287 address os::current_stack_pointer() {
 288   return (address)_get_current_sp();
 289 }
 290 
 291 extern "C" intptr_t *_get_current_fp();  // in .il file
 292 
 293 frame os::current_frame() {
 294   intptr_t* fp = _get_current_fp();  // it's inlined so want current fp
 295   frame myframe((intptr_t*)os::current_stack_pointer(),
 296                 (intptr_t*)fp,
 297                 CAST_FROM_FN_PTR(address, os::current_frame));
 298   if (os::is_first_C_frame(&myframe)) {
 299     // stack is not walkable
 300     frame ret; // This will be a null useless frame


 449 
 450   // decide if this trap can be handled by a stub
 451   address stub = NULL;
 452 
 453   address pc          = NULL;
 454 
 455   //%note os_trap_1
 456   if (info != NULL && uc != NULL && thread != NULL) {
 457     // factor me: getPCfromContext
 458     pc = (address) uc->uc_mcontext.gregs[REG_PC];
 459 
 460     if (StubRoutines::is_safefetch_fault(pc)) {
 461       os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
 462       return true;
 463     }
 464 
 465     // Handle ALL stack overflow variations here
 466     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
 467       address addr = (address) info->si_addr;
 468       if (thread->in_stack_yellow_zone(addr)) {

 469         if (thread->thread_state() == _thread_in_Java) {
 470           if (thread->in_stack_reserved_zone(addr)) { 
 471             frame fr;
 472             if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) {
 473               assert(fr.is_java_frame(), "Must be Java frame");
 474               frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
 475               if (activation.sp() != NULL) {
 476                 thread->disable_stack_reserved_zone();
 477                 if (activation.is_interpreted_frame()) {
 478                   thread->set_reserved_stack_activation(
 479                     activation.fp() + frame::interpreter_frame_initial_sp_offset);
 480                 } else {
 481                   thread->set_reserved_stack_activation(activation.unextended_sp());
 482                 }
 483                 return true;
 484               }
 485             }
 486           }
 487           // Throw a stack overflow exception.  Guard pages will be reenabled
 488           // while unwinding the stack.
 489           thread->disable_stack_yellow_zone();
 490           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 491         } else {
 492           // Thread was in the vm or native code.  Return and try to finish.
 493           thread->disable_stack_yellow_zone();
 494           return true;
 495         }
 496       } else if (thread->in_stack_red_zone(addr)) {
 497         // Fatal red zone violation.  Disable the guard pages and fall through
 498         // to handle_unexpected_exception way down below.
 499         thread->disable_stack_red_zone();
 500         tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
 501       }
 502     }
 503 
 504     if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) {
 505       // Verify that OS save/restore AVX registers.
 506       stub = VM_Version::cpuinfo_cont_addr();
 507     }
 508 
 509     if (thread->thread_state() == _thread_in_vm) {
 510       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
 511         stub = StubRoutines::handler_for_unsafe_access();
 512       }
 513     }