1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Thu Apr 24 15:07:57 2008 -0400 1.3 @@ -0,0 +1,648 @@ 1.4 +/* 1.5 + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// do not include precompiled header file 1.29 + 1.30 +#include "incls/_os_linux_sparc.cpp.incl" 1.31 + 1.32 +// Linux/Sparc has rather obscure naming of registers in sigcontext 1.33 +// different between 32 and 64 bits 1.34 +#ifdef _LP64 1.35 +#define SIG_PC(x) ((x)->sigc_regs.tpc) 1.36 +#define SIG_NPC(x) ((x)->sigc_regs.tnpc) 1.37 +#define SIG_REGS(x) ((x)->sigc_regs) 1.38 +#else 1.39 +#define SIG_PC(x) ((x)->si_regs.pc) 1.40 +#define SIG_NPC(x) ((x)->si_regs.npc) 1.41 +#define SIG_REGS(x) ((x)->si_regs) 1.42 +#endif 1.43 + 1.44 +// those are to reference registers in sigcontext 1.45 +enum { 1.46 + CON_G0 = 0, 1.47 + CON_G1, 1.48 + CON_G2, 1.49 + CON_G3, 1.50 + CON_G4, 1.51 + CON_G5, 1.52 + CON_G6, 1.53 + CON_G7, 1.54 + CON_O0, 1.55 + CON_O1, 1.56 + CON_O2, 1.57 + CON_O3, 1.58 + CON_O4, 1.59 + CON_O5, 1.60 + CON_O6, 1.61 + CON_O7, 1.62 +}; 1.63 + 1.64 +static inline void set_cont_address(sigcontext* ctx, address addr) { 1.65 + SIG_PC(ctx) = (intptr_t)addr; 1.66 + SIG_NPC(ctx) = (intptr_t)(addr+4); 1.67 +} 1.68 + 1.69 +// For Forte Analyzer AsyncGetCallTrace profiling support - thread is 1.70 +// currently interrupted by SIGPROF. 1.71 +// os::Solaris::fetch_frame_from_ucontext() tries to skip nested 1.72 +// signal frames. Currently we don't do that on Linux, so it's the 1.73 +// same as os::fetch_frame_from_context(). 1.74 +ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread, 1.75 + ucontext_t* uc, 1.76 + intptr_t** ret_sp, 1.77 + intptr_t** ret_fp) { 1.78 + assert(thread != NULL, "just checking"); 1.79 + assert(ret_sp != NULL, "just checking"); 1.80 + assert(ret_fp != NULL, "just checking"); 1.81 + 1.82 + return os::fetch_frame_from_context(uc, ret_sp, ret_fp); 1.83 +} 1.84 + 1.85 +ExtendedPC os::fetch_frame_from_context(void* ucVoid, 1.86 + intptr_t** ret_sp, 1.87 + intptr_t** ret_fp) { 1.88 + ucontext_t* uc = (ucontext_t*) ucVoid; 1.89 + ExtendedPC epc; 1.90 + 1.91 + if (uc != NULL) { 1.92 + epc = ExtendedPC(os::Linux::ucontext_get_pc(uc)); 1.93 + if (ret_sp) { 1.94 + *ret_sp = os::Linux::ucontext_get_sp(uc); 1.95 + } 1.96 + if (ret_fp) { 1.97 + *ret_fp = os::Linux::ucontext_get_fp(uc); 1.98 + } 1.99 + } else { 1.100 + // construct empty ExtendedPC for return value checking 1.101 + epc = ExtendedPC(NULL); 1.102 + if (ret_sp) { 1.103 + *ret_sp = (intptr_t*) NULL; 1.104 + } 1.105 + if (ret_fp) { 1.106 + *ret_fp = (intptr_t*) NULL; 1.107 + } 1.108 + } 1.109 + 1.110 + return epc; 1.111 +} 1.112 + 1.113 +frame os::fetch_frame_from_context(void* ucVoid) { 1.114 + intptr_t* sp; 1.115 + intptr_t* fp; 1.116 + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 1.117 + return frame(sp, fp, epc.pc()); 1.118 +} 1.119 + 1.120 +frame os::get_sender_for_C_frame(frame* fr) { 1.121 + return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); 1.122 +} 1.123 + 1.124 +frame os::current_frame() { 1.125 + fprintf(stderr, "current_frame()"); 1.126 + 1.127 + intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()(); 1.128 + frame myframe(sp, frame::unpatchable, 1.129 + CAST_FROM_FN_PTR(address, os::current_frame)); 1.130 + if (os::is_first_C_frame(&myframe)) { 1.131 + // stack is not walkable 1.132 + return frame(NULL, frame::unpatchable, NULL); 1.133 + } else { 1.134 + return os::get_sender_for_C_frame(&myframe); 1.135 + } 1.136 +} 1.137 + 1.138 +address os::current_stack_pointer() { 1.139 + register void *sp __asm__ ("sp"); 1.140 + return (address)sp; 1.141 +} 1.142 + 1.143 +static void current_stack_region(address* bottom, size_t* size) { 1.144 + if (os::Linux::is_initial_thread()) { 1.145 + // initial thread needs special handling because pthread_getattr_np() 1.146 + // may return bogus value. 1.147 + *bottom = os::Linux::initial_thread_stack_bottom(); 1.148 + *size = os::Linux::initial_thread_stack_size(); 1.149 + } else { 1.150 + pthread_attr_t attr; 1.151 + 1.152 + int rslt = pthread_getattr_np(pthread_self(), &attr); 1.153 + 1.154 + // JVM needs to know exact stack location, abort if it fails 1.155 + if (rslt != 0) { 1.156 + if (rslt == ENOMEM) { 1.157 + vm_exit_out_of_memory(0, "pthread_getattr_np"); 1.158 + } else { 1.159 + fatal1("pthread_getattr_np failed with errno = %d", rslt); 1.160 + } 1.161 + } 1.162 + 1.163 + if (pthread_attr_getstack(&attr, (void**)bottom, size) != 0) { 1.164 + fatal("Can not locate current stack attributes!"); 1.165 + } 1.166 + 1.167 + pthread_attr_destroy(&attr); 1.168 + } 1.169 + assert(os::current_stack_pointer() >= *bottom && 1.170 + os::current_stack_pointer() < *bottom + *size, "just checking"); 1.171 +} 1.172 + 1.173 +address os::current_stack_base() { 1.174 + address bottom; 1.175 + size_t size; 1.176 + current_stack_region(&bottom, &size); 1.177 + return bottom + size; 1.178 +} 1.179 + 1.180 +size_t os::current_stack_size() { 1.181 + // stack size includes normal stack and HotSpot guard pages 1.182 + address bottom; 1.183 + size_t size; 1.184 + current_stack_region(&bottom, &size); 1.185 + return size; 1.186 +} 1.187 + 1.188 +char* os::non_memory_address_word() { 1.189 + // Must never look like an address returned by reserve_memory, 1.190 + // even in its subfields (as defined by the CPU immediate fields, 1.191 + // if the CPU splits constants across multiple instructions). 1.192 + // On SPARC, 0 != %hi(any real address), because there is no 1.193 + // allocation in the first 1Kb of the virtual address space. 1.194 + return (char*) 0; 1.195 +} 1.196 + 1.197 +void os::initialize_thread() {} 1.198 + 1.199 +void os::print_context(outputStream *st, void *context) { 1.200 + if (context == NULL) return; 1.201 + 1.202 + ucontext_t* uc = (ucontext_t*)context; 1.203 + sigcontext* sc = (sigcontext*)context; 1.204 + st->print_cr("Registers:"); 1.205 + 1.206 + st->print_cr(" O0=" INTPTR_FORMAT " O1=" INTPTR_FORMAT 1.207 + " O2=" INTPTR_FORMAT " O3=" INTPTR_FORMAT, 1.208 + SIG_REGS(sc).u_regs[CON_O0], 1.209 + SIG_REGS(sc).u_regs[CON_O1], 1.210 + SIG_REGS(sc).u_regs[CON_O2], 1.211 + SIG_REGS(sc).u_regs[CON_O3]); 1.212 + st->print_cr(" O4=" INTPTR_FORMAT " O5=" INTPTR_FORMAT 1.213 + " O6=" INTPTR_FORMAT " O7=" INTPTR_FORMAT, 1.214 + SIG_REGS(sc).u_regs[CON_O4], 1.215 + SIG_REGS(sc).u_regs[CON_O5], 1.216 + SIG_REGS(sc).u_regs[CON_O6], 1.217 + SIG_REGS(sc).u_regs[CON_O7]); 1.218 + 1.219 + st->print_cr(" G1=" INTPTR_FORMAT " G2=" INTPTR_FORMAT 1.220 + " G3=" INTPTR_FORMAT " G4=" INTPTR_FORMAT, 1.221 + SIG_REGS(sc).u_regs[CON_G1], 1.222 + SIG_REGS(sc).u_regs[CON_G2], 1.223 + SIG_REGS(sc).u_regs[CON_G3], 1.224 + SIG_REGS(sc).u_regs[CON_G4]); 1.225 + st->print_cr(" G5=" INTPTR_FORMAT " G6=" INTPTR_FORMAT 1.226 + " G7=" INTPTR_FORMAT " Y=" INTPTR_FORMAT, 1.227 + SIG_REGS(sc).u_regs[CON_G5], 1.228 + SIG_REGS(sc).u_regs[CON_G6], 1.229 + SIG_REGS(sc).u_regs[CON_G7], 1.230 + SIG_REGS(sc).y); 1.231 + 1.232 + st->print_cr(" PC=" INTPTR_FORMAT " nPC=" INTPTR_FORMAT, 1.233 + SIG_PC(sc), 1.234 + SIG_NPC(sc)); 1.235 + st->cr(); 1.236 + st->cr(); 1.237 + 1.238 + intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc); 1.239 + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); 1.240 + print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t)); 1.241 + st->cr(); 1.242 + 1.243 + // Note: it may be unsafe to inspect memory near pc. For example, pc may 1.244 + // point to garbage if entry point in an nmethod is corrupted. Leave 1.245 + // this at the end, and hope for the best. 1.246 + address pc = os::Linux::ucontext_get_pc(uc); 1.247 + st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); 1.248 + print_hex_dump(st, pc - 16, pc + 16, sizeof(char)); 1.249 +} 1.250 + 1.251 + 1.252 +address os::Linux::ucontext_get_pc(ucontext_t* uc) { 1.253 + return (address) SIG_PC((sigcontext*)uc); 1.254 +} 1.255 + 1.256 +intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) { 1.257 + return (intptr_t*) 1.258 + ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS); 1.259 +} 1.260 + 1.261 +// not used on Sparc 1.262 +intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) { 1.263 + ShouldNotReachHere(); 1.264 + return NULL; 1.265 +} 1.266 + 1.267 +// Utility functions 1.268 + 1.269 +extern "C" void Fetch32PFI(); 1.270 +extern "C" void Fetch32Resume(); 1.271 +extern "C" void FetchNPFI(); 1.272 +extern "C" void FetchNResume(); 1.273 + 1.274 +inline static bool checkPrefetch(sigcontext* uc, address pc) { 1.275 + if (pc == (address) Fetch32PFI) { 1.276 + set_cont_address(uc, address(Fetch32Resume)); 1.277 + return true; 1.278 + } 1.279 + if (pc == (address) FetchNPFI) { 1.280 + set_cont_address(uc, address(FetchNResume)); 1.281 + return true; 1.282 + } 1.283 + return false; 1.284 +} 1.285 + 1.286 +inline static bool checkOverflow(sigcontext* uc, 1.287 + address pc, 1.288 + address addr, 1.289 + JavaThread* thread, 1.290 + address* stub) { 1.291 + // check if fault address is within thread stack 1.292 + if (addr < thread->stack_base() && 1.293 + addr >= thread->stack_base() - thread->stack_size()) { 1.294 + // stack overflow 1.295 + if (thread->in_stack_yellow_zone(addr)) { 1.296 + thread->disable_stack_yellow_zone(); 1.297 + if (thread->thread_state() == _thread_in_Java) { 1.298 + // Throw a stack overflow exception. Guard pages will be reenabled 1.299 + // while unwinding the stack. 1.300 + *stub = 1.301 + SharedRuntime::continuation_for_implicit_exception(thread, 1.302 + pc, 1.303 + SharedRuntime::STACK_OVERFLOW); 1.304 + } else { 1.305 + // Thread was in the vm or native code. Return and try to finish. 1.306 + return true; 1.307 + } 1.308 + } else if (thread->in_stack_red_zone(addr)) { 1.309 + // Fatal red zone violation. Disable the guard pages and fall through 1.310 + // to handle_unexpected_exception way down below. 1.311 + thread->disable_stack_red_zone(); 1.312 + tty->print_raw_cr("An irrecoverable stack overflow has occurred."); 1.313 + } else { 1.314 + // Accessing stack address below sp may cause SEGV if current 1.315 + // thread has MAP_GROWSDOWN stack. This should only happen when 1.316 + // current thread was created by user code with MAP_GROWSDOWN flag 1.317 + // and then attached to VM. See notes in os_linux.cpp. 1.318 + if (thread->osthread()->expanding_stack() == 0) { 1.319 + thread->osthread()->set_expanding_stack(); 1.320 + if (os::Linux::manually_expand_stack(thread, addr)) { 1.321 + thread->osthread()->clear_expanding_stack(); 1.322 + return true; 1.323 + } 1.324 + thread->osthread()->clear_expanding_stack(); 1.325 + } else { 1.326 + fatal("recursive segv. expanding stack."); 1.327 + } 1.328 + } 1.329 + } 1.330 + return false; 1.331 +} 1.332 + 1.333 +inline static bool checkPollingPage(address pc, address fault, address* stub) { 1.334 + if (fault == os::get_polling_page()) { 1.335 + *stub = SharedRuntime::get_poll_stub(pc); 1.336 + return true; 1.337 + } 1.338 + return false; 1.339 +} 1.340 + 1.341 +inline static bool checkByteBuffer(address pc, address* stub) { 1.342 + // BugId 4454115: A read from a MappedByteBuffer can fault 1.343 + // here if the underlying file has been truncated. 1.344 + // Do not crash the VM in such a case. 1.345 + CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 1.346 + nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 1.347 + if (nm != NULL && nm->has_unsafe_access()) { 1.348 + *stub = StubRoutines::handler_for_unsafe_access(); 1.349 + return true; 1.350 + } 1.351 + return false; 1.352 +} 1.353 + 1.354 +inline static bool checkVerifyOops(address pc, address fault, address* stub) { 1.355 + if (pc >= MacroAssembler::_verify_oop_implicit_branch[0] 1.356 + && pc < MacroAssembler::_verify_oop_implicit_branch[1] ) { 1.357 + *stub = MacroAssembler::_verify_oop_implicit_branch[2]; 1.358 + warning("fixed up memory fault in +VerifyOops at address " 1.359 + INTPTR_FORMAT, fault); 1.360 + return true; 1.361 + } 1.362 + return false; 1.363 +} 1.364 + 1.365 +inline static bool checkFPFault(address pc, int code, 1.366 + JavaThread* thread, address* stub) { 1.367 + if (code == FPE_INTDIV || code == FPE_FLTDIV) { 1.368 + *stub = 1.369 + SharedRuntime:: 1.370 + continuation_for_implicit_exception(thread, 1.371 + pc, 1.372 + SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 1.373 + return true; 1.374 + } 1.375 + return false; 1.376 +} 1.377 + 1.378 +inline static bool checkNullPointer(address pc, intptr_t fault, 1.379 + JavaThread* thread, address* stub) { 1.380 + if (!MacroAssembler::needs_explicit_null_check(fault)) { 1.381 + // Determination of interpreter/vtable stub/compiled code null 1.382 + // exception 1.383 + *stub = 1.384 + SharedRuntime:: 1.385 + continuation_for_implicit_exception(thread, pc, 1.386 + SharedRuntime::IMPLICIT_NULL); 1.387 + return true; 1.388 + } 1.389 + return false; 1.390 +} 1.391 + 1.392 +inline static bool checkFastJNIAccess(address pc, address* stub) { 1.393 + address addr = JNI_FastGetField::find_slowcase_pc(pc); 1.394 + if (addr != (address)-1) { 1.395 + *stub = addr; 1.396 + return true; 1.397 + } 1.398 + return false; 1.399 +} 1.400 + 1.401 +inline static bool checkSerializePage(JavaThread* thread, address addr) { 1.402 + return os::is_memory_serialize_page(thread, addr); 1.403 +} 1.404 + 1.405 +inline static bool checkZombie(sigcontext* uc, address* pc, address* stub) { 1.406 + if (nativeInstruction_at(*pc)->is_zombie()) { 1.407 + // zombie method (ld [%g0],%o7 instruction) 1.408 + *stub = SharedRuntime::get_handle_wrong_method_stub(); 1.409 + 1.410 + // At the stub it needs to look like a call from the caller of this 1.411 + // method (not a call from the segv site). 1.412 + *pc = (address)SIG_REGS(uc).u_regs[CON_O7]; 1.413 + return true; 1.414 + } 1.415 + return false; 1.416 +} 1.417 + 1.418 +inline static bool checkICMiss(sigcontext* uc, address* pc, address* stub) { 1.419 +#ifdef COMPILER2 1.420 + if (nativeInstruction_at(*pc)->is_ic_miss_trap()) { 1.421 +#ifdef ASSERT 1.422 +#ifdef TIERED 1.423 + CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 1.424 + assert(cb->is_compiled_by_c2(), "Wrong compiler"); 1.425 +#endif // TIERED 1.426 +#endif // ASSERT 1.427 + // Inline cache missed and user trap "Tne G0+ST_RESERVED_FOR_USER_0+2" taken. 1.428 + *stub = SharedRuntime::get_ic_miss_stub(); 1.429 + // At the stub it needs to look like a call from the caller of this 1.430 + // method (not a call from the segv site). 1.431 + *pc = (address)SIG_REGS(uc).u_regs[CON_O7]; 1.432 + return true; 1.433 + } 1.434 +#endif // COMPILER2 1.435 + return false; 1.436 +} 1.437 + 1.438 +extern "C" int 1.439 +JVM_handle_linux_signal(int sig, 1.440 + siginfo_t* info, 1.441 + void* ucVoid, 1.442 + int abort_if_unrecognized) { 1.443 + // in fact this isn't ucontext_t* at all, but struct sigcontext* 1.444 + // but Linux porting layer uses ucontext_t, so to minimize code change 1.445 + // we cast as needed 1.446 + ucontext_t* ucFake = (ucontext_t*) ucVoid; 1.447 + sigcontext* uc = (sigcontext*)ucVoid; 1.448 + 1.449 + Thread* t = ThreadLocalStorage::get_thread_slow(); 1.450 + 1.451 + SignalHandlerMark shm(t); 1.452 + 1.453 + // Note: it's not uncommon that JNI code uses signal/sigset to install 1.454 + // then restore certain signal handler (e.g. to temporarily block SIGPIPE, 1.455 + // or have a SIGILL handler when detecting CPU type). When that happens, 1.456 + // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To 1.457 + // avoid unnecessary crash when libjsig is not preloaded, try handle signals 1.458 + // that do not require siginfo/ucontext first. 1.459 + 1.460 + if (sig == SIGPIPE || sig == SIGXFSZ) { 1.461 + // allow chained handler to go first 1.462 + if (os::Linux::chained_handler(sig, info, ucVoid)) { 1.463 + return true; 1.464 + } else { 1.465 + if (PrintMiscellaneous && (WizardMode || Verbose)) { 1.466 + char buf[64]; 1.467 + warning("Ignoring %s - see bugs 4229104 or 646499219", 1.468 + os::exception_name(sig, buf, sizeof(buf))); 1.469 + } 1.470 + return true; 1.471 + } 1.472 + } 1.473 + 1.474 + JavaThread* thread = NULL; 1.475 + VMThread* vmthread = NULL; 1.476 + if (os::Linux::signal_handlers_are_installed) { 1.477 + if (t != NULL ){ 1.478 + if(t->is_Java_thread()) { 1.479 + thread = (JavaThread*)t; 1.480 + } 1.481 + else if(t->is_VM_thread()){ 1.482 + vmthread = (VMThread *)t; 1.483 + } 1.484 + } 1.485 + } 1.486 + 1.487 + // decide if this trap can be handled by a stub 1.488 + address stub = NULL; 1.489 + address pc = NULL; 1.490 + address npc = NULL; 1.491 + 1.492 + //%note os_trap_1 1.493 + if (info != NULL && uc != NULL && thread != NULL) { 1.494 + pc = address(SIG_PC(uc)); 1.495 + npc = address(SIG_NPC(uc)); 1.496 + 1.497 + // Check to see if we caught the safepoint code in the 1.498 + // process of write protecting the memory serialization page. 1.499 + // It write enables the page immediately after protecting it 1.500 + // so we can just return to retry the write. 1.501 + if ((sig == SIGSEGV) && checkSerializePage(thread, (address)info->si_addr)) { 1.502 + // Block current thread until the memory serialize page permission restored. 1.503 + os::block_on_serialize_page_trap(); 1.504 + return 1; 1.505 + } 1.506 + 1.507 + if (checkPrefetch(uc, pc)) { 1.508 + return 1; 1.509 + } 1.510 + 1.511 + // Handle ALL stack overflow variations here 1.512 + if (sig == SIGSEGV) { 1.513 + if (checkOverflow(uc, pc, (address)info->si_addr, thread, &stub)) { 1.514 + return 1; 1.515 + } 1.516 + } 1.517 + 1.518 + if (sig == SIGBUS && 1.519 + thread->thread_state() == _thread_in_vm && 1.520 + thread->doing_unsafe_access()) { 1.521 + stub = StubRoutines::handler_for_unsafe_access(); 1.522 + } 1.523 + 1.524 + if (thread->thread_state() == _thread_in_Java) { 1.525 + do { 1.526 + // Java thread running in Java code => find exception handler if any 1.527 + // a fault inside compiled code, the interpreter, or a stub 1.528 + 1.529 + if ((sig == SIGSEGV) && checkPollingPage(pc, (address)info->si_addr, &stub)) { 1.530 + break; 1.531 + } 1.532 + 1.533 + if ((sig == SIGBUS) && checkByteBuffer(pc, &stub)) { 1.534 + break; 1.535 + } 1.536 + 1.537 + if ((sig == SIGSEGV || sig == SIGBUS) && 1.538 + checkVerifyOops(pc, (address)info->si_addr, &stub)) { 1.539 + break; 1.540 + } 1.541 + 1.542 + if ((sig == SIGSEGV) && checkZombie(uc, &pc, &stub)) { 1.543 + break; 1.544 + } 1.545 + 1.546 + if ((sig == SIGILL) && checkICMiss(uc, &pc, &stub)) { 1.547 + break; 1.548 + } 1.549 + 1.550 + if ((sig == SIGFPE) && checkFPFault(pc, info->si_code, thread, &stub)) { 1.551 + break; 1.552 + } 1.553 + 1.554 + if ((sig == SIGSEGV) && 1.555 + checkNullPointer(pc, (intptr_t)info->si_addr, thread, &stub)) { 1.556 + break; 1.557 + } 1.558 + } while (0); 1.559 + 1.560 + // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in 1.561 + // and the heap gets shrunk before the field access. 1.562 + if ((sig == SIGSEGV) || (sig == SIGBUS)) { 1.563 + checkFastJNIAccess(pc, &stub); 1.564 + } 1.565 + } 1.566 + 1.567 + if (stub != NULL) { 1.568 + // save all thread context in case we need to restore it 1.569 + thread->set_saved_exception_pc(pc); 1.570 + thread->set_saved_exception_npc(npc); 1.571 + set_cont_address(uc, stub); 1.572 + return true; 1.573 + } 1.574 + } 1.575 + 1.576 + // signal-chaining 1.577 + if (os::Linux::chained_handler(sig, info, ucVoid)) { 1.578 + return true; 1.579 + } 1.580 + 1.581 + if (!abort_if_unrecognized) { 1.582 + // caller wants another chance, so give it to him 1.583 + return false; 1.584 + } 1.585 + 1.586 + if (pc == NULL && uc != NULL) { 1.587 + pc = os::Linux::ucontext_get_pc((ucontext_t*)uc); 1.588 + } 1.589 + 1.590 + // unmask current signal 1.591 + sigset_t newset; 1.592 + sigemptyset(&newset); 1.593 + sigaddset(&newset, sig); 1.594 + sigprocmask(SIG_UNBLOCK, &newset, NULL); 1.595 + 1.596 + VMError err(t, sig, pc, info, ucVoid); 1.597 + err.report_and_die(); 1.598 + 1.599 + ShouldNotReachHere(); 1.600 +} 1.601 + 1.602 +void os::Linux::init_thread_fpu_state(void) { 1.603 + // Nothing to do 1.604 +} 1.605 + 1.606 +int os::Linux::get_fpu_control_word() { 1.607 + return 0; 1.608 +} 1.609 + 1.610 +void os::Linux::set_fpu_control_word(int fpu) { 1.611 + // nothing 1.612 +} 1.613 + 1.614 +bool os::is_allocatable(size_t bytes) { 1.615 +#ifdef _LP64 1.616 + return true; 1.617 +#else 1.618 + if (bytes < 2 * G) { 1.619 + return true; 1.620 + } 1.621 + 1.622 + char* addr = reserve_memory(bytes, NULL); 1.623 + 1.624 + if (addr != NULL) { 1.625 + release_memory(addr, bytes); 1.626 + } 1.627 + 1.628 + return addr != NULL; 1.629 +#endif // _LP64 1.630 +} 1.631 + 1.632 +/////////////////////////////////////////////////////////////////////////////// 1.633 +// thread stack 1.634 + 1.635 +size_t os::Linux::min_stack_allowed = 128 * K; 1.636 + 1.637 +// pthread on Ubuntu is always in floating stack mode 1.638 +bool os::Linux::supports_variable_stack_size() { return true; } 1.639 + 1.640 +// return default stack size for thr_type 1.641 +size_t os::Linux::default_stack_size(os::ThreadType thr_type) { 1.642 + // default stack size (compiler thread needs larger stack) 1.643 + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); 1.644 + return s; 1.645 +} 1.646 + 1.647 +size_t os::Linux::default_guard_size(os::ThreadType thr_type) { 1.648 + // Creating guard page is very expensive. Java thread has HotSpot 1.649 + // guard page, only enable glibc guard page for non-Java threads. 1.650 + return (thr_type == java_thread ? 0 : page_size()); 1.651 +}