src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp

Print this page
rev 4773 : 8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
   1 /*
   2  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 177 }
 178 
 179 // Assumes ucontext is valid
 180 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
 181   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
 182   // set npc to zero to avoid using it for safepoint, good for profiling only
 183   return ExtendedPC(pc);
 184 }
 185 
 186 // Assumes ucontext is valid
 187 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
 188   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
 189 }
 190 
 191 // Solaris X86 only
 192 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
 193   ShouldNotReachHere();
 194   return NULL;
 195 }
 196 





 197 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 198 // is currently interrupted by SIGPROF.
 199 //
 200 // ret_fp parameter is only used by Solaris X86.
 201 //
 202 // The difference between this and os::fetch_frame_from_context() is that
 203 // here we try to skip nested signal frames.
 204 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
 205   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 206 
 207   assert(thread != NULL, "just checking");
 208   assert(ret_sp != NULL, "just checking");
 209   assert(ret_fp == NULL, "just checking");
 210 
 211   ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
 212 
 213   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
 214 }
 215 
 216 


 248 // point into the calling threads stack, and be no lower than the current stack
 249 // pointer.
 250 address os::current_stack_pointer() {
 251   volatile int dummy;
 252   address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
 253   return sp;
 254 }
 255 
 256 frame os::current_frame() {
 257   intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
 258   frame myframe(sp, frame::unpatchable,
 259                 CAST_FROM_FN_PTR(address, os::current_frame));
 260   if (os::is_first_C_frame(&myframe)) {
 261     // stack is not walkable
 262     return frame(NULL, NULL, NULL);
 263   } else {
 264     return os::get_sender_for_C_frame(&myframe);
 265   }
 266 }
 267 
 268 
 269 void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
 270   Thread*     thread = args->thread();
 271   ucontext_t* uc     = args->ucontext();
 272   intptr_t* sp;
 273 
 274   assert(ProfileVM && thread->is_VM_thread(), "just checking");
 275 
 276   // Skip the mcontext corruption verification. If if occasionally
 277   // things get corrupt, it is ok for profiling - we will just get an unresolved
 278   // function name
 279   ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
 280   _addr = new_addr;
 281 }
 282 
 283 
 284 static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
 285   char lwpstatusfile[PROCFILE_LENGTH];
 286   int lwpfd, err;
 287 
 288   if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs))
 289     return (err);
 290   if (*flags == TRS_LWPID) {
 291     sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(),
 292             *lwp);
 293     if ((lwpfd = ::open(lwpstatusfile, O_RDONLY)) < 0) {
 294       perror("thr_mutator_status: open lwpstatus");
 295       return (EINVAL);
 296     }
 297     if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) !=
 298         sizeof (lwpstatus_t)) {
 299       perror("thr_mutator_status: read lwpstatus");
 300       (void) ::close(lwpfd);
 301       return (EINVAL);
 302     }
 303     (void) ::close(lwpfd);


 341       return true;
 342     }
 343   }
 344 
 345   JavaThread* thread = NULL;
 346   VMThread* vmthread = NULL;
 347   if (os::Solaris::signal_handlers_are_installed) {
 348     if (t != NULL ){
 349       if(t->is_Java_thread()) {
 350         thread = (JavaThread*)t;
 351       }
 352       else if(t->is_VM_thread()){
 353         vmthread = (VMThread *)t;
 354       }
 355     }
 356   }
 357 
 358   guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
 359 
 360   if (sig == os::Solaris::SIGasync()) {
 361     if (thread) {
 362       OSThread::InterruptArguments args(thread, uc);
 363       thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
 364       return true;
 365     } else if (vmthread) {
 366       OSThread::InterruptArguments args(vmthread, uc);
 367       vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
 368       return true;
 369     } else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
 370       return true;
 371     } else {
 372       // If os::Solaris::SIGasync not chained, and this is a non-vm and
 373       // non-java thread
 374       return true;
 375     }
 376   }
 377 
 378   if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
 379     // can't decode this kind of signal
 380     info = NULL;
 381   } else {
 382     assert(sig == info->si_signo, "bad siginfo");
 383   }
 384 
 385   // decide if this trap can be handled by a stub
 386   address stub = NULL;
 387 


   1 /*
   2  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 177 }
 178 
 179 // Assumes ucontext is valid
 180 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
 181   address pc = (address)uc->uc_mcontext.gregs[REG_PC];
 182   // set npc to zero to avoid using it for safepoint, good for profiling only
 183   return ExtendedPC(pc);
 184 }
 185 
 186 // Assumes ucontext is valid
 187 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
 188   return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
 189 }
 190 
 191 // Solaris X86 only
 192 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
 193   ShouldNotReachHere();
 194   return NULL;
 195 }
 196 
 197 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
 198   return (address) uc->uc_mcontext.gregs[REG_PC];
 199 }
 200 
 201 
 202 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
 203 // is currently interrupted by SIGPROF.
 204 //
 205 // ret_fp parameter is only used by Solaris X86.
 206 //
 207 // The difference between this and os::fetch_frame_from_context() is that
 208 // here we try to skip nested signal frames.
 209 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
 210   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
 211 
 212   assert(thread != NULL, "just checking");
 213   assert(ret_sp != NULL, "just checking");
 214   assert(ret_fp == NULL, "just checking");
 215 
 216   ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
 217 
 218   return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
 219 }
 220 
 221 


 253 // point into the calling threads stack, and be no lower than the current stack
 254 // pointer.
 255 address os::current_stack_pointer() {
 256   volatile int dummy;
 257   address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
 258   return sp;
 259 }
 260 
 261 frame os::current_frame() {
 262   intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
 263   frame myframe(sp, frame::unpatchable,
 264                 CAST_FROM_FN_PTR(address, os::current_frame));
 265   if (os::is_first_C_frame(&myframe)) {
 266     // stack is not walkable
 267     return frame(NULL, NULL, NULL);
 268   } else {
 269     return os::get_sender_for_C_frame(&myframe);
 270   }
 271 }
 272 
















 273 static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
 274   char lwpstatusfile[PROCFILE_LENGTH];
 275   int lwpfd, err;
 276 
 277   if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs))
 278     return (err);
 279   if (*flags == TRS_LWPID) {
 280     sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(),
 281             *lwp);
 282     if ((lwpfd = ::open(lwpstatusfile, O_RDONLY)) < 0) {
 283       perror("thr_mutator_status: open lwpstatus");
 284       return (EINVAL);
 285     }
 286     if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) !=
 287         sizeof (lwpstatus_t)) {
 288       perror("thr_mutator_status: read lwpstatus");
 289       (void) ::close(lwpfd);
 290       return (EINVAL);
 291     }
 292     (void) ::close(lwpfd);


 330       return true;
 331     }
 332   }
 333 
 334   JavaThread* thread = NULL;
 335   VMThread* vmthread = NULL;
 336   if (os::Solaris::signal_handlers_are_installed) {
 337     if (t != NULL ){
 338       if(t->is_Java_thread()) {
 339         thread = (JavaThread*)t;
 340       }
 341       else if(t->is_VM_thread()){
 342         vmthread = (VMThread *)t;
 343       }
 344     }
 345   }
 346 
 347   guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
 348 
 349   if (sig == os::Solaris::SIGasync()) {
 350     if (thread || vmthread) {
 351       OSThread::SR_handler(t, uc);





 352       return true;
 353     } else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
 354       return true;
 355     } else {
 356       // If os::Solaris::SIGasync not chained, and this is a non-vm and
 357       // non-java thread
 358       return true;
 359     }
 360   }
 361 
 362   if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
 363     // can't decode this kind of signal
 364     info = NULL;
 365   } else {
 366     assert(sig == info->si_signo, "bad siginfo");
 367   }
 368 
 369   // decide if this trap can be handled by a stub
 370   address stub = NULL;
 371