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