hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
changeset 35077 8b86440d3bf1
parent 35071 a0910b1d3e0d
child 35201 996db89f378e
equal deleted inserted replaced
35076:14858721b3b3 35077:8b86440d3bf1
   119 
   119 
   120 // Validate a ucontext retrieved from walking a uc_link of a ucontext.
   120 // Validate a ucontext retrieved from walking a uc_link of a ucontext.
   121 // There are issues with libthread giving out uc_links for different threads
   121 // There are issues with libthread giving out uc_links for different threads
   122 // on the same uc_link chain and bad or circular links.
   122 // on the same uc_link chain and bad or circular links.
   123 //
   123 //
   124 bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) {
   124 bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect) {
   125   if (valid >= suspect ||
   125   if (valid >= suspect ||
   126       valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
   126       valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
   127       valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
   127       valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
   128       valid->uc_stack.ss_size  != suspect->uc_stack.ss_size) {
   128       valid->uc_stack.ss_size  != suspect->uc_stack.ss_size) {
   129     DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");)
   129     DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");)
   146 }
   146 }
   147 
   147 
   148 // We will only follow one level of uc_link since there are libthread
   148 // We will only follow one level of uc_link since there are libthread
   149 // issues with ucontext linking and it is better to be safe and just
   149 // issues with ucontext linking and it is better to be safe and just
   150 // let caller retry later.
   150 // let caller retry later.
   151 ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
   151 const ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
   152   ucontext_t *uc) {
   152   const ucontext_t *uc) {
   153 
   153 
   154   ucontext_t *retuc = NULL;
   154   const ucontext_t *retuc = NULL;
   155 
   155 
   156   // Sometimes the topmost register windows are not properly flushed.
   156   // Sometimes the topmost register windows are not properly flushed.
   157   // i.e., if the kernel would have needed to take a page fault
   157   // i.e., if the kernel would have needed to take a page fault
   158   if (uc != NULL && uc->uc_mcontext.gwins != NULL) {
   158   if (uc != NULL && uc->uc_mcontext.gwins != NULL) {
   159     ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
   159     ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
   177   }
   177   }
   178   return retuc;
   178   return retuc;
   179 }
   179 }
   180 
   180 
   181 // Assumes ucontext is valid
   181 // Assumes ucontext is valid
   182 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
   182 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(const ucontext_t *uc) {
   183   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
   183   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
   184   // set npc to zero to avoid using it for safepoint, good for profiling only
   184   // set npc to zero to avoid using it for safepoint, good for profiling only
   185   return ExtendedPC(pc);
   185   return ExtendedPC(pc);
   186 }
   186 }
   187 
   187 
   189   uc->uc_mcontext.gregs [REG_PC]  = (greg_t) pc;
   189   uc->uc_mcontext.gregs [REG_PC]  = (greg_t) pc;
   190   uc->uc_mcontext.gregs [REG_nPC] = (greg_t) (pc + 4);
   190   uc->uc_mcontext.gregs [REG_nPC] = (greg_t) (pc + 4);
   191 }
   191 }
   192 
   192 
   193 // Assumes ucontext is valid
   193 // Assumes ucontext is valid
   194 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
   194 intptr_t* os::Solaris::ucontext_get_sp(const ucontext_t *uc) {
   195   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
   195   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
   196 }
   196 }
   197 
   197 
   198 // Solaris X86 only
   198 // Solaris X86 only
   199 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
   199 intptr_t* os::Solaris::ucontext_get_fp(const ucontext_t *uc) {
   200   ShouldNotReachHere();
   200   ShouldNotReachHere();
   201   return NULL;
   201   return NULL;
   202 }
   202 }
   203 
   203 
   204 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
   204 address os::Solaris::ucontext_get_pc(const ucontext_t *uc) {
   205   return (address) uc->uc_mcontext.gregs[REG_PC];
   205   return (address) uc->uc_mcontext.gregs[REG_PC];
   206 }
   206 }
   207 
   207 
   208 
   208 
   209 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
   209 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
   213 //
   213 //
   214 // The difference between this and os::fetch_frame_from_context() is that
   214 // The difference between this and os::fetch_frame_from_context() is that
   215 // here we try to skip nested signal frames.
   215 // here we try to skip nested signal frames.
   216 // This method is also used for stack overflow signal handling.
   216 // This method is also used for stack overflow signal handling.
   217 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
   217 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
   218   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
   218   const ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
   219 
   219 
   220   assert(thread != NULL, "just checking");
   220   assert(thread != NULL, "just checking");
   221   assert(ret_sp != NULL, "just checking");
   221   assert(ret_sp != NULL, "just checking");
   222   assert(ret_fp == NULL, "just checking");
   222   assert(ret_fp == NULL, "just checking");
   223 
   223 
   224   ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
   224   const ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
   225 
   225 
   226   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
   226   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
   227 }
   227 }
   228 
   228 
   229 
   229 
   230 // ret_fp parameter is only used by Solaris X86.
   230 // ret_fp parameter is only used by Solaris X86.
   231 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
   231 ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
   232                     intptr_t** ret_sp, intptr_t** ret_fp) {
   232                     intptr_t** ret_sp, intptr_t** ret_fp) {
   233 
   233 
   234   ExtendedPC  epc;
   234   ExtendedPC  epc;
   235   ucontext_t *uc = (ucontext_t*)ucVoid;
   235   const ucontext_t *uc = (const ucontext_t*)ucVoid;
   236 
   236 
   237   if (uc != NULL) {
   237   if (uc != NULL) {
   238     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   238     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
   239     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
   239     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
   240   } else {
   240   } else {
   244   }
   244   }
   245 
   245 
   246   return epc;
   246   return epc;
   247 }
   247 }
   248 
   248 
   249 frame os::fetch_frame_from_context(void* ucVoid) {
   249 frame os::fetch_frame_from_context(const void* ucVoid) {
   250   intptr_t* sp;
   250   intptr_t* sp;
   251   intptr_t* fp;
   251   intptr_t* fp;
   252   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   252   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   253   return frame(sp, frame::unpatchable, epc.pc());
   253   return frame(sp, frame::unpatchable, epc.pc());
   254 }
   254 }
   603 
   603 
   604   ShouldNotReachHere();
   604   ShouldNotReachHere();
   605   return false;
   605   return false;
   606 }
   606 }
   607 
   607 
   608 void os::print_context(outputStream *st, void *context) {
   608 void os::print_context(outputStream *st, const void *context) {
   609   if (context == NULL) return;
   609   if (context == NULL) return;
   610 
   610 
   611   ucontext_t *uc = (ucontext_t*)context;
   611   const ucontext_t *uc = (const ucontext_t*)context;
   612   st->print_cr("Registers:");
   612   st->print_cr("Registers:");
   613 
   613 
   614   st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
   614   st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
   615                " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
   615                " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
   616             uc->uc_mcontext.gregs[REG_G1],
   616             uc->uc_mcontext.gregs[REG_G1],
   680   address pc = epc.pc();
   680   address pc = epc.pc();
   681   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
   681   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
   682   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
   682   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
   683 }
   683 }
   684 
   684 
   685 void os::print_register_info(outputStream *st, void *context) {
   685 void os::print_register_info(outputStream *st, const void *context) {
   686   if (context == NULL) return;
   686   if (context == NULL) return;
   687 
   687 
   688   ucontext_t *uc = (ucontext_t*)context;
   688   const ucontext_t *uc = (const ucontext_t*)context;
   689   intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
   689   intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
   690 
   690 
   691   st->print_cr("Register to memory mapping:");
   691   st->print_cr("Register to memory mapping:");
   692   st->cr();
   692   st->cr();
   693 
   693