annotate src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @ 3612:ed3ac862d22d

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