1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,565 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright 2012, 2014 SAP AG. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +// no precompiled headers 1.30 +#include "assembler_ppc.inline.hpp" 1.31 +#include "classfile/classLoader.hpp" 1.32 +#include "classfile/systemDictionary.hpp" 1.33 +#include "classfile/vmSymbols.hpp" 1.34 +#include "code/icBuffer.hpp" 1.35 +#include "code/vtableStubs.hpp" 1.36 +#include "interpreter/interpreter.hpp" 1.37 +#include "jvm_aix.h" 1.38 +#include "memory/allocation.inline.hpp" 1.39 +#include "mutex_aix.inline.hpp" 1.40 +#include "nativeInst_ppc.hpp" 1.41 +#include "os_share_aix.hpp" 1.42 +#include "prims/jniFastGetField.hpp" 1.43 +#include "prims/jvm.h" 1.44 +#include "prims/jvm_misc.hpp" 1.45 +#include "runtime/arguments.hpp" 1.46 +#include "runtime/extendedPC.hpp" 1.47 +#include "runtime/frame.inline.hpp" 1.48 +#include "runtime/interfaceSupport.hpp" 1.49 +#include "runtime/java.hpp" 1.50 +#include "runtime/javaCalls.hpp" 1.51 +#include "runtime/mutexLocker.hpp" 1.52 +#include "runtime/osThread.hpp" 1.53 +#include "runtime/sharedRuntime.hpp" 1.54 +#include "runtime/stubRoutines.hpp" 1.55 +#include "runtime/thread.inline.hpp" 1.56 +#include "runtime/timer.hpp" 1.57 +#include "utilities/events.hpp" 1.58 +#include "utilities/vmError.hpp" 1.59 +#ifdef COMPILER1 1.60 +#include "c1/c1_Runtime1.hpp" 1.61 +#endif 1.62 +#ifdef COMPILER2 1.63 +#include "opto/runtime.hpp" 1.64 +#endif 1.65 + 1.66 +// put OS-includes here 1.67 +# include <ucontext.h> 1.68 + 1.69 +address os::current_stack_pointer() { 1.70 + address csp; 1.71 + 1.72 +#if !defined(USE_XLC_BUILTINS) 1.73 + // inline assembly for `mr regno(csp), R1_SP': 1.74 + __asm__ __volatile__ ("mr %0, 1":"=r"(csp):); 1.75 +#else 1.76 + csp = (address) __builtin_frame_address(0); 1.77 +#endif 1.78 + 1.79 + return csp; 1.80 +} 1.81 + 1.82 +char* os::non_memory_address_word() { 1.83 + // Must never look like an address returned by reserve_memory, 1.84 + // even in its subfields (as defined by the CPU immediate fields, 1.85 + // if the CPU splits constants across multiple instructions). 1.86 + 1.87 + return (char*) -1; 1.88 +} 1.89 + 1.90 +// OS specific thread initialization 1.91 +// 1.92 +// Calculate and store the limits of the memory stack. 1.93 +void os::initialize_thread(Thread *thread) { } 1.94 + 1.95 +// Frame information (pc, sp, fp) retrieved via ucontext 1.96 +// always looks like a C-frame according to the frame 1.97 +// conventions in frame_ppc64.hpp. 1.98 +address os::Aix::ucontext_get_pc(ucontext_t * uc) { 1.99 + return (address)uc->uc_mcontext.jmp_context.iar; 1.100 +} 1.101 + 1.102 +intptr_t* os::Aix::ucontext_get_sp(ucontext_t * uc) { 1.103 + // gpr1 holds the stack pointer on aix 1.104 + return (intptr_t*)uc->uc_mcontext.jmp_context.gpr[1/*REG_SP*/]; 1.105 +} 1.106 + 1.107 +intptr_t* os::Aix::ucontext_get_fp(ucontext_t * uc) { 1.108 + return NULL; 1.109 +} 1.110 + 1.111 +void os::Aix::ucontext_set_pc(ucontext_t* uc, address new_pc) { 1.112 + uc->uc_mcontext.jmp_context.iar = (uint64_t) new_pc; 1.113 +} 1.114 + 1.115 +ExtendedPC os::fetch_frame_from_context(void* ucVoid, 1.116 + intptr_t** ret_sp, intptr_t** ret_fp) { 1.117 + 1.118 + ExtendedPC epc; 1.119 + ucontext_t* uc = (ucontext_t*)ucVoid; 1.120 + 1.121 + if (uc != NULL) { 1.122 + epc = ExtendedPC(os::Aix::ucontext_get_pc(uc)); 1.123 + if (ret_sp) *ret_sp = os::Aix::ucontext_get_sp(uc); 1.124 + if (ret_fp) *ret_fp = os::Aix::ucontext_get_fp(uc); 1.125 + } else { 1.126 + // construct empty ExtendedPC for return value checking 1.127 + epc = ExtendedPC(NULL); 1.128 + if (ret_sp) *ret_sp = (intptr_t *)NULL; 1.129 + if (ret_fp) *ret_fp = (intptr_t *)NULL; 1.130 + } 1.131 + 1.132 + return epc; 1.133 +} 1.134 + 1.135 +frame os::fetch_frame_from_context(void* ucVoid) { 1.136 + intptr_t* sp; 1.137 + intptr_t* fp; 1.138 + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); 1.139 + // Avoid crash during crash if pc broken. 1.140 + if (epc.pc()) { 1.141 + frame fr(sp, epc.pc()); 1.142 + return fr; 1.143 + } 1.144 + frame fr(sp); 1.145 + return fr; 1.146 +} 1.147 + 1.148 +frame os::get_sender_for_C_frame(frame* fr) { 1.149 + if (*fr->sp() == NULL) { 1.150 + // fr is the last C frame 1.151 + return frame(NULL, NULL); 1.152 + } 1.153 + return frame(fr->sender_sp(), fr->sender_pc()); 1.154 +} 1.155 + 1.156 + 1.157 +frame os::current_frame() { 1.158 + intptr_t* csp = (intptr_t*) *((intptr_t*) os::current_stack_pointer()); 1.159 + // hack. 1.160 + frame topframe(csp, (address)0x8); 1.161 + // return sender of current topframe which hopefully has pc != NULL. 1.162 + return os::get_sender_for_C_frame(&topframe); 1.163 +} 1.164 + 1.165 +// Utility functions 1.166 + 1.167 +extern "C" JNIEXPORT int 1.168 +JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { 1.169 + 1.170 + ucontext_t* uc = (ucontext_t*) ucVoid; 1.171 + 1.172 + Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady 1.173 + 1.174 + SignalHandlerMark shm(t); 1.175 + 1.176 + // Note: it's not uncommon that JNI code uses signal/sigset to install 1.177 + // then restore certain signal handler (e.g. to temporarily block SIGPIPE, 1.178 + // or have a SIGILL handler when detecting CPU type). When that happens, 1.179 + // JVM_handle_aix_signal() might be invoked with junk info/ucVoid. To 1.180 + // avoid unnecessary crash when libjsig is not preloaded, try handle signals 1.181 + // that do not require siginfo/ucontext first. 1.182 + 1.183 + if (sig == SIGPIPE) { 1.184 + if (os::Aix::chained_handler(sig, info, ucVoid)) { 1.185 + return 1; 1.186 + } else { 1.187 + if (PrintMiscellaneous && (WizardMode || Verbose)) { 1.188 + warning("Ignoring SIGPIPE - see bug 4229104"); 1.189 + } 1.190 + return 1; 1.191 + } 1.192 + } 1.193 + 1.194 + JavaThread* thread = NULL; 1.195 + VMThread* vmthread = NULL; 1.196 + if (os::Aix::signal_handlers_are_installed) { 1.197 + if (t != NULL) { 1.198 + if(t->is_Java_thread()) { 1.199 + thread = (JavaThread*)t; 1.200 + } 1.201 + else if(t->is_VM_thread()) { 1.202 + vmthread = (VMThread *)t; 1.203 + } 1.204 + } 1.205 + } 1.206 + 1.207 + // Decide if this trap can be handled by a stub. 1.208 + address stub = NULL; 1.209 + 1.210 + // retrieve program counter 1.211 + address const pc = uc ? os::Aix::ucontext_get_pc(uc) : NULL; 1.212 + 1.213 + // retrieve crash address 1.214 + address const addr = info ? (const address) info->si_addr : NULL; 1.215 + 1.216 + // SafeFetch 32 handling: 1.217 + // - make it work if _thread is null 1.218 + // - make it use the standard os::...::ucontext_get/set_pc APIs 1.219 + if (uc) { 1.220 + address const pc = os::Aix::ucontext_get_pc(uc); 1.221 + if (pc && StubRoutines::is_safefetch_fault(pc)) { 1.222 + os::Aix::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc)); 1.223 + return true; 1.224 + } 1.225 + } 1.226 + 1.227 + // Handle SIGDANGER right away. AIX would raise SIGDANGER whenever available swap 1.228 + // space falls below 30%. This is only a chance for the process to gracefully abort. 1.229 + // We can't hope to proceed after SIGDANGER since SIGKILL tailgates. 1.230 + if (sig == SIGDANGER) { 1.231 + goto report_and_die; 1.232 + } 1.233 + 1.234 + if (info == NULL || uc == NULL || thread == NULL && vmthread == NULL) { 1.235 + goto run_chained_handler; 1.236 + } 1.237 + 1.238 + // If we are a java thread... 1.239 + if (thread != NULL) { 1.240 + 1.241 + // Handle ALL stack overflow variations here 1.242 + if (sig == SIGSEGV && (addr < thread->stack_base() && 1.243 + addr >= thread->stack_base() - thread->stack_size())) { 1.244 + // stack overflow 1.245 + // 1.246 + // If we are in a yellow zone and we are inside java, we disable the yellow zone and 1.247 + // throw a stack overflow exception. 1.248 + // If we are in native code or VM C code, we report-and-die. The original coding tried 1.249 + // to continue with yellow zone disabled, but that doesn't buy us much and prevents 1.250 + // hs_err_pid files. 1.251 + if (thread->in_stack_yellow_zone(addr)) { 1.252 + thread->disable_stack_yellow_zone(); 1.253 + if (thread->thread_state() == _thread_in_Java) { 1.254 + // Throw a stack overflow exception. 1.255 + // Guard pages will be reenabled while unwinding the stack. 1.256 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); 1.257 + goto run_stub; 1.258 + } else { 1.259 + // Thread was in the vm or native code. Return and try to finish. 1.260 + return 1; 1.261 + } 1.262 + } else if (thread->in_stack_red_zone(addr)) { 1.263 + // Fatal red zone violation. Disable the guard pages and fall through 1.264 + // to handle_unexpected_exception way down below. 1.265 + thread->disable_stack_red_zone(); 1.266 + tty->print_raw_cr("An irrecoverable stack overflow has occurred."); 1.267 + goto report_and_die; 1.268 + } else { 1.269 + // This means a segv happened inside our stack, but not in 1.270 + // the guarded zone. I'd like to know when this happens, 1.271 + tty->print_raw_cr("SIGSEGV happened inside stack but outside yellow and red zone."); 1.272 + goto report_and_die; 1.273 + } 1.274 + 1.275 + } // end handle SIGSEGV inside stack boundaries 1.276 + 1.277 + if (thread->thread_state() == _thread_in_Java) { 1.278 + // Java thread running in Java code 1.279 + 1.280 + // The following signals are used for communicating VM events: 1.281 + // 1.282 + // SIGILL: the compiler generates illegal opcodes 1.283 + // at places where it wishes to interrupt the VM: 1.284 + // Safepoints, Unreachable Code, Entry points of Zombie methods, 1.285 + // This results in a SIGILL with (*pc) == inserted illegal instruction. 1.286 + // 1.287 + // (so, SIGILLs with a pc inside the zero page are real errors) 1.288 + // 1.289 + // SIGTRAP: 1.290 + // The ppc trap instruction raises a SIGTRAP and is very efficient if it 1.291 + // does not trap. It is used for conditional branches that are expected 1.292 + // to be never taken. These are: 1.293 + // - zombie methods 1.294 + // - IC (inline cache) misses. 1.295 + // - null checks leading to UncommonTraps. 1.296 + // - range checks leading to Uncommon Traps. 1.297 + // On Aix, these are especially null checks, as the ImplicitNullCheck 1.298 + // optimization works only in rare cases, as the page at address 0 is only 1.299 + // write protected. // 1.300 + // Note: !UseSIGTRAP is used to prevent SIGTRAPS altogether, to facilitate debugging. 1.301 + // 1.302 + // SIGSEGV: 1.303 + // used for safe point polling: 1.304 + // To notify all threads that they have to reach a safe point, safe point polling is used: 1.305 + // All threads poll a certain mapped memory page. Normally, this page has read access. 1.306 + // If the VM wants to inform the threads about impending safe points, it puts this 1.307 + // page to read only ("poisens" the page), and the threads then reach a safe point. 1.308 + // used for null checks: 1.309 + // If the compiler finds a store it uses it for a null check. Unfortunately this 1.310 + // happens rarely. In heap based and disjoint base compressd oop modes also loads 1.311 + // are used for null checks. 1.312 + 1.313 + // A VM-related SIGILL may only occur if we are not in the zero page. 1.314 + // On AIX, we get a SIGILL if we jump to 0x0 or to somewhere else 1.315 + // in the zero page, because it is filled with 0x0. We ignore 1.316 + // explicit SIGILLs in the zero page. 1.317 + if (sig == SIGILL && (pc < (address) 0x200)) { 1.318 + if (TraceTraps) { 1.319 + tty->print_raw_cr("SIGILL happened inside zero page."); 1.320 + } 1.321 + goto report_and_die; 1.322 + } 1.323 + 1.324 + // Handle signal from NativeJump::patch_verified_entry(). 1.325 + if (( TrapBasedNotEntrantChecks && sig == SIGTRAP && nativeInstruction_at(pc)->is_sigtrap_zombie_not_entrant()) || 1.326 + (!TrapBasedNotEntrantChecks && sig == SIGILL && nativeInstruction_at(pc)->is_sigill_zombie_not_entrant())) { 1.327 + if (TraceTraps) { 1.328 + tty->print_cr("trap: zombie_not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL"); 1.329 + } 1.330 + stub = SharedRuntime::get_handle_wrong_method_stub(); 1.331 + goto run_stub; 1.332 + } 1.333 + 1.334 + else if (sig == SIGSEGV && os::is_poll_address(addr)) { 1.335 + if (TraceTraps) { 1.336 + tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", pc); 1.337 + } 1.338 + stub = SharedRuntime::get_poll_stub(pc); 1.339 + goto run_stub; 1.340 + } 1.341 + 1.342 + // SIGTRAP-based ic miss check in compiled code. 1.343 + else if (sig == SIGTRAP && TrapBasedICMissChecks && 1.344 + nativeInstruction_at(pc)->is_sigtrap_ic_miss_check()) { 1.345 + if (TraceTraps) { 1.346 + tty->print_cr("trap: ic_miss_check at " INTPTR_FORMAT " (SIGTRAP)", pc); 1.347 + } 1.348 + stub = SharedRuntime::get_ic_miss_stub(); 1.349 + goto run_stub; 1.350 + } 1.351 + 1.352 + // SIGTRAP-based implicit null check in compiled code. 1.353 + else if (sig == SIGTRAP && TrapBasedNullChecks && 1.354 + nativeInstruction_at(pc)->is_sigtrap_null_check()) { 1.355 + if (TraceTraps) { 1.356 + tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGTRAP)", pc); 1.357 + } 1.358 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 1.359 + goto run_stub; 1.360 + } 1.361 + 1.362 + // SIGSEGV-based implicit null check in compiled code. 1.363 + else if (sig == SIGSEGV && ImplicitNullChecks && 1.364 + CodeCache::contains((void*) pc) && 1.365 + !MacroAssembler::needs_explicit_null_check((intptr_t) info->si_addr)) { 1.366 + if (TraceTraps) { 1.367 + tty->print_cr("trap: null_check at " INTPTR_FORMAT " (SIGSEGV)", pc); 1.368 + } 1.369 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 1.370 + } 1.371 + 1.372 +#ifdef COMPILER2 1.373 + // SIGTRAP-based implicit range check in compiled code. 1.374 + else if (sig == SIGTRAP && TrapBasedRangeChecks && 1.375 + nativeInstruction_at(pc)->is_sigtrap_range_check()) { 1.376 + if (TraceTraps) { 1.377 + tty->print_cr("trap: range_check at " INTPTR_FORMAT " (SIGTRAP)", pc); 1.378 + } 1.379 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 1.380 + goto run_stub; 1.381 + } 1.382 +#endif 1.383 + 1.384 + else if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) { 1.385 + if (TraceTraps) { 1.386 + tty->print_raw_cr("Fix SIGFPE handler, trying divide by zero handler."); 1.387 + } 1.388 + stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); 1.389 + goto run_stub; 1.390 + } 1.391 + 1.392 + else if (sig == SIGBUS) { 1.393 + // BugId 4454115: A read from a MappedByteBuffer can fault here if the 1.394 + // underlying file has been truncated. Do not crash the VM in such a case. 1.395 + CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 1.396 + nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 1.397 + if (nm != NULL && nm->has_unsafe_access()) { 1.398 + // We don't really need a stub here! Just set the pending exeption and 1.399 + // continue at the next instruction after the faulting read. Returning 1.400 + // garbage from this read is ok. 1.401 + thread->set_pending_unsafe_access_error(); 1.402 + uc->uc_mcontext.jmp_context.iar = ((unsigned long)pc) + 4; 1.403 + return 1; 1.404 + } 1.405 + } 1.406 + } 1.407 + 1.408 + else { // thread->thread_state() != _thread_in_Java 1.409 + // Detect CPU features. This is only done at the very start of the VM. Later, the 1.410 + // VM_Version::is_determine_features_test_running() flag should be false. 1.411 + 1.412 + if (sig == SIGILL && VM_Version::is_determine_features_test_running()) { 1.413 + // SIGILL must be caused by VM_Version::determine_features(). 1.414 + *(int *)pc = 0; // patch instruction to 0 to indicate that it causes a SIGILL, 1.415 + // flushing of icache is not necessary. 1.416 + stub = pc + 4; // continue with next instruction. 1.417 + goto run_stub; 1.418 + } 1.419 + else if (thread->thread_state() == _thread_in_vm && 1.420 + sig == SIGBUS && thread->doing_unsafe_access()) { 1.421 + // We don't really need a stub here! Just set the pending exeption and 1.422 + // continue at the next instruction after the faulting read. Returning 1.423 + // garbage from this read is ok. 1.424 + thread->set_pending_unsafe_access_error(); 1.425 + uc->uc_mcontext.jmp_context.iar = ((unsigned long)pc) + 4; 1.426 + return 1; 1.427 + } 1.428 + } 1.429 + 1.430 + // Check to see if we caught the safepoint code in the 1.431 + // process of write protecting the memory serialization page. 1.432 + // It write enables the page immediately after protecting it 1.433 + // so we can just return to retry the write. 1.434 + if ((sig == SIGSEGV) && 1.435 + os::is_memory_serialize_page(thread, addr)) { 1.436 + // Synchronization problem in the pseudo memory barrier code (bug id 6546278) 1.437 + // Block current thread until the memory serialize page permission restored. 1.438 + os::block_on_serialize_page_trap(); 1.439 + return true; 1.440 + } 1.441 + } 1.442 + 1.443 +run_stub: 1.444 + 1.445 + // One of the above code blocks ininitalized the stub, so we want to 1.446 + // delegate control to that stub. 1.447 + if (stub != NULL) { 1.448 + // Save all thread context in case we need to restore it. 1.449 + if (thread != NULL) thread->set_saved_exception_pc(pc); 1.450 + uc->uc_mcontext.jmp_context.iar = (unsigned long)stub; 1.451 + return 1; 1.452 + } 1.453 + 1.454 +run_chained_handler: 1.455 + 1.456 + // signal-chaining 1.457 + if (os::Aix::chained_handler(sig, info, ucVoid)) { 1.458 + return 1; 1.459 + } 1.460 + if (!abort_if_unrecognized) { 1.461 + // caller wants another chance, so give it to him 1.462 + return 0; 1.463 + } 1.464 + 1.465 +report_and_die: 1.466 + 1.467 + // Use sigthreadmask instead of sigprocmask on AIX and unmask current signal. 1.468 + sigset_t newset; 1.469 + sigemptyset(&newset); 1.470 + sigaddset(&newset, sig); 1.471 + sigthreadmask(SIG_UNBLOCK, &newset, NULL); 1.472 + 1.473 + VMError err(t, sig, pc, info, ucVoid); 1.474 + err.report_and_die(); 1.475 + 1.476 + ShouldNotReachHere(); 1.477 + return 0; 1.478 +} 1.479 + 1.480 +void os::Aix::init_thread_fpu_state(void) { 1.481 +#if !defined(USE_XLC_BUILTINS) 1.482 + // Disable FP exceptions. 1.483 + __asm__ __volatile__ ("mtfsfi 6,0"); 1.484 +#else 1.485 + __mtfsfi(6, 0); 1.486 +#endif 1.487 +} 1.488 + 1.489 +//////////////////////////////////////////////////////////////////////////////// 1.490 +// thread stack 1.491 + 1.492 +size_t os::Aix::min_stack_allowed = 768*K; 1.493 + 1.494 +// Aix is always in floating stack mode. The stack size for a new 1.495 +// thread can be set via pthread_attr_setstacksize(). 1.496 +bool os::Aix::supports_variable_stack_size() { return true; } 1.497 + 1.498 +// return default stack size for thr_type 1.499 +size_t os::Aix::default_stack_size(os::ThreadType thr_type) { 1.500 + // default stack size (compiler thread needs larger stack) 1.501 + // Notice that the setting for compiler threads here have no impact 1.502 + // because of the strange 'fallback logic' in os::create_thread(). 1.503 + // Better set CompilerThreadStackSize in globals_<os_cpu>.hpp if you want to 1.504 + // specify a different stack size for compiler threads! 1.505 + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K); 1.506 + return s; 1.507 +} 1.508 + 1.509 +size_t os::Aix::default_guard_size(os::ThreadType thr_type) { 1.510 + return 2 * page_size(); 1.511 +} 1.512 + 1.513 +///////////////////////////////////////////////////////////////////////////// 1.514 +// helper functions for fatal error handler 1.515 + 1.516 +void os::print_context(outputStream *st, void *context) { 1.517 + if (context == NULL) return; 1.518 + 1.519 + ucontext_t* uc = (ucontext_t*)context; 1.520 + 1.521 + st->print_cr("Registers:"); 1.522 + st->print("pc =" INTPTR_FORMAT " ", uc->uc_mcontext.jmp_context.iar); 1.523 + st->print("lr =" INTPTR_FORMAT " ", uc->uc_mcontext.jmp_context.lr); 1.524 + st->print("ctr=" INTPTR_FORMAT " ", uc->uc_mcontext.jmp_context.ctr); 1.525 + st->cr(); 1.526 + for (int i = 0; i < 32; i++) { 1.527 + st->print("r%-2d=" INTPTR_FORMAT " ", i, uc->uc_mcontext.jmp_context.gpr[i]); 1.528 + if (i % 3 == 2) st->cr(); 1.529 + } 1.530 + st->cr(); 1.531 + st->cr(); 1.532 + 1.533 + intptr_t *sp = (intptr_t *)os::Aix::ucontext_get_sp(uc); 1.534 + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); 1.535 + print_hex_dump(st, (address)sp, (address)(sp + 128), sizeof(intptr_t)); 1.536 + st->cr(); 1.537 + 1.538 + // Note: it may be unsafe to inspect memory near pc. For example, pc may 1.539 + // point to garbage if entry point in an nmethod is corrupted. Leave 1.540 + // this at the end, and hope for the best. 1.541 + address pc = os::Aix::ucontext_get_pc(uc); 1.542 + st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); 1.543 + print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4); 1.544 + st->cr(); 1.545 + 1.546 + // Try to decode the instructions. 1.547 + st->print_cr("Decoded instructions: (pc=" PTR_FORMAT ")", pc); 1.548 + st->print("<TODO: PPC port - print_context>"); 1.549 + // TODO: PPC port Disassembler::decode(pc, 16, 16, st); 1.550 + st->cr(); 1.551 +} 1.552 + 1.553 +void os::print_register_info(outputStream *st, void *context) { 1.554 + if (context == NULL) return; 1.555 + st->print("Not ported - print_register_info\n"); 1.556 +} 1.557 + 1.558 +extern "C" { 1.559 + int SpinPause() { 1.560 + return 0; 1.561 + } 1.562 +} 1.563 + 1.564 +#ifndef PRODUCT 1.565 +void os::verify_stack_alignment() { 1.566 + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); 1.567 +} 1.568 +#endif