os_solaris_sparc.cpp revision 1601:126ea7725993
1/*
2 * Copyright (c) 1999, 2009, 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 *
23 */
24
25// do not include  precompiled  header file
26
27# include <signal.h>        // needed first to avoid name collision for "std" with SC 5.0
28
29# include "incls/_os_solaris_sparc.cpp.incl"
30
31// put OS-includes here
32# include <sys/types.h>
33# include <sys/mman.h>
34# include <pthread.h>
35# include <errno.h>
36# include <dlfcn.h>
37# include <stdio.h>
38# include <unistd.h>
39# include <sys/resource.h>
40# include <thread.h>
41# include <sys/stat.h>
42# include <sys/time.h>
43# include <sys/filio.h>
44# include <sys/utsname.h>
45# include <sys/systeminfo.h>
46# include <sys/socket.h>
47# include <sys/lwp.h>
48# include <pwd.h>
49# include <poll.h>
50# include <sys/lwp.h>
51
52# define _STRUCTURED_PROC 1  //  this gets us the new structured proc interfaces of 5.6 & later
53# include <sys/procfs.h>     //  see comment in <sys/procfs.h>
54
55#define MAX_PATH (2 * K)
56
57// Minimum stack size for the VM.  It's easier to document a constant
58// but it's different for x86 and sparc because the page sizes are different.
59#ifdef _LP64
60size_t os::Solaris::min_stack_allowed = 128*K;
61#else
62size_t os::Solaris::min_stack_allowed = 96*K;
63#endif
64
65int os::Solaris::max_register_window_saves_before_flushing() {
66  // We should detect this at run time. For now, filling
67  // in with a constant.
68  return 8;
69}
70
71static void handle_unflushed_register_windows(gwindows_t *win) {
72  int restore_count = win->wbcnt;
73  int i;
74
75  for(i=0; i<restore_count; i++) {
76    address sp = ((address)win->spbuf[i]) + STACK_BIAS;
77    address reg_win = (address)&win->wbuf[i];
78    memcpy(sp,reg_win,sizeof(struct rwindow));
79  }
80}
81
82char* os::non_memory_address_word() {
83  // Must never look like an address returned by reserve_memory,
84  // even in its subfields (as defined by the CPU immediate fields,
85  // if the CPU splits constants across multiple instructions).
86  // On SPARC, 0 != %hi(any real address), because there is no
87  // allocation in the first 1Kb of the virtual address space.
88  return (char*) 0;
89}
90
91// Validate a ucontext retrieved from walking a uc_link of a ucontext.
92// There are issues with libthread giving out uc_links for different threads
93// on the same uc_link chain and bad or circular links.
94//
95bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) {
96  if (valid >= suspect ||
97      valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
98      valid->uc_stack.ss_sp    != suspect->uc_stack.ss_sp    ||
99      valid->uc_stack.ss_size  != suspect->uc_stack.ss_size) {
100    DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");)
101    return false;
102  }
103
104  if (thread->is_Java_thread()) {
105    if (!valid_stack_address(thread, (address)suspect)) {
106      DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");)
107      return false;
108    }
109    address _sp   = (address)((intptr_t)suspect->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
110    if (!valid_stack_address(thread, _sp) ||
111        !frame::is_valid_stack_pointer(((JavaThread*)thread)->base_of_stack_pointer(), (intptr_t*)_sp)) {
112      DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");)
113      return false;
114    }
115  }
116  return true;
117}
118
119// We will only follow one level of uc_link since there are libthread
120// issues with ucontext linking and it is better to be safe and just
121// let caller retry later.
122ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
123  ucontext_t *uc) {
124
125  ucontext_t *retuc = NULL;
126
127  // Sometimes the topmost register windows are not properly flushed.
128  // i.e., if the kernel would have needed to take a page fault
129  if (uc != NULL && uc->uc_mcontext.gwins != NULL) {
130    ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
131  }
132
133  if (uc != NULL) {
134    if (uc->uc_link == NULL) {
135      // cannot validate without uc_link so accept current ucontext
136      retuc = uc;
137    } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) {
138      // first ucontext is valid so try the next one
139      uc = uc->uc_link;
140      if (uc->uc_link == NULL) {
141        // cannot validate without uc_link so accept current ucontext
142        retuc = uc;
143      } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) {
144        // the ucontext one level down is also valid so return it
145        retuc = uc;
146      }
147    }
148  }
149  return retuc;
150}
151
152// Assumes ucontext is valid
153ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
154  address pc = (address)uc->uc_mcontext.gregs[REG_PC];
155  // set npc to zero to avoid using it for safepoint, good for profiling only
156  return ExtendedPC(pc);
157}
158
159// Assumes ucontext is valid
160intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
161  return (intptr_t*)((intptr_t)uc->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
162}
163
164// Solaris X86 only
165intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
166  ShouldNotReachHere();
167  return NULL;
168}
169
170// For Forte Analyzer AsyncGetCallTrace profiling support - thread
171// is currently interrupted by SIGPROF.
172//
173// ret_fp parameter is only used by Solaris X86.
174//
175// The difference between this and os::fetch_frame_from_context() is that
176// here we try to skip nested signal frames.
177ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
178  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
179
180  assert(thread != NULL, "just checking");
181  assert(ret_sp != NULL, "just checking");
182  assert(ret_fp == NULL, "just checking");
183
184  ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
185
186  return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
187}
188
189
190// ret_fp parameter is only used by Solaris X86.
191ExtendedPC os::fetch_frame_from_context(void* ucVoid,
192                    intptr_t** ret_sp, intptr_t** ret_fp) {
193
194  ExtendedPC  epc;
195  ucontext_t *uc = (ucontext_t*)ucVoid;
196
197  if (uc != NULL) {
198    epc = os::Solaris::ucontext_get_ExtendedPC(uc);
199    if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
200  } else {
201    // construct empty ExtendedPC for return value checking
202    epc = ExtendedPC(NULL);
203    if (ret_sp) *ret_sp = (intptr_t *)NULL;
204  }
205
206  return epc;
207}
208
209frame os::fetch_frame_from_context(void* ucVoid) {
210  intptr_t* sp;
211  intptr_t* fp;
212  ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
213  return frame(sp, frame::unpatchable, epc.pc());
214}
215
216frame os::get_sender_for_C_frame(frame* fr) {
217  return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
218}
219
220frame os::current_frame() {
221  intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
222  frame myframe(sp, frame::unpatchable,
223                CAST_FROM_FN_PTR(address, os::current_frame));
224  if (os::is_first_C_frame(&myframe)) {
225    // stack is not walkable
226    return frame(NULL, NULL, NULL);
227  } else {
228    return os::get_sender_for_C_frame(&myframe);
229  }
230}
231
232
233void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
234  Thread*     thread = args->thread();
235  ucontext_t* uc     = args->ucontext();
236  intptr_t* sp;
237
238  assert(ProfileVM && thread->is_VM_thread(), "just checking");
239
240  // Skip the mcontext corruption verification. If if occasionally
241  // things get corrupt, it is ok for profiling - we will just get an unresolved
242  // function name
243  ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
244  _addr = new_addr;
245}
246
247
248static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
249  char lwpstatusfile[PROCFILE_LENGTH];
250  int lwpfd, err;
251
252  if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs))
253    return (err);
254  if (*flags == TRS_LWPID) {
255    sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(),
256            *lwp);
257    if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) {
258      perror("thr_mutator_status: open lwpstatus");
259      return (EINVAL);
260    }
261    if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) !=
262        sizeof (lwpstatus_t)) {
263      perror("thr_mutator_status: read lwpstatus");
264      (void) close(lwpfd);
265      return (EINVAL);
266    }
267    (void) close(lwpfd);
268  }
269  return (0);
270}
271
272
273bool os::is_allocatable(size_t bytes) {
274#ifdef _LP64
275   return true;
276#else
277   return (bytes <= (size_t)3835*M);
278#endif
279}
280
281extern "C" void Fetch32PFI () ;
282extern "C" void Fetch32Resume () ;
283extern "C" void FetchNPFI () ;
284extern "C" void FetchNResume () ;
285
286extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized);
287
288int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) {
289  ucontext_t* uc = (ucontext_t*) ucVoid;
290
291  Thread* t = ThreadLocalStorage::get_thread_slow();
292
293  SignalHandlerMark shm(t);
294
295  if(sig == SIGPIPE || sig == SIGXFSZ) {
296    if (os::Solaris::chained_handler(sig, info, ucVoid)) {
297      return true;
298    } else {
299      if (PrintMiscellaneous && (WizardMode || Verbose)) {
300        char buf[64];
301        warning("Ignoring %s - see 4229104 or 6499219",
302                os::exception_name(sig, buf, sizeof(buf)));
303
304      }
305      return true;
306    }
307  }
308
309  JavaThread* thread = NULL;
310  VMThread* vmthread = NULL;
311  if (os::Solaris::signal_handlers_are_installed) {
312    if (t != NULL ){
313      if(t->is_Java_thread()) {
314        thread = (JavaThread*)t;
315      }
316      else if(t->is_VM_thread()){
317        vmthread = (VMThread *)t;
318      }
319    }
320  }
321
322  guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
323
324  if (sig == os::Solaris::SIGasync()) {
325    if (thread) {
326      OSThread::InterruptArguments args(thread, uc);
327      thread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
328      return true;
329    } else if (vmthread) {
330      OSThread::InterruptArguments args(vmthread, uc);
331      vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args);
332      return true;
333    } else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
334      return true;
335    } else {
336      // If os::Solaris::SIGasync not chained, and this is a non-vm and
337      // non-java thread
338      return true;
339    }
340  }
341
342  if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
343    // can't decode this kind of signal
344    info = NULL;
345  } else {
346    assert(sig == info->si_signo, "bad siginfo");
347  }
348
349  // decide if this trap can be handled by a stub
350  address stub = NULL;
351
352  address pc          = NULL;
353  address npc         = NULL;
354
355  //%note os_trap_1
356  if (info != NULL && uc != NULL && thread != NULL) {
357    // factor me: getPCfromContext
358    pc  = (address) uc->uc_mcontext.gregs[REG_PC];
359    npc = (address) uc->uc_mcontext.gregs[REG_nPC];
360
361    // SafeFetch() support
362    // Implemented with either a fixed set of addresses such
363    // as Fetch32*, or with Thread._OnTrap.
364    if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(Fetch32PFI)) {
365      uc->uc_mcontext.gregs [REG_PC]  = intptr_t(Fetch32Resume) ;
366      uc->uc_mcontext.gregs [REG_nPC] = intptr_t(Fetch32Resume) + 4 ;
367      return true ;
368    }
369    if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(FetchNPFI)) {
370      uc->uc_mcontext.gregs [REG_PC]  = intptr_t(FetchNResume) ;
371      uc->uc_mcontext.gregs [REG_nPC] = intptr_t(FetchNResume) + 4 ;
372      return true ;
373    }
374
375    // Handle ALL stack overflow variations here
376    if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
377      address addr = (address) info->si_addr;
378      if (thread->in_stack_yellow_zone(addr)) {
379        thread->disable_stack_yellow_zone();
380        // Sometimes the register windows are not properly flushed.
381        if(uc->uc_mcontext.gwins != NULL) {
382          ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
383        }
384        if (thread->thread_state() == _thread_in_Java) {
385          // Throw a stack overflow exception.  Guard pages will be reenabled
386          // while unwinding the stack.
387          stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
388        } else {
389          // Thread was in the vm or native code.  Return and try to finish.
390          return true;
391        }
392      } else if (thread->in_stack_red_zone(addr)) {
393        // Fatal red zone violation.  Disable the guard pages and fall through
394        // to handle_unexpected_exception way down below.
395        thread->disable_stack_red_zone();
396        tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
397        // Sometimes the register windows are not properly flushed.
398        if(uc->uc_mcontext.gwins != NULL) {
399          ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
400        }
401      }
402    }
403
404
405    if (thread->thread_state() == _thread_in_vm) {
406      if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
407        stub = StubRoutines::handler_for_unsafe_access();
408      }
409    }
410
411    else if (thread->thread_state() == _thread_in_Java) {
412      // Java thread running in Java code => find exception handler if any
413      // a fault inside compiled code, the interpreter, or a stub
414
415      // Support Safepoint Polling
416      if ( sig == SIGSEGV && (address)info->si_addr == os::get_polling_page() ) {
417        stub = SharedRuntime::get_poll_stub(pc);
418      }
419
420      // Not needed on x86 solaris because verify_oops doesn't generate
421      // SEGV/BUS like sparc does.
422      if ( (sig == SIGSEGV || sig == SIGBUS)
423           && pc >= MacroAssembler::_verify_oop_implicit_branch[0]
424           && pc <  MacroAssembler::_verify_oop_implicit_branch[1] ) {
425        stub     =  MacroAssembler::_verify_oop_implicit_branch[2];
426        warning("fixed up memory fault in +VerifyOops at address " INTPTR_FORMAT, info->si_addr);
427      }
428
429      // This is not factored because on x86 solaris the patching for
430      // zombies does not generate a SEGV.
431      else if (sig == SIGSEGV && nativeInstruction_at(pc)->is_zombie()) {
432        // zombie method (ld [%g0],%o7 instruction)
433        stub = SharedRuntime::get_handle_wrong_method_stub();
434
435        // At the stub it needs to look like a call from the caller of this
436        // method (not a call from the segv site).
437        pc = (address)uc->uc_mcontext.gregs[REG_O7];
438      }
439      else if (sig == SIGBUS && info->si_code == BUS_OBJERR) {
440        // BugId 4454115: A read from a MappedByteBuffer can fault
441        // here if the underlying file has been truncated.
442        // Do not crash the VM in such a case.
443        CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
444        nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
445        if (nm != NULL && nm->has_unsafe_access()) {
446          stub = StubRoutines::handler_for_unsafe_access();
447        }
448      }
449
450      else if (sig == SIGFPE && info->si_code == FPE_INTDIV) {
451        // integer divide by zero
452        stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
453      }
454      else if (sig == SIGFPE && info->si_code == FPE_FLTDIV) {
455        // floating-point divide by zero
456        stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
457      }
458#ifdef COMPILER2
459      else if (sig == SIGILL && nativeInstruction_at(pc)->is_ic_miss_trap()) {
460#ifdef ASSERT
461  #ifdef TIERED
462        CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
463        assert(cb->is_compiled_by_c2(), "Wrong compiler");
464  #endif // TIERED
465#endif // ASSERT
466        // Inline cache missed and user trap "Tne G0+ST_RESERVED_FOR_USER_0+2" taken.
467        stub = SharedRuntime::get_ic_miss_stub();
468        // At the stub it needs to look like a call from the caller of this
469        // method (not a call from the segv site).
470        pc = (address)uc->uc_mcontext.gregs[REG_O7];
471      }
472#endif  // COMPILER2
473
474      else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
475        // Determination of interpreter/vtable stub/compiled code null exception
476        stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
477      }
478    }
479
480    // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
481    // and the heap gets shrunk before the field access.
482    if ((sig == SIGSEGV) || (sig == SIGBUS)) {
483      address addr = JNI_FastGetField::find_slowcase_pc(pc);
484      if (addr != (address)-1) {
485        stub = addr;
486      }
487    }
488
489    // Check to see if we caught the safepoint code in the
490    // process of write protecting the memory serialization page.
491    // It write enables the page immediately after protecting it
492    // so just return.
493    if ((sig == SIGSEGV) &&
494        os::is_memory_serialize_page(thread, (address)info->si_addr)) {
495      // Block current thread until the memory serialize page permission restored.
496      os::block_on_serialize_page_trap();
497      return true;
498    }
499  }
500
501  if (stub != NULL) {
502    // save all thread context in case we need to restore it
503
504    thread->set_saved_exception_pc(pc);
505    thread->set_saved_exception_npc(npc);
506
507    // simulate a branch to the stub (a "call" in the safepoint stub case)
508    // factor me: setPC
509    uc->uc_mcontext.gregs[REG_PC ] = (greg_t)stub;
510    uc->uc_mcontext.gregs[REG_nPC] = (greg_t)(stub + 4);
511
512#ifndef PRODUCT
513    if (TraceJumps) thread->record_jump(stub, NULL, __FILE__, __LINE__);
514#endif /* PRODUCT */
515
516    return true;
517  }
518
519  // signal-chaining
520  if (os::Solaris::chained_handler(sig, info, ucVoid)) {
521    return true;
522  }
523
524  if (!abort_if_unrecognized) {
525    // caller wants another chance, so give it to him
526    return false;
527  }
528
529  if (!os::Solaris::libjsig_is_loaded) {
530    struct sigaction oldAct;
531    sigaction(sig, (struct sigaction *)0, &oldAct);
532    if (oldAct.sa_sigaction != signalHandler) {
533      void* sighand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
534                                          : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
535      warning("Unexpected Signal %d occurred under user-defined signal handler " INTPTR_FORMAT, sig, (intptr_t)sighand);
536    }
537  }
538
539  if (pc == NULL && uc != NULL) {
540    pc = (address) uc->uc_mcontext.gregs[REG_PC];
541  }
542
543  // unmask current signal
544  sigset_t newset;
545  sigemptyset(&newset);
546  sigaddset(&newset, sig);
547  sigprocmask(SIG_UNBLOCK, &newset, NULL);
548
549  VMError err(t, sig, pc, info, ucVoid);
550  err.report_and_die();
551
552  ShouldNotReachHere();
553}
554
555void os::print_context(outputStream *st, void *context) {
556  if (context == NULL) return;
557
558  ucontext_t *uc = (ucontext_t*)context;
559  st->print_cr("Registers:");
560
561  st->print_cr(" O0=" INTPTR_FORMAT " O1=" INTPTR_FORMAT
562               " O2=" INTPTR_FORMAT " O3=" INTPTR_FORMAT,
563                 uc->uc_mcontext.gregs[REG_O0],
564                 uc->uc_mcontext.gregs[REG_O1],
565                 uc->uc_mcontext.gregs[REG_O2],
566                 uc->uc_mcontext.gregs[REG_O3]);
567  st->print_cr(" O4=" INTPTR_FORMAT " O5=" INTPTR_FORMAT
568               " O6=" INTPTR_FORMAT " O7=" INTPTR_FORMAT,
569            uc->uc_mcontext.gregs[REG_O4],
570            uc->uc_mcontext.gregs[REG_O5],
571            uc->uc_mcontext.gregs[REG_O6],
572            uc->uc_mcontext.gregs[REG_O7]);
573
574  st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT
575               " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT,
576            uc->uc_mcontext.gregs[REG_G1],
577            uc->uc_mcontext.gregs[REG_G2],
578            uc->uc_mcontext.gregs[REG_G3],
579            uc->uc_mcontext.gregs[REG_G4]);
580  st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT
581               " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT,
582            uc->uc_mcontext.gregs[REG_G5],
583            uc->uc_mcontext.gregs[REG_G6],
584            uc->uc_mcontext.gregs[REG_G7],
585            uc->uc_mcontext.gregs[REG_Y]);
586
587  st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT,
588            uc->uc_mcontext.gregs[REG_PC],
589            uc->uc_mcontext.gregs[REG_nPC]);
590
591  st->cr();
592  st->cr();
593
594  st->print_cr("Register to memory mapping:");
595  st->cr();
596
597  // this is only for the "general purpose" registers
598
599  st->print_cr("O0=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O0]);
600  print_location(st, uc->uc_mcontext.gregs[REG_O0]);
601  st->cr();
602  st->print_cr("O1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O1]);
603  print_location(st, uc->uc_mcontext.gregs[REG_O1]);
604  st->cr();
605  st->print_cr("O2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O2]);
606  print_location(st, uc->uc_mcontext.gregs[REG_O2]);
607  st->cr();
608  st->print_cr("O3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O3]);
609  print_location(st, uc->uc_mcontext.gregs[REG_O3]);
610  st->cr();
611  st->print_cr("O4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O4]);
612  print_location(st, uc->uc_mcontext.gregs[REG_O4]);
613  st->cr();
614  st->print_cr("O5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O5]);
615  print_location(st, uc->uc_mcontext.gregs[REG_O5]);
616  st->cr();
617  st->print_cr("O6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O6]);
618  print_location(st, uc->uc_mcontext.gregs[REG_O6]);
619  st->cr();
620  st->print_cr("O7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_O7]);
621  print_location(st, uc->uc_mcontext.gregs[REG_O7]);
622  st->cr();
623
624  st->print_cr("G1=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G1]);
625  print_location(st, uc->uc_mcontext.gregs[REG_G1]);
626  st->cr();
627  st->print_cr("G2=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G2]);
628  print_location(st, uc->uc_mcontext.gregs[REG_G2]);
629  st->cr();
630  st->print_cr("G3=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G3]);
631  print_location(st, uc->uc_mcontext.gregs[REG_G3]);
632  st->cr();
633  st->print_cr("G4=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G4]);
634  print_location(st, uc->uc_mcontext.gregs[REG_G4]);
635  st->cr();
636  st->print_cr("G5=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G5]);
637  print_location(st, uc->uc_mcontext.gregs[REG_G5]);
638  st->cr();
639  st->print_cr("G6=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G6]);
640  print_location(st, uc->uc_mcontext.gregs[REG_G6]);
641  st->cr();
642  st->print_cr("G7=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_G7]);
643  print_location(st, uc->uc_mcontext.gregs[REG_G7]);
644
645  st->cr();
646  st->cr();
647
648  intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
649  st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
650  print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
651  st->cr();
652
653  // Note: it may be unsafe to inspect memory near pc. For example, pc may
654  // point to garbage if entry point in an nmethod is corrupted. Leave
655  // this at the end, and hope for the best.
656  ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
657  address pc = epc.pc();
658  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
659  print_hex_dump(st, pc - 16, pc + 16, sizeof(char));
660}
661
662void os::Solaris::init_thread_fpu_state(void) {
663    // Nothing needed on Sparc.
664}
665
666#if !defined(COMPILER2) && !defined(_LP64)
667
668// These routines are the initial value of atomic_xchg_entry(),
669// atomic_cmpxchg_entry(), atomic_add_entry() and fence_entry()
670// until initialization is complete.
671// TODO - remove when the VM drops support for V8.
672
673typedef jint  xchg_func_t        (jint,  volatile jint*);
674typedef jint  cmpxchg_func_t     (jint,  volatile jint*,  jint);
675typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong);
676typedef jint  add_func_t         (jint,  volatile jint*);
677
678jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) {
679  // try to use the stub:
680  xchg_func_t* func = CAST_TO_FN_PTR(xchg_func_t*, StubRoutines::atomic_xchg_entry());
681
682  if (func != NULL) {
683    os::atomic_xchg_func = func;
684    return (*func)(exchange_value, dest);
685  }
686  assert(Threads::number_of_threads() == 0, "for bootstrap only");
687
688  jint old_value = *dest;
689  *dest = exchange_value;
690  return old_value;
691}
692
693jint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint compare_value) {
694  // try to use the stub:
695  cmpxchg_func_t* func = CAST_TO_FN_PTR(cmpxchg_func_t*, StubRoutines::atomic_cmpxchg_entry());
696
697  if (func != NULL) {
698    os::atomic_cmpxchg_func = func;
699    return (*func)(exchange_value, dest, compare_value);
700  }
701  assert(Threads::number_of_threads() == 0, "for bootstrap only");
702
703  jint old_value = *dest;
704  if (old_value == compare_value)
705    *dest = exchange_value;
706  return old_value;
707}
708
709jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
710  // try to use the stub:
711  cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry());
712
713  if (func != NULL) {
714    os::atomic_cmpxchg_long_func = func;
715    return (*func)(exchange_value, dest, compare_value);
716  }
717  assert(Threads::number_of_threads() == 0, "for bootstrap only");
718
719  jlong old_value = *dest;
720  if (old_value == compare_value)
721    *dest = exchange_value;
722  return old_value;
723}
724
725jint os::atomic_add_bootstrap(jint add_value, volatile jint* dest) {
726  // try to use the stub:
727  add_func_t* func = CAST_TO_FN_PTR(add_func_t*, StubRoutines::atomic_add_entry());
728
729  if (func != NULL) {
730    os::atomic_add_func = func;
731    return (*func)(add_value, dest);
732  }
733  assert(Threads::number_of_threads() == 0, "for bootstrap only");
734
735  return (*dest) += add_value;
736}
737
738xchg_func_t*         os::atomic_xchg_func         = os::atomic_xchg_bootstrap;
739cmpxchg_func_t*      os::atomic_cmpxchg_func      = os::atomic_cmpxchg_bootstrap;
740cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
741add_func_t*          os::atomic_add_func          = os::atomic_add_bootstrap;
742
743#endif // !_LP64 && !COMPILER2
744
745#if defined(__sparc) && defined(COMPILER2) && defined(_GNU_SOURCE)
746 // See file build/solaris/makefiles/$compiler.make
747 // For compiler1 the architecture is v8 and frps isn't present in v8
748 extern "C"  void _mark_fpu_nosave() {
749   __asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :);
750  }
751#endif //defined(__sparc) && defined(COMPILER2)
752