src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp

Print this page




 180 
 181 // Assumes ucontext is valid
 182 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
 183   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
 184 }
 185 
 186 // Assumes ucontext is valid
 187 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
 188   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
 189 }
 190 
 191 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
 192   return (address) uc->uc_mcontext.gregs[REG_PC];
 193 }
 194 
 195 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 196 // is currently interrupted by SIGPROF.
 197 //
 198 // The difference between this and os::fetch_frame_from_context() is that
 199 // here we try to skip nested signal frames.

 200 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
 201   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 202 
 203   assert(thread != NULL, "just checking");
 204   assert(ret_sp != NULL, "just checking");
 205   assert(ret_fp != NULL, "just checking");
 206 
 207   ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
 208   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
 209 }
 210 
 211 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
 212                     intptr_t** ret_sp, intptr_t** ret_fp) {
 213 
 214   ExtendedPC  epc;
 215   ucontext_t *uc = (ucontext_t*)ucVoid;
 216 
 217   if (uc != NULL) {
 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     }




 180 
 181 // Assumes ucontext is valid
 182 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
 183   return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
 184 }
 185 
 186 // Assumes ucontext is valid
 187 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
 188   return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
 189 }
 190 
 191 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
 192   return (address) uc->uc_mcontext.gregs[REG_PC];
 193 }
 194 
 195 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 196 // is currently interrupted by SIGPROF.
 197 //
 198 // The difference between this and os::fetch_frame_from_context() is that
 199 // here we try to skip nested signal frames.
 200 // This method is also used for stack overflow signal handling.
 201 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
 202   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 203 
 204   assert(thread != NULL, "just checking");
 205   assert(ret_sp != NULL, "just checking");
 206   assert(ret_fp != NULL, "just checking");
 207 
 208   ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
 209   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
 210 }
 211 
 212 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
 213                     intptr_t** ret_sp, intptr_t** ret_fp) {
 214 
 215   ExtendedPC  epc;
 216   ucontext_t *uc = (ucontext_t*)ucVoid;
 217 
 218   if (uc != NULL) {
 219     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
 220     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
 221     if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
 222   } else {
 223     // construct empty ExtendedPC for return value checking
 224     epc = ExtendedPC(NULL);
 225     if (ret_sp) *ret_sp = (intptr_t *)NULL;
 226     if (ret_fp) *ret_fp = (intptr_t *)NULL;
 227   }
 228 
 229   return epc;
 230 }
 231 
 232 frame os::fetch_frame_from_context(void* ucVoid) {
 233   intptr_t* sp;
 234   intptr_t* fp;
 235   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
 236   return frame(sp, fp, epc.pc());
 237 }
 238 
 239 frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
 240   intptr_t* sp;
 241   intptr_t* fp;
 242   ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
 243   return frame(sp, fp, epc.pc());
 244 }
 245 
 246 bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
 247  address pc = (address) os::Solaris::ucontext_get_pc(uc);
 248   if (Interpreter::contains(pc)) {
 249     // interpreter performs stack banging after the fixed frame header has
 250     // been generated while the compilers perform it before. To maintain
 251     // semantic consistency between interpreted and compiled frames, the
 252     // method returns the Java sender of the current frame.
 253     *fr = os::fetch_frame_from_ucontext(thread, uc);
 254     if (!fr->is_first_java_frame()) {
 255         assert(fr->safe_for_sender(thread), "Safety check");
 256       *fr = fr->java_sender();
 257     }
 258   } else {
 259     // more complex code with compiled code
 260     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
 261     CodeBlob* cb = CodeCache::find_blob(pc);
 262     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
 263       // Not sure where the pc points to, fallback to default 
 264       // stack overflow handling
 265       return false;
 266     } else {
 267       // in compiled code, the stack banging is performed just after the return pc
 268       // has been pushed on the stack
 269       intptr_t* fp = os::Solaris::ucontext_get_fp(uc);
 270       intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
 271       *fr = frame(sp + 1, fp, (address)*sp);
 272       if (!fr->is_java_frame()) {
 273         assert(fr->safe_for_sender(thread), "Safety check");
 274         *fr = fr->java_sender();
 275       }
 276     }
 277   }
 278   assert(fr->is_java_frame(), "Safety check");
 279   return true;
 280 }
 281 
 282 frame os::get_sender_for_C_frame(frame* fr) {
 283   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 284 }
 285 
 286 extern "C" intptr_t *_get_current_sp();  // in .il file
 287 
 288 address os::current_stack_pointer() {
 289   return (address)_get_current_sp();
 290 }
 291 
 292 extern "C" intptr_t *_get_current_fp();  // in .il file
 293 
 294 frame os::current_frame() {
 295   intptr_t* fp = _get_current_fp();  // it's inlined so want current fp
 296   frame myframe((intptr_t*)os::current_stack_pointer(),
 297                 (intptr_t*)fp,
 298                 CAST_FROM_FN_PTR(address, os::current_frame));
 299   if (os::is_first_C_frame(&myframe)) {
 300     // stack is not walkable
 301     frame ret; // This will be a null useless frame


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

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