src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Tue Sep 13 12:29:08 2011
--- new/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Tue Sep 13 12:29:08 2011
*** 28,42 ****
--- 28,42 ----
#include "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/icBuffer.hpp"
#include "code/vtableStubs.hpp"
#include "interpreter/interpreter.hpp"
! #include "jvm_linux.h"
! #include "jvm_bsd.h"
#include "memory/allocation.inline.hpp"
! #include "mutex_linux.inline.hpp"
! #include "mutex_bsd.inline.hpp"
#include "nativeInst_x86.hpp"
! #include "os_share_linux.hpp"
! #include "os_share_bsd.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/extendedPC.hpp"
*** 47,57 ****
--- 47,57 ----
#include "runtime/mutexLocker.hpp"
#include "runtime/osThread.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/timer.hpp"
! #include "thread_linux.inline.hpp"
! #include "thread_bsd.inline.hpp"
#include "utilities/events.hpp"
#include "utilities/vmError.hpp"
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
*** 76,102 ****
--- 76,281 ----
# include <sys/utsname.h>
# include <sys/socket.h>
# include <sys/wait.h>
# include <pwd.h>
# include <poll.h>
+ #ifndef __OpenBSD__
# include <ucontext.h>
# include <fpu_control.h>
+ #endif
+ #if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
+ # include <pthread_np.h>
+ #endif
+
#ifdef AMD64
#define REG_SP REG_RSP
#define REG_PC REG_RIP
#define REG_FP REG_RBP
#define SPELL_REG_SP "rsp"
#define SPELL_REG_FP "rbp"
#else
#define REG_SP REG_UESP
#define REG_PC REG_EIP
#define REG_FP REG_EBP
#define SPELL_REG_SP "esp"
#define SPELL_REG_FP "ebp"
#endif // AMD64
+ #ifdef __FreeBSD__
+ # define context_trapno uc_mcontext.mc_trapno
+ # ifdef AMD64
+ # define context_pc uc_mcontext.mc_rip
+ # define context_sp uc_mcontext.mc_rsp
+ # define context_fp uc_mcontext.mc_rbp
+ # define context_rip uc_mcontext.mc_rip
+ # define context_rsp uc_mcontext.mc_rsp
+ # define context_rbp uc_mcontext.mc_rbp
+ # define context_rax uc_mcontext.mc_rax
+ # define context_rbx uc_mcontext.mc_rbx
+ # define context_rcx uc_mcontext.mc_rcx
+ # define context_rdx uc_mcontext.mc_rdx
+ # define context_rsi uc_mcontext.mc_rsi
+ # define context_rdi uc_mcontext.mc_rdi
+ # define context_r8 uc_mcontext.mc_r8
+ # define context_r9 uc_mcontext.mc_r9
+ # define context_r10 uc_mcontext.mc_r10
+ # define context_r11 uc_mcontext.mc_r11
+ # define context_r12 uc_mcontext.mc_r12
+ # define context_r13 uc_mcontext.mc_r13
+ # define context_r14 uc_mcontext.mc_r14
+ # define context_r15 uc_mcontext.mc_r15
+ # define context_flags uc_mcontext.mc_flags
+ # define context_err uc_mcontext.mc_err
+ # else
+ # define context_pc uc_mcontext.mc_eip
+ # define context_sp uc_mcontext.mc_esp
+ # define context_fp uc_mcontext.mc_ebp
+ # define context_eip uc_mcontext.mc_eip
+ # define context_esp uc_mcontext.mc_esp
+ # define context_eax uc_mcontext.mc_eax
+ # define context_ebx uc_mcontext.mc_ebx
+ # define context_ecx uc_mcontext.mc_ecx
+ # define context_edx uc_mcontext.mc_edx
+ # define context_ebp uc_mcontext.mc_ebp
+ # define context_esi uc_mcontext.mc_esi
+ # define context_edi uc_mcontext.mc_edi
+ # define context_eflags uc_mcontext.mc_eflags
+ # define context_trapno uc_mcontext.mc_trapno
+ # endif
+ #endif
+
+ #ifdef __APPLE__
+ # if __DARWIN_UNIX03 && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ // 10.5 UNIX03 member name prefixes
+ #define DU3_PREFIX(s, m) __ ## s.__ ## m
+ # else
+ #define DU3_PREFIX(s, m) s ## . ## m
+ # endif
+
+ # ifdef AMD64
+ # define context_pc context_rip
+ # define context_sp context_rsp
+ # define context_fp context_rbp
+ # define context_rip uc_mcontext->DU3_PREFIX(ss,rip)
+ # define context_rsp uc_mcontext->DU3_PREFIX(ss,rsp)
+ # define context_rax uc_mcontext->DU3_PREFIX(ss,rax)
+ # define context_rbx uc_mcontext->DU3_PREFIX(ss,rbx)
+ # define context_rcx uc_mcontext->DU3_PREFIX(ss,rcx)
+ # define context_rdx uc_mcontext->DU3_PREFIX(ss,rdx)
+ # define context_rbp uc_mcontext->DU3_PREFIX(ss,rbp)
+ # define context_rsi uc_mcontext->DU3_PREFIX(ss,rsi)
+ # define context_rdi uc_mcontext->DU3_PREFIX(ss,rdi)
+ # define context_r8 uc_mcontext->DU3_PREFIX(ss,r8)
+ # define context_r9 uc_mcontext->DU3_PREFIX(ss,r9)
+ # define context_r10 uc_mcontext->DU3_PREFIX(ss,r10)
+ # define context_r11 uc_mcontext->DU3_PREFIX(ss,r11)
+ # define context_r12 uc_mcontext->DU3_PREFIX(ss,r12)
+ # define context_r13 uc_mcontext->DU3_PREFIX(ss,r13)
+ # define context_r14 uc_mcontext->DU3_PREFIX(ss,r14)
+ # define context_r15 uc_mcontext->DU3_PREFIX(ss,r15)
+ # define context_flags uc_mcontext->DU3_PREFIX(ss,rflags)
+ # define context_trapno uc_mcontext->DU3_PREFIX(es,trapno)
+ # define context_err uc_mcontext->DU3_PREFIX(es,err)
+ # else
+ # define context_pc context_eip
+ # define context_sp context_esp
+ # define context_fp context_ebp
+ # define context_eip uc_mcontext->DU3_PREFIX(ss,eip)
+ # define context_esp uc_mcontext->DU3_PREFIX(ss,esp)
+ # define context_eax uc_mcontext->DU3_PREFIX(ss,eax)
+ # define context_ebx uc_mcontext->DU3_PREFIX(ss,ebx)
+ # define context_ecx uc_mcontext->DU3_PREFIX(ss,ecx)
+ # define context_edx uc_mcontext->DU3_PREFIX(ss,edx)
+ # define context_ebp uc_mcontext->DU3_PREFIX(ss,ebp)
+ # define context_esi uc_mcontext->DU3_PREFIX(ss,esi)
+ # define context_edi uc_mcontext->DU3_PREFIX(ss,edi)
+ # define context_eflags uc_mcontext->DU3_PREFIX(ss,eflags)
+ # define context_trapno uc_mcontext->DU3_PREFIX(es,trapno)
+ # endif
+ #endif
+
+ #ifdef __OpenBSD__
+ # define context_trapno sc_trapno
+ # ifdef AMD64
+ # define context_pc sc_rip
+ # define context_sp sc_rsp
+ # define context_fp sc_rbp
+ # define context_rip sc_rip
+ # define context_rsp sc_rsp
+ # define context_rbp sc_rbp
+ # define context_rax sc_rax
+ # define context_rbx sc_rbx
+ # define context_rcx sc_rcx
+ # define context_rdx sc_rdx
+ # define context_rsi sc_rsi
+ # define context_rdi sc_rdi
+ # define context_r8 sc_r8
+ # define context_r9 sc_r9
+ # define context_r10 sc_r10
+ # define context_r11 sc_r11
+ # define context_r12 sc_r12
+ # define context_r13 sc_r13
+ # define context_r14 sc_r14
+ # define context_r15 sc_r15
+ # define context_flags sc_rflags
+ # define context_err sc_err
+ # else
+ # define context_pc sc_eip
+ # define context_sp sc_esp
+ # define context_fp sc_ebp
+ # define context_eip sc_eip
+ # define context_esp sc_esp
+ # define context_eax sc_eax
+ # define context_ebx sc_ebx
+ # define context_ecx sc_ecx
+ # define context_edx sc_edx
+ # define context_ebp sc_ebp
+ # define context_esi sc_esi
+ # define context_edi sc_edi
+ # define context_eflags sc_eflags
+ # define context_trapno sc_trapno
+ # endif
+ #endif
+
+ #ifdef __NetBSD__
+ # define context_trapno uc_mcontext.__gregs[_REG_TRAPNO]
+ # ifdef AMD64
+ # define __register_t __greg_t
+ # define context_pc uc_mcontext.__gregs[_REG_RIP]
+ # define context_sp uc_mcontext.__gregs[_REG_URSP]
+ # define context_fp uc_mcontext.__gregs[_REG_RBP]
+ # define context_rip uc_mcontext.__gregs[_REG_RIP]
+ # define context_rsp uc_mcontext.__gregs[_REG_URSP]
+ # define context_rax uc_mcontext.__gregs[_REG_RAX]
+ # define context_rbx uc_mcontext.__gregs[_REG_RBX]
+ # define context_rcx uc_mcontext.__gregs[_REG_RCX]
+ # define context_rdx uc_mcontext.__gregs[_REG_RDX]
+ # define context_rbp uc_mcontext.__gregs[_REG_RBP]
+ # define context_rsi uc_mcontext.__gregs[_REG_RSI]
+ # define context_rdi uc_mcontext.__gregs[_REG_RDI]
+ # define context_r8 uc_mcontext.__gregs[_REG_R8]
+ # define context_r9 uc_mcontext.__gregs[_REG_R9]
+ # define context_r10 uc_mcontext.__gregs[_REG_R10]
+ # define context_r11 uc_mcontext.__gregs[_REG_R11]
+ # define context_r12 uc_mcontext.__gregs[_REG_R12]
+ # define context_r13 uc_mcontext.__gregs[_REG_R13]
+ # define context_r14 uc_mcontext.__gregs[_REG_R14]
+ # define context_r15 uc_mcontext.__gregs[_REG_R15]
+ # define context_flags uc_mcontext.__gregs[_REG_RFL]
+ # define context_err uc_mcontext.__gregs[_REG_ERR]
+ # else
+ # define context_pc uc_mcontext.__gregs[_REG_EIP]
+ # define context_sp uc_mcontext.__gregs[_REG_UESP]
+ # define context_fp uc_mcontext.__gregs[_REG_EBP]
+ # define context_eip uc_mcontext.__gregs[_REG_EIP]
+ # define context_esp uc_mcontext.__gregs[_REG_UESP]
+ # define context_eax uc_mcontext.__gregs[_REG_EAX]
+ # define context_ebx uc_mcontext.__gregs[_REG_EBX]
+ # define context_ecx uc_mcontext.__gregs[_REG_ECX]
+ # define context_edx uc_mcontext.__gregs[_REG_EDX]
+ # define context_ebp uc_mcontext.__gregs[_REG_EBP]
+ # define context_esi uc_mcontext.__gregs[_REG_ESI]
+ # define context_edi uc_mcontext.__gregs[_REG_EDI]
+ # define context_eflags uc_mcontext.__gregs[_REG_EFL]
+ # define context_trapno uc_mcontext.__gregs[_REG_TRAPNO]
+ # endif
+ #endif
+
address os::current_stack_pointer() {
#ifdef SPARC_WORKS
register void *esp;
__asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
return (address) ((char*)esp + sizeof(long)*2);
*** 116,143 ****
--- 295,322 ----
void os::initialize_thread() {
// Nothing to do.
}
! address os::Linux::ucontext_get_pc(ucontext_t * uc) {
! return (address)uc->uc_mcontext.gregs[REG_PC];
! address os::Bsd::ucontext_get_pc(ucontext_t * uc) {
! return (address)uc->context_pc;
}
! intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
! return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
! intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) {
! return (intptr_t*)uc->context_sp;
}
! intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
! return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
! intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) {
! return (intptr_t*)uc->context_fp;
}
// For Forte Analyzer AsyncGetCallTrace profiling support - thread
// is currently interrupted by SIGPROF.
// os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
! // frames. Currently we don't do that on Linux, so it's the same as
! // frames. Currently we don't do that on Bsd, so it's the same as
// os::fetch_frame_from_context().
! ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
! ExtendedPC os::Bsd::fetch_frame_from_ucontext(Thread* thread,
ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
assert(thread != NULL, "just checking");
assert(ret_sp != NULL, "just checking");
assert(ret_fp != NULL, "just checking");
*** 150,162 ****
--- 329,341 ----
ExtendedPC epc;
ucontext_t* uc = (ucontext_t*)ucVoid;
if (uc != NULL) {
! epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
! if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc);
! if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc);
! epc = ExtendedPC(os::Bsd::ucontext_get_pc(uc));
! if (ret_sp) *ret_sp = os::Bsd::ucontext_get_sp(uc);
! if (ret_fp) *ret_fp = os::Bsd::ucontext_get_fp(uc);
} else {
// construct empty ExtendedPC for return value checking
epc = ExtendedPC(NULL);
if (ret_sp) *ret_sp = (intptr_t *)NULL;
if (ret_fp) *ret_fp = (intptr_t *)NULL;
*** 215,225 ****
--- 394,404 ----
extern "C" void FetchNPFI () ;
extern "C" void FetchNResume () ;
#endif // AMD64
extern "C" JNIEXPORT int
! JVM_handle_linux_signal(int sig,
! JVM_handle_bsd_signal(int sig,
siginfo_t* info,
void* ucVoid,
int abort_if_unrecognized) {
ucontext_t* uc = (ucontext_t*) ucVoid;
*** 228,244 ****
--- 407,423 ----
SignalHandlerMark shm(t);
// Note: it's not uncommon that JNI code uses signal/sigset to install
// then restore certain signal handler (e.g. to temporarily block SIGPIPE,
// or have a SIGILL handler when detecting CPU type). When that happens,
! // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
! // JVM_handle_bsd_signal() might be invoked with junk info/ucVoid. To
// avoid unnecessary crash when libjsig is not preloaded, try handle signals
// that do not require siginfo/ucontext first.
if (sig == SIGPIPE || sig == SIGXFSZ) {
// allow chained handler to go first
! if (os::Linux::chained_handler(sig, info, ucVoid)) {
! if (os::Bsd::chained_handler(sig, info, ucVoid)) {
return true;
} else {
if (PrintMiscellaneous && (WizardMode || Verbose)) {
char buf[64];
warning("Ignoring %s - see bugs 4229104 or 646499219",
*** 248,258 ****
--- 427,437 ----
}
}
JavaThread* thread = NULL;
VMThread* vmthread = NULL;
! if (os::Linux::signal_handlers_are_installed) {
! if (os::Bsd::signal_handlers_are_installed) {
if (t != NULL ){
if(t->is_Java_thread()) {
thread = (JavaThread*)t;
}
else if(t->is_VM_thread()){
*** 259,269 ****
--- 438,448 ----
vmthread = (VMThread *)t;
}
}
}
/*
! NOTE: does not seem to work on linux.
! NOTE: does not seem to work on bsd.
if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
// can't decode this kind of signal
info = NULL;
} else {
assert(sig == info->si_signo, "bad siginfo");
*** 274,298 ****
--- 453,477 ----
address pc = NULL;
//%note os_trap_1
if (info != NULL && uc != NULL && thread != NULL) {
! pc = (address) os::Linux::ucontext_get_pc(uc);
! pc = (address) os::Bsd::ucontext_get_pc(uc);
if (pc == (address) Fetch32PFI) {
! uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
! uc->context_pc = intptr_t(Fetch32Resume) ;
return 1 ;
}
#ifdef AMD64
if (pc == (address) FetchNPFI) {
! uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ;
! uc->context_pc = intptr_t (FetchNResume) ;
return 1 ;
}
#endif // AMD64
// Handle ALL stack overflow variations here
! if (sig == SIGSEGV || sig == SIGBUS) {
address addr = (address) info->si_addr;
// check if fault address is within thread stack
if (addr < thread->stack_base() &&
addr >= thread->stack_base() - thread->stack_size()) {
*** 310,345 ****
--- 489,533 ----
} else if (thread->in_stack_red_zone(addr)) {
// Fatal red zone violation. Disable the guard pages and fall through
// to handle_unexpected_exception way down below.
thread->disable_stack_red_zone();
tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
+ #ifndef _ALLBSD_SOURCE
} else {
// Accessing stack address below sp may cause SEGV if current
// thread has MAP_GROWSDOWN stack. This should only happen when
// current thread was created by user code with MAP_GROWSDOWN flag
! // and then attached to VM. See notes in os_linux.cpp.
! // and then attached to VM. See notes in os_bsd.cpp.
if (thread->osthread()->expanding_stack() == 0) {
thread->osthread()->set_expanding_stack();
! if (os::Linux::manually_expand_stack(thread, addr)) {
! if (os::Bsd::manually_expand_stack(thread, addr)) {
thread->osthread()->clear_expanding_stack();
return 1;
}
thread->osthread()->clear_expanding_stack();
} else {
fatal("recursive segv. expanding stack.");
}
+ #endif
}
}
}
if (thread->thread_state() == _thread_in_Java) {
// Java thread running in Java code => find exception handler if any
// a fault inside compiled code, the interpreter, or a stub
! if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) {
stub = SharedRuntime::get_poll_stub(pc);
+ #if defined(__APPLE__) && !defined(AMD64)
+ // 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions.
+ // Catching SIGBUS here prevents the implicit SIGBUS NULL check below from
+ // being called, so only do so if the implicit NULL check is not necessary.
+ } else if (sig == SIGBUS && MacroAssembler::needs_explicit_null_check((int)info->si_addr)) {
+ #else
} else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
+ #endif
// BugId 4454115: A read from a MappedByteBuffer can fault
// here if the underlying file has been truncated.
// Do not crash the VM in such a case.
CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
*** 356,368 ****
--- 544,578 ----
SharedRuntime::
continuation_for_implicit_exception(thread,
pc,
SharedRuntime::
IMPLICIT_DIVIDE_BY_ZERO);
+ #ifdef __APPLE__
+ } else if (sig == SIGFPE && info->si_code == FPE_NOOP) {
+ int op = pc[0];
+
+ // Skip REX
+ if ((pc[0] & 0xf0) == 0x40) {
+ op = pc[1];
+ } else {
+ op = pc[0];
+ }
+
+ // Check for IDIV
+ if (op == 0xF7) {
+ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime:: IMPLICIT_DIVIDE_BY_ZERO);
+ } else {
+ // TODO: handle more cases if we are using other x86 instructions
+ // that can generate SIGFPE signal.
+ tty->print_cr("unknown opcode 0x%X with SIGFPE.", op);
+ fatal("please update this code.");
+ }
+ #endif /* __APPLE__ */
+
#else
if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) {
! // HACK: si_code does not work on linux 2.2.12-20!!!
! // HACK: si_code does not work on bsd 2.2.12-20!!!
int op = pc[0];
if (op == 0xDB) {
// FIST
// TODO: The encoding of D2I in i486.ad can cause an exception
// prior to the fist instruction if there was an invalid operation
*** 378,393 ****
--- 588,603 ----
} else if (op == 0xF7) {
// IDIV
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
} else {
// TODO: handle more cases if we are using other x86 instructions
! // that can generate SIGFPE signal on linux.
! // that can generate SIGFPE signal on bsd.
tty->print_cr("unknown opcode 0x%X with SIGFPE.", op);
fatal("please update this code.");
}
#endif // AMD64
! } else if ((sig == SIGSEGV || sig == SIGBUS) &&
!MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
// Determination of interpreter/vtable stub/compiled code null exception
stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
}
} else if (thread->thread_state() == _thread_in_vm &&
*** 407,417 ****
--- 617,627 ----
// Check to see if we caught the safepoint code in the
// process of write protecting the memory serialization page.
// It write enables the page immediately after protecting it
// so we can just return to retry the write.
! if ((sig == SIGSEGV || sig == SIGBUS) &&
os::is_memory_serialize_page(thread, (address) info->si_addr)) {
// Block current thread until the memory serialize page permission restored.
os::block_on_serialize_page_trap();
return true;
}
*** 428,441 ****
--- 638,651 ----
// this si_code is so generic that it is almost meaningless; and
// the si_code for this condition may change in the future.
// Furthermore, a false-positive should be harmless.
if (UnguardOnExecutionViolation > 0 &&
(sig == SIGSEGV || sig == SIGBUS) &&
! uc->uc_mcontext.gregs[REG_TRAPNO] == trap_page_fault) {
! uc->context_trapno == trap_page_fault) {
int page_size = os::vm_page_size();
address addr = (address) info->si_addr;
! address pc = os::Linux::ucontext_get_pc(uc);
! address pc = os::Bsd::ucontext_get_pc(uc);
// Make sure the pc and the faulting address are sane.
//
// If an instruction spans a page boundary, and the page containing
// the beginning of the instruction is executable but the following
// page is not, the pc and the faulting address might be slightly
*** 498,523 ****
--- 708,733 ----
if (stub != NULL) {
// save all thread context in case we need to restore it
if (thread != NULL) thread->set_saved_exception_pc(pc);
! uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub;
! uc->context_pc = (intptr_t)stub;
return true;
}
// signal-chaining
! if (os::Linux::chained_handler(sig, info, ucVoid)) {
! if (os::Bsd::chained_handler(sig, info, ucVoid)) {
return true;
}
if (!abort_if_unrecognized) {
// caller wants another chance, so give it to him
return false;
}
if (pc == NULL && uc != NULL) {
! pc = os::Linux::ucontext_get_pc(uc);
! pc = os::Bsd::ucontext_get_pc(uc);
}
// unmask current signal
sigset_t newset;
sigemptyset(&newset);
*** 528,564 ****
--- 738,786 ----
err.report_and_die();
ShouldNotReachHere();
}
void os::Linux::init_thread_fpu_state(void) {
+ #ifdef _ALLBSD_SOURCE
+ // From solaris_i486.s ported to bsd_i486.s
+ extern "C" void fixcw();
+ #endif
+
+ void os::Bsd::init_thread_fpu_state(void) {
#ifndef AMD64
+ # ifdef _ALLBSD_SOURCE
+ // Set fpu to 53 bit precision. This happens too early to use a stub.
+ fixcw();
+ # else
// set fpu to 53 bit precision
set_fpu_control_word(0x27f);
+ # endif
#endif // !AMD64
}
int os::Linux::get_fpu_control_word(void) {
+ #ifndef _ALLBSD_SOURCE
+ int os::Bsd::get_fpu_control_word(void) {
#ifdef AMD64
return 0;
#else
int fpu_control;
_FPU_GETCW(fpu_control);
return fpu_control & 0xffff;
#endif // AMD64
}
! void os::Linux::set_fpu_control_word(int fpu_control) {
! void os::Bsd::set_fpu_control_word(int fpu_control) {
#ifndef AMD64
_FPU_SETCW(fpu_control);
#endif // !AMD64
}
+ #endif
! // Check that the linux kernel version is 2.4 or higher since earlier
! // Check that the bsd kernel version is 2.4 or higher since earlier
// versions do not support SSE without patches.
bool os::supports_sse() {
! #ifdef AMD64
! #if defined(AMD64) || defined(_ALLBSD_SOURCE)
return true;
#else
struct utsname uts;
if( uname(&uts) != 0 ) return false; // uname fails?
char *minor_string;
*** 597,643 ****
--- 819,868 ----
////////////////////////////////////////////////////////////////////////////////
// thread stack
#ifdef AMD64
! size_t os::Linux::min_stack_allowed = 64 * K;
! size_t os::Bsd::min_stack_allowed = 64 * K;
// amd64: pthread on amd64 is always in floating stack mode
! bool os::Linux::supports_variable_stack_size() { return true; }
! bool os::Bsd::supports_variable_stack_size() { return true; }
#else
! size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
! size_t os::Bsd::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
#ifdef __GNUC__
#define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
#endif
// Test if pthread library can support variable thread stack size. LinuxThreads
// in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
+ #ifdef _ALLBSD_SOURCE
+ bool os::Bsd::supports_variable_stack_size() { return true; }
+ #else
+ // Test if pthread library can support variable thread stack size. BsdThreads
+ // in fixed stack mode allocates 2M fixed slot for each thread. BsdThreads
// in floating stack mode and NPTL support variable stack size.
! bool os::Linux::supports_variable_stack_size() {
! if (os::Linux::is_NPTL()) {
! bool os::Bsd::supports_variable_stack_size() {
! if (os::Bsd::is_NPTL()) {
// NPTL, yes
return true;
} else {
// Note: We can't control default stack size when creating a thread.
// If we use non-default stack size (pthread_attr_setstacksize), both
! // floating stack and non-floating stack LinuxThreads will return the
! // floating stack and non-floating stack BsdThreads will return the
// same value. This makes it impossible to implement this function by
// detecting thread stack size directly.
//
! // An alternative approach is to check %gs. Fixed-stack LinuxThreads
! // do not use %gs, so its value is 0. Floating-stack LinuxThreads use
! // An alternative approach is to check %gs. Fixed-stack BsdThreads
! // do not use %gs, so its value is 0. Floating-stack BsdThreads use
// %gs (either as LDT selector or GDT selector, depending on kernel)
// to access thread specific data.
//
// Note that %gs is a reserved glibc register since early 2001, so
// applications are not allowed to change its value (Ulrich Drepper from
// Redhat confirmed that all known offenders have been modified to use
// either %fs or TSD). In the worst case scenario, when VM is embedded in
// a native application that plays with %gs, we might see non-zero %gs
! // even LinuxThreads is running in fixed stack mode. As the result, we'll
! // even BsdThreads is running in fixed stack mode. As the result, we'll
// return true and skip _thread_safety_check(), so we may not be able to
// detect stack-heap collisions. But otherwise it's harmless.
//
#ifdef __GNUC__
return (GET_GS() != 0);
*** 644,667 ****
--- 869,893 ----
#else
return false;
#endif
}
}
+ #endif
#endif // AMD64
// return default stack size for thr_type
! size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
! size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
// default stack size (compiler thread needs larger stack)
#ifdef AMD64
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
#else
size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
#endif // AMD64
return s;
}
! size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
! size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
// Creating guard page is very expensive. Java thread has HotSpot
// guard page, only enable glibc guard page for non-Java threads.
return (thr_type == java_thread ? 0 : page_size());
}
*** 697,711 ****
--- 923,972 ----
//
// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
// pthread_attr_getstack()
static void current_stack_region(address * bottom, size_t * size) {
if (os::Linux::is_initial_thread()) {
+ #ifdef __APPLE__
+ pthread_t self = pthread_self();
+ void *stacktop = pthread_get_stackaddr_np(self);
+ *size = pthread_get_stacksize_np(self);
+ *bottom = (address) stacktop - *size;
+ #elif defined(__OpenBSD__)
+ stack_t ss;
+ int rslt = pthread_stackseg_np(pthread_self(), &ss);
+
+ if (rslt != 0)
+ fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt));
+
+ *bottom = (address)((char *)ss.ss_sp - ss.ss_size);
+ *size = ss.ss_size;
+ #elif defined(_ALLBSD_SOURCE)
+ pthread_attr_t attr;
+
+ int rslt = pthread_attr_init(&attr);
+
+ // JVM needs to know exact stack location, abort if it fails
+ if (rslt != 0)
+ fatal(err_msg("pthread_attr_init failed with err = %d", rslt));
+
+ rslt = pthread_attr_get_np(pthread_self(), &attr);
+
+ if (rslt != 0)
+ fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt));
+
+ if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 ||
+ pthread_attr_getstacksize(&attr, size) != 0) {
+ fatal("Can not locate current stack attributes!");
+ }
+
+ pthread_attr_destroy(&attr);
+ #else
+ if (os::Bsd::is_initial_thread()) {
// initial thread needs special handling because pthread_getattr_np()
// may return bogus value.
! *bottom = os::Linux::initial_thread_stack_bottom();
! *size = os::Linux::initial_thread_stack_size();
! *bottom = os::Bsd::initial_thread_stack_bottom();
! *size = os::Bsd::initial_thread_stack_size();
} else {
pthread_attr_t attr;
int rslt = pthread_getattr_np(pthread_self(), &attr);
*** 723,732 ****
--- 984,994 ----
}
pthread_attr_destroy(&attr);
}
+ #endif
assert(os::current_stack_pointer() >= *bottom &&
os::current_stack_pointer() < *bottom + *size, "just checking");
}
address os::current_stack_base() {
*** 751,813 ****
--- 1013,1073 ----
if (context == NULL) return;
ucontext_t *uc = (ucontext_t*)context;
st->print_cr("Registers:");
#ifdef AMD64
! st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
! st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
! st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
! st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
! st->print( "RAX=" INTPTR_FORMAT, uc->context_rax);
! st->print(", RBX=" INTPTR_FORMAT, uc->context_rbx);
! st->print(", RCX=" INTPTR_FORMAT, uc->context_rcx);
! st->print(", RDX=" INTPTR_FORMAT, uc->context_rdx);
st->cr();
! st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
! st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
! st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
! st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
! st->print( "RSP=" INTPTR_FORMAT, uc->context_rsp);
! st->print(", RBP=" INTPTR_FORMAT, uc->context_rbp);
! st->print(", RSI=" INTPTR_FORMAT, uc->context_rsi);
! st->print(", RDI=" INTPTR_FORMAT, uc->context_rdi);
st->cr();
! st->print( "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
! st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
! st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
! st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
! st->print( "R8 =" INTPTR_FORMAT, uc->context_r8);
! st->print(", R9 =" INTPTR_FORMAT, uc->context_r9);
! st->print(", R10=" INTPTR_FORMAT, uc->context_r10);
! st->print(", R11=" INTPTR_FORMAT, uc->context_r11);
st->cr();
! st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
! st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
! st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
! st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
! st->print( "R12=" INTPTR_FORMAT, uc->context_r12);
! st->print(", R13=" INTPTR_FORMAT, uc->context_r13);
! st->print(", R14=" INTPTR_FORMAT, uc->context_r14);
! st->print(", R15=" INTPTR_FORMAT, uc->context_r15);
st->cr();
! st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
! st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
! st->print(", CSGSFS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_CSGSFS]);
st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]);
! st->print( "RIP=" INTPTR_FORMAT, uc->context_rip);
! st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_flags);
! st->print(", ERR=" INTPTR_FORMAT, uc->context_err);
st->cr();
! st->print(" TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]);
! st->print(" TRAPNO=" INTPTR_FORMAT, uc->context_trapno);
#else
! st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
! st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
! st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]);
! st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]);
! st->print( "EAX=" INTPTR_FORMAT, uc->context_eax);
! st->print(", EBX=" INTPTR_FORMAT, uc->context_ebx);
! st->print(", ECX=" INTPTR_FORMAT, uc->context_ecx);
! st->print(", EDX=" INTPTR_FORMAT, uc->context_edx);
st->cr();
! st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_UESP]);
! st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]);
! st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]);
! st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]);
! st->print( "ESP=" INTPTR_FORMAT, uc->context_esp);
! st->print(", EBP=" INTPTR_FORMAT, uc->context_ebp);
! st->print(", ESI=" INTPTR_FORMAT, uc->context_esi);
! st->print(", EDI=" INTPTR_FORMAT, uc->context_edi);
st->cr();
! st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]);
! st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2);
! st->print( "EIP=" INTPTR_FORMAT, uc->context_eip);
! st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_eflags);
#endif // AMD64
st->cr();
st->cr();
! intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
! intptr_t *sp = (intptr_t *)os::Bsd::ucontext_get_sp(uc);
st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
st->cr();
// Note: it may be unsafe to inspect memory near pc. For example, pc may
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
! address pc = os::Linux::ucontext_get_pc(uc);
! address pc = os::Bsd::ucontext_get_pc(uc);
st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
}
void os::print_register_info(outputStream *st, void *context) {
*** 823,857 ****
--- 1083,1117 ----
// we can't just iterate through the gregs area
// this is only for the "general purpose" registers
#ifdef AMD64
! st->print("RAX="); print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
! st->print("RBX="); print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
! st->print("RCX="); print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
! st->print("RDX="); print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
! st->print("RSP="); print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
! st->print("RBP="); print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
! st->print("RSI="); print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
! st->print("RDI="); print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
! st->print("R8 ="); print_location(st, uc->uc_mcontext.gregs[REG_R8]);
! st->print("R9 ="); print_location(st, uc->uc_mcontext.gregs[REG_R9]);
! st->print("R10="); print_location(st, uc->uc_mcontext.gregs[REG_R10]);
! st->print("R11="); print_location(st, uc->uc_mcontext.gregs[REG_R11]);
! st->print("R12="); print_location(st, uc->uc_mcontext.gregs[REG_R12]);
! st->print("R13="); print_location(st, uc->uc_mcontext.gregs[REG_R13]);
! st->print("R14="); print_location(st, uc->uc_mcontext.gregs[REG_R14]);
! st->print("R15="); print_location(st, uc->uc_mcontext.gregs[REG_R15]);
! st->print("RAX="); print_location(st, uc->context_rax);
! st->print("RBX="); print_location(st, uc->context_rbx);
! st->print("RCX="); print_location(st, uc->context_rcx);
! st->print("RDX="); print_location(st, uc->context_rdx);
! st->print("RSP="); print_location(st, uc->context_rsp);
! st->print("RBP="); print_location(st, uc->context_rbp);
! st->print("RSI="); print_location(st, uc->context_rsi);
! st->print("RDI="); print_location(st, uc->context_rdi);
! st->print("R8 ="); print_location(st, uc->context_r8);
! st->print("R9 ="); print_location(st, uc->context_r9);
! st->print("R10="); print_location(st, uc->context_r10);
! st->print("R11="); print_location(st, uc->context_r11);
! st->print("R12="); print_location(st, uc->context_r12);
! st->print("R13="); print_location(st, uc->context_r13);
! st->print("R14="); print_location(st, uc->context_r14);
! st->print("R15="); print_location(st, uc->context_r15);
#else
! st->print("EAX="); print_location(st, uc->uc_mcontext.gregs[REG_EAX]);
! st->print("EBX="); print_location(st, uc->uc_mcontext.gregs[REG_EBX]);
! st->print("ECX="); print_location(st, uc->uc_mcontext.gregs[REG_ECX]);
! st->print("EDX="); print_location(st, uc->uc_mcontext.gregs[REG_EDX]);
! st->print("ESP="); print_location(st, uc->uc_mcontext.gregs[REG_ESP]);
! st->print("EBP="); print_location(st, uc->uc_mcontext.gregs[REG_EBP]);
! st->print("ESI="); print_location(st, uc->uc_mcontext.gregs[REG_ESI]);
! st->print("EDI="); print_location(st, uc->uc_mcontext.gregs[REG_EDI]);
! st->print("EAX="); print_location(st, uc->context_eax);
! st->print("EBX="); print_location(st, uc->context_ebx);
! st->print("ECX="); print_location(st, uc->context_ecx);
! st->print("EDX="); print_location(st, uc->context_edx);
! st->print("ESP="); print_location(st, uc->context_esp);
! st->print("EBP="); print_location(st, uc->context_ebp);
! st->print("ESI="); print_location(st, uc->context_esi);
! st->print("EDI="); print_location(st, uc->context_edi);
#endif // AMD64
st->cr();
}
src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File