Mercurial > hg > graal-compiler
annotate src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @ 2030:fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
Summary: The concurrent marking thread can complete its operation and increment the full GC counter during a Full GC. This causes the nesting of increments to the start and end of Full GCs that we are expecting to be wrong. the fix is for the marking thread to join the suspendible thread set before incrementing the counter so that it's blocked until the Full GC (or any other safepoint) is finished. The change also includes some minor code cleanup (I renamed a parameter).
Reviewed-by: brutisso, ysr
author | tonyp |
---|---|
date | Tue, 14 Dec 2010 16:19:44 -0500 |
parents | 828eafbd85cc |
children | 36c186bcc085 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1250
diff
changeset
|
2 * Copyright (c) 1999, 2010, 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:
1250
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1250
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:
1250
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 // no precompiled headers |
26 #include "assembler_x86.inline.hpp" | |
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_x86.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" | |
51 #include "runtime/timer.hpp" | |
52 #include "thread_solaris.inline.hpp" | |
53 #include "utilities/events.hpp" | |
54 #include "utilities/vmError.hpp" | |
55 #ifdef COMPILER1 | |
56 #include "c1/c1_Runtime1.hpp" | |
57 #endif | |
58 #ifdef COMPILER2 | |
59 #include "opto/runtime.hpp" | |
60 #endif | |
0 | 61 |
62 // put OS-includes here | |
63 # include <sys/types.h> | |
64 # include <sys/mman.h> | |
65 # include <pthread.h> | |
66 # include <signal.h> | |
67 # include <setjmp.h> | |
68 # include <errno.h> | |
69 # include <dlfcn.h> | |
70 # include <stdio.h> | |
71 # include <unistd.h> | |
72 # include <sys/resource.h> | |
73 # include <thread.h> | |
74 # include <sys/stat.h> | |
75 # include <sys/time.h> | |
76 # include <sys/filio.h> | |
77 # include <sys/utsname.h> | |
78 # include <sys/systeminfo.h> | |
79 # include <sys/socket.h> | |
80 # include <sys/trap.h> | |
81 # include <sys/lwp.h> | |
82 # include <pwd.h> | |
83 # include <poll.h> | |
84 # include <sys/lwp.h> | |
85 # include <procfs.h> // see comment in <sys/procfs.h> | |
86 | |
87 #ifndef AMD64 | |
88 // QQQ seems useless at this point | |
89 # define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later | |
90 #endif // AMD64 | |
91 # include <sys/procfs.h> // see comment in <sys/procfs.h> | |
92 | |
93 | |
94 #define MAX_PATH (2 * K) | |
95 | |
96 // Minimum stack size for the VM. It's easier to document a constant value | |
97 // but it's different for x86 and sparc because the page sizes are different. | |
98 #ifdef AMD64 | |
99 size_t os::Solaris::min_stack_allowed = 224*K; | |
100 #define REG_SP REG_RSP | |
101 #define REG_PC REG_RIP | |
102 #define REG_FP REG_RBP | |
103 #else | |
104 size_t os::Solaris::min_stack_allowed = 64*K; | |
105 #define REG_SP UESP | |
106 #define REG_PC EIP | |
107 #define REG_FP EBP | |
108 // 4900493 counter to prevent runaway LDTR refresh attempt | |
109 | |
110 static volatile int ldtr_refresh = 0; | |
111 // the libthread instruction that faults because of the stale LDTR | |
112 | |
113 static const unsigned char movlfs[] = { 0x8e, 0xe0 // movl %eax,%fs | |
114 }; | |
115 #endif // AMD64 | |
116 | |
117 char* os::non_memory_address_word() { | |
118 // Must never look like an address returned by reserve_memory, | |
119 // even in its subfields (as defined by the CPU immediate fields, | |
120 // if the CPU splits constants across multiple instructions). | |
121 return (char*) -1; | |
122 } | |
123 | |
124 // | |
125 // Validate a ucontext retrieved from walking a uc_link of a ucontext. | |
126 // There are issues with libthread giving out uc_links for different threads | |
127 // on the same uc_link chain and bad or circular links. | |
128 // | |
129 bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) { | |
130 if (valid >= suspect || | |
131 valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags || | |
132 valid->uc_stack.ss_sp != suspect->uc_stack.ss_sp || | |
133 valid->uc_stack.ss_size != suspect->uc_stack.ss_size) { | |
134 DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");) | |
135 return false; | |
136 } | |
137 | |
138 if (thread->is_Java_thread()) { | |
139 if (!valid_stack_address(thread, (address)suspect)) { | |
140 DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");) | |
141 return false; | |
142 } | |
143 if (!valid_stack_address(thread, (address) suspect->uc_mcontext.gregs[REG_SP])) { | |
144 DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");) | |
145 return false; | |
146 } | |
147 } | |
148 return true; | |
149 } | |
150 | |
151 // We will only follow one level of uc_link since there are libthread | |
152 // issues with ucontext linking and it is better to be safe and just | |
153 // let caller retry later. | |
154 ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread, | |
155 ucontext_t *uc) { | |
156 | |
157 ucontext_t *retuc = NULL; | |
158 | |
159 if (uc != NULL) { | |
160 if (uc->uc_link == NULL) { | |
161 // cannot validate without uc_link so accept current ucontext | |
162 retuc = uc; | |
163 } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { | |
164 // first ucontext is valid so try the next one | |
165 uc = uc->uc_link; | |
166 if (uc->uc_link == NULL) { | |
167 // cannot validate without uc_link so accept current ucontext | |
168 retuc = uc; | |
169 } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { | |
170 // the ucontext one level down is also valid so return it | |
171 retuc = uc; | |
172 } | |
173 } | |
174 } | |
175 return retuc; | |
176 } | |
177 | |
178 // Assumes ucontext is valid | |
179 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) { | |
180 return ExtendedPC((address)uc->uc_mcontext.gregs[REG_PC]); | |
181 } | |
182 | |
183 // Assumes ucontext is valid | |
184 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) { | |
185 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; | |
186 } | |
187 | |
188 // Assumes ucontext is valid | |
189 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) { | |
190 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; | |
191 } | |
192 | |
193 // For Forte Analyzer AsyncGetCallTrace profiling support - thread | |
194 // is currently interrupted by SIGPROF. | |
195 // | |
196 // The difference between this and os::fetch_frame_from_context() is that | |
197 // here we try to skip nested signal frames. | |
198 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread, | |
199 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) { | |
200 | |
201 assert(thread != NULL, "just checking"); | |
202 assert(ret_sp != NULL, "just checking"); | |
203 assert(ret_fp != NULL, "just checking"); | |
204 | |
205 ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc); | |
206 return os::fetch_frame_from_context(luc, ret_sp, ret_fp); | |
207 } | |
208 | |
209 ExtendedPC os::fetch_frame_from_context(void* ucVoid, | |
210 intptr_t** ret_sp, intptr_t** ret_fp) { | |
211 | |
212 ExtendedPC epc; | |
213 ucontext_t *uc = (ucontext_t*)ucVoid; | |
214 | |
215 if (uc != NULL) { | |
216 epc = os::Solaris::ucontext_get_ExtendedPC(uc); | |
217 if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc); | |
218 if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc); | |
219 } else { | |
220 // construct empty ExtendedPC for return value checking | |
221 epc = ExtendedPC(NULL); | |
222 if (ret_sp) *ret_sp = (intptr_t *)NULL; | |
223 if (ret_fp) *ret_fp = (intptr_t *)NULL; | |
224 } | |
225 | |
226 return epc; | |
227 } | |
228 | |
229 frame os::fetch_frame_from_context(void* ucVoid) { | |
230 intptr_t* sp; | |
231 intptr_t* fp; | |
232 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); | |
233 return frame(sp, fp, epc.pc()); | |
234 } | |
235 | |
236 frame os::get_sender_for_C_frame(frame* fr) { | |
237 return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); | |
238 } | |
239 | |
472
7b920868b475
6773838: There is no calling stack for Compiler thread in hs_err file on x86
coleenp
parents:
196
diff
changeset
|
240 extern "C" intptr_t *_get_current_fp(); // in .il file |
0 | 241 |
242 frame os::current_frame() { | |
472
7b920868b475
6773838: There is no calling stack for Compiler thread in hs_err file on x86
coleenp
parents:
196
diff
changeset
|
243 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp |
0 | 244 frame myframe((intptr_t*)os::current_stack_pointer(), |
245 (intptr_t*)fp, | |
246 CAST_FROM_FN_PTR(address, os::current_frame)); | |
247 if (os::is_first_C_frame(&myframe)) { | |
248 // stack is not walkable | |
107
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
249 frame ret; // This will be a null useless frame |
93b6525e3b82
6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents:
0
diff
changeset
|
250 return ret; |
0 | 251 } else { |
252 return os::get_sender_for_C_frame(&myframe); | |
253 } | |
254 } | |
255 | |
256 // This is a simple callback that just fetches a PC for an interrupted thread. | |
257 // The thread need not be suspended and the fetched PC is just a hint. | |
258 // This one is currently used for profiling the VMThread ONLY! | |
259 | |
260 // Must be synchronous | |
261 void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) { | |
262 Thread* thread = args->thread(); | |
263 ucontext_t* uc = args->ucontext(); | |
264 intptr_t* sp; | |
265 | |
266 assert(ProfileVM && thread->is_VM_thread(), "just checking"); | |
267 | |
268 ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]); | |
269 _addr = new_addr; | |
270 } | |
271 | |
272 static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) { | |
273 char lwpstatusfile[PROCFILE_LENGTH]; | |
274 int lwpfd, err; | |
275 | |
276 if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs)) | |
277 return (err); | |
278 if (*flags == TRS_LWPID) { | |
279 sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(), | |
280 *lwp); | |
281 if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) { | |
282 perror("thr_mutator_status: open lwpstatus"); | |
283 return (EINVAL); | |
284 } | |
285 if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) != | |
286 sizeof (lwpstatus_t)) { | |
287 perror("thr_mutator_status: read lwpstatus"); | |
288 (void) close(lwpfd); | |
289 return (EINVAL); | |
290 } | |
291 (void) close(lwpfd); | |
292 } | |
293 return (0); | |
294 } | |
295 | |
296 #ifndef AMD64 | |
297 | |
298 // Detecting SSE support by OS | |
299 // From solaris_i486.s | |
300 extern "C" bool sse_check(); | |
301 extern "C" bool sse_unavailable(); | |
302 | |
303 enum { SSE_UNKNOWN, SSE_NOT_SUPPORTED, SSE_SUPPORTED}; | |
304 static int sse_status = SSE_UNKNOWN; | |
305 | |
306 | |
307 static void check_for_sse_support() { | |
308 if (!VM_Version::supports_sse()) { | |
309 sse_status = SSE_NOT_SUPPORTED; | |
310 return; | |
311 } | |
312 // looking for _sse_hw in libc.so, if it does not exist or | |
313 // the value (int) is 0, OS has no support for SSE | |
314 int *sse_hwp; | |
315 void *h; | |
316 | |
317 if ((h=dlopen("/usr/lib/libc.so", RTLD_LAZY)) == NULL) { | |
318 //open failed, presume no support for SSE | |
319 sse_status = SSE_NOT_SUPPORTED; | |
320 return; | |
321 } | |
322 if ((sse_hwp = (int *)dlsym(h, "_sse_hw")) == NULL) { | |
323 sse_status = SSE_NOT_SUPPORTED; | |
324 } else if (*sse_hwp == 0) { | |
325 sse_status = SSE_NOT_SUPPORTED; | |
326 } | |
327 dlclose(h); | |
328 | |
329 if (sse_status == SSE_UNKNOWN) { | |
330 bool (*try_sse)() = (bool (*)())sse_check; | |
331 sse_status = (*try_sse)() ? SSE_SUPPORTED : SSE_NOT_SUPPORTED; | |
332 } | |
333 | |
334 } | |
335 | |
585 | 336 #endif // AMD64 |
337 | |
0 | 338 bool os::supports_sse() { |
585 | 339 #ifdef AMD64 |
340 return true; | |
341 #else | |
0 | 342 if (sse_status == SSE_UNKNOWN) |
343 check_for_sse_support(); | |
344 return sse_status == SSE_SUPPORTED; | |
585 | 345 #endif // AMD64 |
0 | 346 } |
347 | |
348 bool os::is_allocatable(size_t bytes) { | |
349 #ifdef AMD64 | |
350 return true; | |
351 #else | |
352 | |
353 if (bytes < 2 * G) { | |
354 return true; | |
355 } | |
356 | |
357 char* addr = reserve_memory(bytes, NULL); | |
358 | |
359 if (addr != NULL) { | |
360 release_memory(addr, bytes); | |
361 } | |
362 | |
363 return addr != NULL; | |
364 #endif // AMD64 | |
365 | |
366 } | |
367 | |
368 extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized); | |
369 | |
370 extern "C" void Fetch32PFI () ; | |
371 extern "C" void Fetch32Resume () ; | |
372 #ifdef AMD64 | |
373 extern "C" void FetchNPFI () ; | |
374 extern "C" void FetchNResume () ; | |
375 #endif // AMD64 | |
376 | |
377 int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { | |
378 ucontext_t* uc = (ucontext_t*) ucVoid; | |
379 | |
380 #ifndef AMD64 | |
381 if (sig == SIGILL && info->si_addr == (caddr_t)sse_check) { | |
382 // the SSE instruction faulted. supports_sse() need return false. | |
383 uc->uc_mcontext.gregs[EIP] = (greg_t)sse_unavailable; | |
384 return true; | |
385 } | |
386 #endif // !AMD64 | |
387 | |
388 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady | |
389 | |
390 SignalHandlerMark shm(t); | |
391 | |
392 if(sig == SIGPIPE || sig == SIGXFSZ) { | |
393 if (os::Solaris::chained_handler(sig, info, ucVoid)) { | |
394 return true; | |
395 } else { | |
396 if (PrintMiscellaneous && (WizardMode || Verbose)) { | |
397 char buf[64]; | |
398 warning("Ignoring %s - see 4229104 or 6499219", | |
399 os::exception_name(sig, buf, sizeof(buf))); | |
400 | |
401 } | |
402 return true; | |
403 } | |
404 } | |
405 | |
406 JavaThread* thread = NULL; | |
407 VMThread* vmthread = NULL; | |
408 | |
409 if (os::Solaris::signal_handlers_are_installed) { | |
410 if (t != NULL ){ | |
411 if(t->is_Java_thread()) { | |
412 thread = (JavaThread*)t; | |
413 } | |
414 else if(t->is_VM_thread()){ | |
415 vmthread = (VMThread *)t; | |
416 } | |
417 } | |
418 } | |
419 | |
420 guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs"); | |
421 | |
422 if (sig == os::Solaris::SIGasync()) { | |
423 if(thread){ | |
424 OSThread::InterruptArguments args(thread, uc); | |
425 thread->osthread()->do_interrupt_callbacks_at_interrupt(&args); | |
426 return true; | |
427 } | |
428 else if(vmthread){ | |
429 OSThread::InterruptArguments args(vmthread, uc); | |
430 vmthread->osthread()->do_interrupt_callbacks_at_interrupt(&args); | |
431 return true; | |
432 } else if (os::Solaris::chained_handler(sig, info, ucVoid)) { | |
433 return true; | |
434 } else { | |
435 // If os::Solaris::SIGasync not chained, and this is a non-vm and | |
436 // non-java thread | |
437 return true; | |
438 } | |
439 } | |
440 | |
441 if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) { | |
442 // can't decode this kind of signal | |
443 info = NULL; | |
444 } else { | |
445 assert(sig == info->si_signo, "bad siginfo"); | |
446 } | |
447 | |
448 // decide if this trap can be handled by a stub | |
449 address stub = NULL; | |
450 | |
451 address pc = NULL; | |
452 | |
453 //%note os_trap_1 | |
454 if (info != NULL && uc != NULL && thread != NULL) { | |
455 // factor me: getPCfromContext | |
456 pc = (address) uc->uc_mcontext.gregs[REG_PC]; | |
457 | |
458 // SafeFetch32() support | |
459 if (pc == (address) Fetch32PFI) { | |
460 uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ; | |
461 return true ; | |
462 } | |
463 #ifdef AMD64 | |
464 if (pc == (address) FetchNPFI) { | |
465 uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ; | |
466 return true ; | |
467 } | |
468 #endif // AMD64 | |
469 | |
470 // Handle ALL stack overflow variations here | |
471 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { | |
472 address addr = (address) info->si_addr; | |
473 if (thread->in_stack_yellow_zone(addr)) { | |
474 thread->disable_stack_yellow_zone(); | |
475 if (thread->thread_state() == _thread_in_Java) { | |
476 // Throw a stack overflow exception. Guard pages will be reenabled | |
477 // while unwinding the stack. | |
478 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); | |
479 } else { | |
480 // Thread was in the vm or native code. Return and try to finish. | |
481 return true; | |
482 } | |
483 } else if (thread->in_stack_red_zone(addr)) { | |
484 // Fatal red zone violation. Disable the guard pages and fall through | |
485 // to handle_unexpected_exception way down below. | |
486 thread->disable_stack_red_zone(); | |
487 tty->print_raw_cr("An irrecoverable stack overflow has occurred."); | |
488 } | |
489 } | |
490 | |
491 if (thread->thread_state() == _thread_in_vm) { | |
492 if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) { | |
493 stub = StubRoutines::handler_for_unsafe_access(); | |
494 } | |
495 } | |
496 | |
497 if (thread->thread_state() == _thread_in_Java) { | |
498 // Support Safepoint Polling | |
499 if ( sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) { | |
500 stub = SharedRuntime::get_poll_stub(pc); | |
501 } | |
502 else if (sig == SIGBUS && info->si_code == BUS_OBJERR) { | |
503 // BugId 4454115: A read from a MappedByteBuffer can fault | |
504 // here if the underlying file has been truncated. | |
505 // Do not crash the VM in such a case. | |
506 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); | |
507 nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; | |
508 if (nm != NULL && nm->has_unsafe_access()) { | |
509 stub = StubRoutines::handler_for_unsafe_access(); | |
510 } | |
511 } | |
512 else | |
513 if (sig == SIGFPE && info->si_code == FPE_INTDIV) { | |
514 // integer divide by zero | |
515 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); | |
516 } | |
517 #ifndef AMD64 | |
518 else if (sig == SIGFPE && info->si_code == FPE_FLTDIV) { | |
519 // floating-point divide by zero | |
520 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); | |
521 } | |
522 else if (sig == SIGFPE && info->si_code == FPE_FLTINV) { | |
523 // The encoding of D2I in i486.ad can cause an exception prior | |
524 // to the fist instruction if there was an invalid operation | |
525 // pending. We want to dismiss that exception. From the win_32 | |
526 // side it also seems that if it really was the fist causing | |
527 // the exception that we do the d2i by hand with different | |
528 // rounding. Seems kind of weird. QQQ TODO | |
529 // Note that we take the exception at the NEXT floating point instruction. | |
530 if (pc[0] == 0xDB) { | |
531 assert(pc[0] == 0xDB, "not a FIST opcode"); | |
532 assert(pc[1] == 0x14, "not a FIST opcode"); | |
533 assert(pc[2] == 0x24, "not a FIST opcode"); | |
534 return true; | |
535 } else { | |
536 assert(pc[-3] == 0xDB, "not an flt invalid opcode"); | |
537 assert(pc[-2] == 0x14, "not an flt invalid opcode"); | |
538 assert(pc[-1] == 0x24, "not an flt invalid opcode"); | |
539 } | |
540 } | |
541 else if (sig == SIGFPE ) { | |
542 tty->print_cr("caught SIGFPE, info 0x%x.", info->si_code); | |
543 } | |
544 #endif // !AMD64 | |
545 | |
546 // QQQ It doesn't seem that we need to do this on x86 because we should be able | |
547 // to return properly from the handler without this extra stuff on the back side. | |
548 | |
549 else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { | |
550 // Determination of interpreter/vtable stub/compiled code null exception | |
551 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); | |
552 } | |
553 } | |
554 | |
555 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in | |
556 // and the heap gets shrunk before the field access. | |
557 if ((sig == SIGSEGV) || (sig == SIGBUS)) { | |
558 address addr = JNI_FastGetField::find_slowcase_pc(pc); | |
559 if (addr != (address)-1) { | |
560 stub = addr; | |
561 } | |
562 } | |
563 | |
564 // Check to see if we caught the safepoint code in the | |
565 // process of write protecting the memory serialization page. | |
566 // It write enables the page immediately after protecting it | |
567 // so we can just return to retry the write. | |
568 if ((sig == SIGSEGV) && | |
569 os::is_memory_serialize_page(thread, (address)info->si_addr)) { | |
570 // Block current thread until the memory serialize page permission restored. | |
571 os::block_on_serialize_page_trap(); | |
572 return true; | |
573 } | |
574 } | |
575 | |
576 // Execution protection violation | |
577 // | |
578 // Preventative code for future versions of Solaris which may | |
579 // enable execution protection when running the 32-bit VM on AMD64. | |
580 // | |
581 // This should be kept as the last step in the triage. We don't | |
582 // have a dedicated trap number for a no-execute fault, so be | |
583 // conservative and allow other handlers the first shot. | |
584 // | |
585 // Note: We don't test that info->si_code == SEGV_ACCERR here. | |
586 // this si_code is so generic that it is almost meaningless; and | |
587 // the si_code for this condition may change in the future. | |
588 // Furthermore, a false-positive should be harmless. | |
589 if (UnguardOnExecutionViolation > 0 && | |
590 (sig == SIGSEGV || sig == SIGBUS) && | |
591 uc->uc_mcontext.gregs[TRAPNO] == T_PGFLT) { // page fault | |
592 int page_size = os::vm_page_size(); | |
593 address addr = (address) info->si_addr; | |
594 address pc = (address) uc->uc_mcontext.gregs[REG_PC]; | |
595 // Make sure the pc and the faulting address are sane. | |
596 // | |
597 // If an instruction spans a page boundary, and the page containing | |
598 // the beginning of the instruction is executable but the following | |
599 // page is not, the pc and the faulting address might be slightly | |
600 // different - we still want to unguard the 2nd page in this case. | |
601 // | |
602 // 15 bytes seems to be a (very) safe value for max instruction size. | |
603 bool pc_is_near_addr = | |
604 (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15); | |
605 bool instr_spans_page_boundary = | |
606 (align_size_down((intptr_t) pc ^ (intptr_t) addr, | |
607 (intptr_t) page_size) > 0); | |
608 | |
609 if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) { | |
610 static volatile address last_addr = | |
611 (address) os::non_memory_address_word(); | |
612 | |
613 // In conservative mode, don't unguard unless the address is in the VM | |
614 if (addr != last_addr && | |
615 (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { | |
616 | |
477
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
472
diff
changeset
|
617 // Make memory rwx and retry |
0 | 618 address page_start = |
619 (address) align_size_down((intptr_t) addr, (intptr_t) page_size); | |
477
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
472
diff
changeset
|
620 bool res = os::protect_memory((char*) page_start, page_size, |
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
472
diff
changeset
|
621 os::MEM_PROT_RWX); |
0 | 622 |
623 if (PrintMiscellaneous && Verbose) { | |
624 char buf[256]; | |
625 jio_snprintf(buf, sizeof(buf), "Execution protection violation " | |
626 "at " INTPTR_FORMAT | |
627 ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, | |
628 page_start, (res ? "success" : "failed"), errno); | |
629 tty->print_raw_cr(buf); | |
630 } | |
631 stub = pc; | |
632 | |
633 // Set last_addr so if we fault again at the same address, we don't end | |
634 // up in an endless loop. | |
635 // | |
636 // There are two potential complications here. Two threads trapping at | |
637 // the same address at the same time could cause one of the threads to | |
638 // think it already unguarded, and abort the VM. Likely very rare. | |
639 // | |
640 // The other race involves two threads alternately trapping at | |
641 // different addresses and failing to unguard the page, resulting in | |
642 // an endless loop. This condition is probably even more unlikely than | |
643 // the first. | |
644 // | |
645 // Although both cases could be avoided by using locks or thread local | |
646 // last_addr, these solutions are unnecessary complication: this | |
647 // handler is a best-effort safety net, not a complete solution. It is | |
648 // disabled by default and should only be used as a workaround in case | |
649 // we missed any no-execute-unsafe VM code. | |
650 | |
651 last_addr = addr; | |
652 } | |
653 } | |
654 } | |
655 | |
656 if (stub != NULL) { | |
657 // save all thread context in case we need to restore it | |
658 | |
659 if (thread != NULL) thread->set_saved_exception_pc(pc); | |
660 // 12/02/99: On Sparc it appears that the full context is also saved | |
661 // but as yet, no one looks at or restores that saved context | |
662 // factor me: setPC | |
663 uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub; | |
664 return true; | |
665 } | |
666 | |
667 // signal-chaining | |
668 if (os::Solaris::chained_handler(sig, info, ucVoid)) { | |
669 return true; | |
670 } | |
671 | |
672 #ifndef AMD64 | |
673 // Workaround (bug 4900493) for Solaris kernel bug 4966651. | |
674 // Handle an undefined selector caused by an attempt to assign | |
675 // fs in libthread getipriptr(). With the current libthread design every 512 | |
676 // thread creations the LDT for a private thread data structure is extended | |
677 // and thre is a hazard that and another thread attempting a thread creation | |
678 // will use a stale LDTR that doesn't reflect the structure's growth, | |
679 // causing a GP fault. | |
680 // Enforce the probable limit of passes through here to guard against an | |
681 // infinite loop if some other move to fs caused the GP fault. Note that | |
682 // this loop counter is ultimately a heuristic as it is possible for | |
683 // more than one thread to generate this fault at a time in an MP system. | |
684 // In the case of the loop count being exceeded or if the poll fails | |
685 // just fall through to a fatal error. | |
686 // If there is some other source of T_GPFLT traps and the text at EIP is | |
687 // unreadable this code will loop infinitely until the stack is exausted. | |
688 // The key to diagnosis in this case is to look for the bottom signal handler | |
689 // frame. | |
690 | |
691 if(! IgnoreLibthreadGPFault) { | |
692 if (sig == SIGSEGV && uc->uc_mcontext.gregs[TRAPNO] == T_GPFLT) { | |
693 const unsigned char *p = | |
694 (unsigned const char *) uc->uc_mcontext.gregs[EIP]; | |
695 | |
696 // Expected instruction? | |
697 | |
698 if(p[0] == movlfs[0] && p[1] == movlfs[1]) { | |
699 | |
700 Atomic::inc(&ldtr_refresh); | |
701 | |
702 // Infinite loop? | |
703 | |
704 if(ldtr_refresh < ((2 << 16) / PAGESIZE)) { | |
705 | |
706 // No, force scheduling to get a fresh view of the LDTR | |
707 | |
708 if(poll(NULL, 0, 10) == 0) { | |
709 | |
710 // Retry the move | |
711 | |
712 return false; | |
713 } | |
714 } | |
715 } | |
716 } | |
717 } | |
718 #endif // !AMD64 | |
719 | |
720 if (!abort_if_unrecognized) { | |
721 // caller wants another chance, so give it to him | |
722 return false; | |
723 } | |
724 | |
725 if (!os::Solaris::libjsig_is_loaded) { | |
726 struct sigaction oldAct; | |
727 sigaction(sig, (struct sigaction *)0, &oldAct); | |
728 if (oldAct.sa_sigaction != signalHandler) { | |
729 void* sighand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
730 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
605 | 731 warning("Unexpected Signal %d occurred under user-defined signal handler %#lx", sig, (long)sighand); |
0 | 732 } |
733 } | |
734 | |
735 if (pc == NULL && uc != NULL) { | |
736 pc = (address) uc->uc_mcontext.gregs[REG_PC]; | |
737 } | |
738 | |
739 // unmask current signal | |
740 sigset_t newset; | |
741 sigemptyset(&newset); | |
742 sigaddset(&newset, sig); | |
743 sigprocmask(SIG_UNBLOCK, &newset, NULL); | |
744 | |
745 VMError err(t, sig, pc, info, ucVoid); | |
746 err.report_and_die(); | |
747 | |
748 ShouldNotReachHere(); | |
749 } | |
750 | |
751 void os::print_context(outputStream *st, void *context) { | |
752 if (context == NULL) return; | |
753 | |
754 ucontext_t *uc = (ucontext_t*)context; | |
755 st->print_cr("Registers:"); | |
756 #ifdef AMD64 | |
757 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); | |
758 st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); | |
759 st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); | |
760 st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]); | |
761 st->cr(); | |
762 st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]); | |
763 st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]); | |
764 st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); | |
765 st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); | |
766 st->cr(); | |
1907 | 767 st->print( "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); |
768 st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); | |
0 | 769 st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); |
770 st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); | |
1250 | 771 st->cr(); |
772 st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); | |
0 | 773 st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); |
774 st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); | |
775 st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); | |
776 st->cr(); | |
777 st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]); | |
778 st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]); | |
779 #else | |
780 st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]); | |
781 st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]); | |
782 st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]); | |
783 st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]); | |
784 st->cr(); | |
785 st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]); | |
786 st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]); | |
787 st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]); | |
788 st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]); | |
789 st->cr(); | |
790 st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]); | |
791 st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]); | |
792 #endif // AMD64 | |
793 st->cr(); | |
794 st->cr(); | |
795 | |
796 intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc); | |
797 st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); | |
798 print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t)); | |
799 st->cr(); | |
800 | |
801 // Note: it may be unsafe to inspect memory near pc. For example, pc may | |
802 // point to garbage if entry point in an nmethod is corrupted. Leave | |
803 // this at the end, and hope for the best. | |
804 ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc); | |
805 address pc = epc.pc(); | |
806 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); | |
1907 | 807 print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); |
808 } | |
809 | |
810 void os::print_register_info(outputStream *st, void *context) { | |
811 if (context == NULL) return; | |
812 | |
813 ucontext_t *uc = (ucontext_t*)context; | |
814 | |
815 st->print_cr("Register to memory mapping:"); | |
816 st->cr(); | |
817 | |
818 // this is horrendously verbose but the layout of the registers in the | |
819 // context does not match how we defined our abstract Register set, so | |
820 // we can't just iterate through the gregs area | |
821 | |
822 // this is only for the "general purpose" registers | |
823 | |
824 #ifdef AMD64 | |
825 st->print("RAX="); print_location(st, uc->uc_mcontext.gregs[REG_RAX]); | |
826 st->print("RBX="); print_location(st, uc->uc_mcontext.gregs[REG_RBX]); | |
827 st->print("RCX="); print_location(st, uc->uc_mcontext.gregs[REG_RCX]); | |
828 st->print("RDX="); print_location(st, uc->uc_mcontext.gregs[REG_RDX]); | |
829 st->print("RSP="); print_location(st, uc->uc_mcontext.gregs[REG_RSP]); | |
830 st->print("RBP="); print_location(st, uc->uc_mcontext.gregs[REG_RBP]); | |
831 st->print("RSI="); print_location(st, uc->uc_mcontext.gregs[REG_RSI]); | |
832 st->print("RDI="); print_location(st, uc->uc_mcontext.gregs[REG_RDI]); | |
833 st->print("R8 ="); print_location(st, uc->uc_mcontext.gregs[REG_R8]); | |
834 st->print("R9 ="); print_location(st, uc->uc_mcontext.gregs[REG_R9]); | |
835 st->print("R10="); print_location(st, uc->uc_mcontext.gregs[REG_R10]); | |
836 st->print("R11="); print_location(st, uc->uc_mcontext.gregs[REG_R11]); | |
837 st->print("R12="); print_location(st, uc->uc_mcontext.gregs[REG_R12]); | |
838 st->print("R13="); print_location(st, uc->uc_mcontext.gregs[REG_R13]); | |
839 st->print("R14="); print_location(st, uc->uc_mcontext.gregs[REG_R14]); | |
840 st->print("R15="); print_location(st, uc->uc_mcontext.gregs[REG_R15]); | |
841 #else | |
842 st->print("EAX="); print_location(st, uc->uc_mcontext.gregs[EAX]); | |
843 st->print("EBX="); print_location(st, uc->uc_mcontext.gregs[EBX]); | |
844 st->print("ECX="); print_location(st, uc->uc_mcontext.gregs[ECX]); | |
845 st->print("EDX="); print_location(st, uc->uc_mcontext.gregs[EDX]); | |
846 st->print("ESP="); print_location(st, uc->uc_mcontext.gregs[UESP]); | |
847 st->print("EBP="); print_location(st, uc->uc_mcontext.gregs[EBP]); | |
848 st->print("ESI="); print_location(st, uc->uc_mcontext.gregs[ESI]); | |
849 st->print("EDI="); print_location(st, uc->uc_mcontext.gregs[EDI]); | |
850 #endif | |
851 | |
852 st->cr(); | |
0 | 853 } |
854 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1624
diff
changeset
|
855 |
0 | 856 #ifdef AMD64 |
857 void os::Solaris::init_thread_fpu_state(void) { | |
858 // Nothing to do | |
859 } | |
860 #else | |
861 // From solaris_i486.s | |
862 extern "C" void fixcw(); | |
863 | |
864 void os::Solaris::init_thread_fpu_state(void) { | |
865 // Set fpu to 53 bit precision. This happens too early to use a stub. | |
866 fixcw(); | |
867 } | |
868 | |
869 // These routines are the initial value of atomic_xchg_entry(), | |
870 // atomic_cmpxchg_entry(), atomic_inc_entry() and fence_entry() | |
871 // until initialization is complete. | |
872 // TODO - replace with .il implementation when compiler supports it. | |
873 | |
874 typedef jint xchg_func_t (jint, volatile jint*); | |
875 typedef jint cmpxchg_func_t (jint, volatile jint*, jint); | |
876 typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong); | |
877 typedef jint add_func_t (jint, volatile jint*); | |
878 | |
879 jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) { | |
880 // try to use the stub: | |
881 xchg_func_t* func = CAST_TO_FN_PTR(xchg_func_t*, StubRoutines::atomic_xchg_entry()); | |
882 | |
883 if (func != NULL) { | |
884 os::atomic_xchg_func = func; | |
885 return (*func)(exchange_value, dest); | |
886 } | |
887 assert(Threads::number_of_threads() == 0, "for bootstrap only"); | |
888 | |
889 jint old_value = *dest; | |
890 *dest = exchange_value; | |
891 return old_value; | |
892 } | |
893 | |
894 jint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint compare_value) { | |
895 // try to use the stub: | |
896 cmpxchg_func_t* func = CAST_TO_FN_PTR(cmpxchg_func_t*, StubRoutines::atomic_cmpxchg_entry()); | |
897 | |
898 if (func != NULL) { | |
899 os::atomic_cmpxchg_func = func; | |
900 return (*func)(exchange_value, dest, compare_value); | |
901 } | |
902 assert(Threads::number_of_threads() == 0, "for bootstrap only"); | |
903 | |
904 jint old_value = *dest; | |
905 if (old_value == compare_value) | |
906 *dest = exchange_value; | |
907 return old_value; | |
908 } | |
909 | |
910 jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) { | |
911 // try to use the stub: | |
912 cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry()); | |
913 | |
914 if (func != NULL) { | |
915 os::atomic_cmpxchg_long_func = func; | |
916 return (*func)(exchange_value, dest, compare_value); | |
917 } | |
918 assert(Threads::number_of_threads() == 0, "for bootstrap only"); | |
919 | |
920 jlong old_value = *dest; | |
921 if (old_value == compare_value) | |
922 *dest = exchange_value; | |
923 return old_value; | |
924 } | |
925 | |
926 jint os::atomic_add_bootstrap(jint add_value, volatile jint* dest) { | |
927 // try to use the stub: | |
928 add_func_t* func = CAST_TO_FN_PTR(add_func_t*, StubRoutines::atomic_add_entry()); | |
929 | |
930 if (func != NULL) { | |
931 os::atomic_add_func = func; | |
932 return (*func)(add_value, dest); | |
933 } | |
934 assert(Threads::number_of_threads() == 0, "for bootstrap only"); | |
935 | |
936 return (*dest) += add_value; | |
937 } | |
938 | |
939 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap; | |
940 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap; | |
941 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; | |
942 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; | |
943 | |
1624
726b40449bd2
6939019: Source code adjustments for parfait compilation of hotspot
zgu
parents:
1552
diff
changeset
|
944 extern "C" void _solaris_raw_setup_fpu(address ptr); |
0 | 945 void os::setup_fpu() { |
946 address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std(); | |
947 _solaris_raw_setup_fpu(fpu_cntrl); | |
948 } | |
949 #endif // AMD64 |