- Loading...
Here are the hotspot os_cpu changes linux vs bsd:
| Code Block |
|---|
Files src/os_cpu/linux_x86/vm/assembler_linux_x86.cpp and src/os_cpu/bsd_x86/vm/assembler_bsd_x86.cpp are identical
--- src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,10 +22,10 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
-#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
+#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
+#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
-#include "orderAccess_linux_x86.inline.hpp"
+#include "orderAccess_bsd_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
@@ -185,7 +185,7 @@
}
extern "C" {
- // defined in linux_x86.s
+ // defined in bsd_x86.s
jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool);
void _Atomic_move_long(volatile jlong* src, volatile jlong* dst);
}
@@ -218,4 +218,4 @@
#endif // AMD64
-#endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
+#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
--- src/os_cpu/linux_x86/vm/linux_x86_32.ad 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/bsd_x86_32.ad 2011-07-26 20:21:21.000000000 -0600
@@ -22,7 +22,7 @@
//
//
-// X86 Linux Architecture Description File
+// X86 Bsd Architecture Description File
//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
// This block specifies the encoding classes used by the compiler to output
@@ -53,13 +53,13 @@
// adding a syntax that specifies the sizes of fields in an order,
// so that the adlc can build the emit functions automagically
- enc_class linux_tlsencode (eRegP dst) %{
+ enc_class bsd_tlsencode (eRegP dst) %{
Register dstReg = as_Register($dst$$reg);
MacroAssembler* masm = new MacroAssembler(&cbuf);
masm->get_thread(dstReg);
%}
- enc_class linux_breakpoint %{
+ enc_class bsd_breakpoint %{
MacroAssembler* masm = new MacroAssembler(&cbuf);
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
%}
@@ -108,7 +108,7 @@
effect(DEF dst, KILL cr);
format %{ "MOV $dst, Thread::current()" %}
- ins_encode( linux_tlsencode(dst) );
+ ins_encode( bsd_tlsencode(dst) );
ins_pipe( ialu_reg_fat );
%}
@@ -130,7 +130,7 @@
// QQQ TODO for now call breakpoint
// opcode(0xCC);
// ins_encode(Opc);
- ins_encode(linux_breakpoint);
+ ins_encode(bsd_breakpoint);
ins_pipe( pipe_slow );
%}
--- src/os_cpu/linux_x86/vm/linux_x86_32.s 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/bsd_x86_32.s 2011-07-26 20:21:21.000000000 -0600
@@ -21,6 +21,17 @@
# questions.
#
+
+#ifdef __APPLE__
+# Darwin uses _ prefixed global symbols
+#define SYMBOL(s) _ ## s
+#define ELF_TYPE(name, description)
+#else
+#define SYMBOL(s) s
+#define ELF_TYPE(name, description) .type name,description
+#endif
+
+ .globl SYMBOL(fixcw)
# NOTE WELL! The _Copy functions are called directly
# from server-compiler-generated code via CallLeafNoFP,
@@ -28,42 +39,62 @@
# point or use it in the same manner as does the server
# compiler.
- .globl _Copy_conjoint_bytes
- .globl _Copy_arrayof_conjoint_bytes
- .globl _Copy_conjoint_jshorts_atomic
- .globl _Copy_arrayof_conjoint_jshorts
- .globl _Copy_conjoint_jints_atomic
- .globl _Copy_arrayof_conjoint_jints
- .globl _Copy_conjoint_jlongs_atomic
- .globl _mmx_Copy_arrayof_conjoint_jshorts
+ .globl SYMBOL(_Copy_conjoint_bytes)
+ .globl SYMBOL(_Copy_arrayof_conjoint_bytes)
+ .globl SYMBOL(_Copy_conjoint_jshorts_atomic)
+ .globl SYMBOL(_Copy_arrayof_conjoint_jshorts)
+ .globl SYMBOL(_Copy_conjoint_jints_atomic)
+ .globl SYMBOL(_Copy_arrayof_conjoint_jints)
+ .globl SYMBOL(_Copy_conjoint_jlongs_atomic)
+ .globl SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts)
- .globl _Atomic_cmpxchg_long
- .globl _Atomic_move_long
+ .globl SYMBOL(_Atomic_cmpxchg_long)
+ .globl SYMBOL(_Atomic_move_long)
.text
- .globl SafeFetch32, Fetch32PFI, Fetch32Resume
- .globl SafeFetchN
+# Support for void os::Solaris::init_thread_fpu_state() in os_solaris_i486.cpp
+# Set fpu to 53 bit precision. This happens too early to use a stub.
+# ported from solaris_x86_32.s
+#ifdef __APPLE__
+ .align 4
+#else
+ .align 16
+#endif
+SYMBOL(fixcw):
+ pushl $0x27f
+ fldcw 0(%esp)
+ popl %eax
+ ret
+
+#ifdef __APPLE__
+ .align 4
+#else
+ .align 16
+#endif
+
+ .globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
+ .globl SYMBOL(SafeFetchN)
## TODO: avoid exposing Fetch32PFI and Fetch32Resume.
## Instead, the signal handler would call a new SafeFetchTriage(FaultingEIP)
## routine to vet the address. If the address is the faulting LD then
## SafeFetchTriage() would return the resume-at EIP, otherwise null.
- .type SafeFetch32,@function
+ ELF_TYPE(SafeFetch32,@function)
.p2align 4,,15
-SafeFetch32:
-SafeFetchN:
+SYMBOL(SafeFetch32):
+SYMBOL(SafeFetchN):
movl 0x8(%esp), %eax
movl 0x4(%esp), %ecx
-Fetch32PFI:
+SYMBOL(Fetch32PFI):
movl (%ecx), %eax
-Fetch32Resume:
+SYMBOL(Fetch32Resume):
ret
- .globl SpinPause
- .type SpinPause,@function
+ .globl SYMBOL(SpinPause)
+ ELF_TYPE(SpinPause,@function)
.p2align 4,,15
-SpinPause:
+SYMBOL(SpinPause):
rep
nop
movl $1, %eax
@@ -73,8 +104,8 @@
# void* to,
# size_t count)
.p2align 4,,15
- .type _Copy_conjoint_bytes,@function
-_Copy_conjoint_bytes:
+ ELF_TYPE(_Copy_conjoint_bytes,@function)
+SYMBOL(_Copy_conjoint_bytes):
pushl %esi
movl 4+12(%esp),%ecx # count
pushl %edi
@@ -181,8 +212,8 @@
#
# Same as _Copy_conjoint_bytes, except no source alignment check.
.p2align 4,,15
- .type _Copy_arrayof_conjoint_bytes,@function
-_Copy_arrayof_conjoint_bytes:
+ ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function)
+SYMBOL(_Copy_arrayof_conjoint_bytes):
pushl %esi
movl 4+12(%esp),%ecx # count
pushl %edi
@@ -269,8 +300,8 @@
# void* to,
# size_t count)
.p2align 4,,15
- .type _Copy_conjoint_jshorts_atomic,@function
-_Copy_conjoint_jshorts_atomic:
+ ELF_TYPE(_Copy_conjoint_jshorts_atomic,@function)
+SYMBOL(_Copy_conjoint_jshorts_atomic):
pushl %esi
movl 4+12(%esp),%ecx # count
pushl %edi
@@ -356,8 +387,8 @@
# void* to,
# size_t count)
.p2align 4,,15
- .type _Copy_arrayof_conjoint_jshorts,@function
-_Copy_arrayof_conjoint_jshorts:
+ ELF_TYPE(_Copy_arrayof_conjoint_jshorts,@function)
+SYMBOL(_Copy_arrayof_conjoint_jshorts):
pushl %esi
movl 4+12(%esp),%ecx # count
pushl %edi
@@ -433,10 +464,10 @@
# Equivalent to
# arrayof_conjoint_jints
.p2align 4,,15
- .type _Copy_conjoint_jints_atomic,@function
- .type _Copy_arrayof_conjoint_jints,@function
-_Copy_conjoint_jints_atomic:
-_Copy_arrayof_conjoint_jints:
+ ELF_TYPE(_Copy_conjoint_jints_atomic,@function)
+ ELF_TYPE(_Copy_arrayof_conjoint_jints,@function)
+SYMBOL(_Copy_conjoint_jints_atomic):
+SYMBOL(_Copy_arrayof_conjoint_jints):
pushl %esi
movl 4+12(%esp),%ecx # count
pushl %edi
@@ -498,7 +529,7 @@
#
# count treated as signed
#
- # if (from > to) {
+ # // if (from > to) {
# while (--count >= 0) {
# *to++ = *from++;
# }
@@ -508,8 +539,8 @@
# }
# }
.p2align 4,,15
- .type _Copy_conjoint_jlongs_atomic,@function
-_Copy_conjoint_jlongs_atomic:
+ ELF_TYPE(_Copy_conjoint_jlongs_atomic,@function)
+SYMBOL(_Copy_conjoint_jlongs_atomic):
movl 4+8(%esp),%ecx # count
movl 4+0(%esp),%eax # from
movl 4+4(%esp),%edx # to
@@ -537,8 +568,8 @@
# void* to,
# size_t count)
.p2align 4,,15
- .type _mmx_Copy_arrayof_conjoint_jshorts,@function
-_mmx_Copy_arrayof_conjoint_jshorts:
+ ELF_TYPE(_mmx_Copy_arrayof_conjoint_jshorts,@function)
+SYMBOL(_mmx_Copy_arrayof_conjoint_jshorts):
pushl %esi
movl 4+12(%esp),%ecx
pushl %edi
@@ -636,8 +667,8 @@
# bool is_MP)
#
.p2align 4,,15
- .type _Atomic_cmpxchg_long,@function
-_Atomic_cmpxchg_long:
+ ELF_TYPE(_Atomic_cmpxchg_long,@function)
+SYMBOL(_Atomic_cmpxchg_long):
# 8(%esp) : return PC
pushl %ebx # 4(%esp) : old %ebx
pushl %edi # 0(%esp) : old %edi
--- src/os_cpu/linux_x86/vm/linux_x86_64.ad 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/bsd_x86_64.ad 2011-07-26 20:21:21.000000000 -0600
@@ -22,7 +22,7 @@
//
//
-// AMD64 Linux Architecture Description File
+// AMD64 Bsd Architecture Description File
//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
// This block specifies the encoding classes used by the compiler to
@@ -70,7 +70,7 @@
emit_opcode(cbuf, 0xD0 | (R10_enc - 8));
%}
- enc_class linux_breakpoint
+ enc_class bsd_breakpoint
%{
MacroAssembler* masm = new MacroAssembler(&cbuf);
masm->call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
@@ -141,7 +141,7 @@
// QQQ TODO for now call breakpoint
// opcode(0xCC);
// ins_encode(Opc);
- ins_encode(linux_breakpoint);
+ ins_encode(bsd_breakpoint);
ins_pipe(pipe_slow);
%}
--- src/os_cpu/linux_x86/vm/linux_x86_64.s 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/bsd_x86_64.s 2011-07-26 20:21:21.000000000 -0600
@@ -21,6 +21,14 @@
# questions.
#
+#ifdef __APPLE__
+# Darwin uses _ prefixed global symbols
+#define SYMBOL(s) _ ## s
+#define ELF_TYPE(name, description)
+#else
+#define SYMBOL(s) s
+#define ELF_TYPE(name, description) .type name,description
+#endif
# NOTE WELL! The _Copy functions are called directly
# from server-compiler-generated code via CallLeafNoFP,
@@ -28,42 +36,54 @@
# point or use it in the same manner as does the server
# compiler.
- .globl _Copy_arrayof_conjoint_bytes
- .globl _Copy_arrayof_conjoint_jshorts
- .globl _Copy_conjoint_jshorts_atomic
- .globl _Copy_arrayof_conjoint_jints
- .globl _Copy_conjoint_jints_atomic
- .globl _Copy_arrayof_conjoint_jlongs
- .globl _Copy_conjoint_jlongs_atomic
+ .globl SYMBOL(_Copy_arrayof_conjoint_bytes)
+ .globl SYMBOL(_Copy_arrayof_conjoint_jshorts)
+ .globl SYMBOL(_Copy_conjoint_jshorts_atomic)
+ .globl SYMBOL(_Copy_arrayof_conjoint_jints)
+ .globl SYMBOL(_Copy_conjoint_jints_atomic)
+ .globl SYMBOL(_Copy_arrayof_conjoint_jlongs)
+ .globl SYMBOL(_Copy_conjoint_jlongs_atomic)
.text
- .globl SafeFetch32, Fetch32PFI, Fetch32Resume
+ .globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume)
+#ifdef __APPLE__
+ .align 4
+#else
.align 16
- .type SafeFetch32,@function
+#endif
+ ELF_TYPE(SafeFetch32,@function)
// Prototype: int SafeFetch32 (int * Adr, int ErrValue)
-SafeFetch32:
+SYMBOL(SafeFetch32):
movl %esi, %eax
-Fetch32PFI:
+SYMBOL(Fetch32PFI):
movl (%rdi), %eax
-Fetch32Resume:
+SYMBOL(Fetch32Resume):
ret
- .globl SafeFetchN, FetchNPFI, FetchNResume
+ .globl SYMBOL(SafeFetchN), SYMBOL(FetchNPFI), SYMBOL(FetchNResume)
+#ifdef __APPLE__
+ .align 4
+#else
.align 16
- .type SafeFetchN,@function
+#endif
+ ELF_TYPE(SafeFetchN,@function)
// Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue)
-SafeFetchN:
+SYMBOL(SafeFetchN):
movq %rsi, %rax
-FetchNPFI:
+SYMBOL(FetchNPFI):
movq (%rdi), %rax
-FetchNResume:
+SYMBOL(FetchNResume):
ret
- .globl SpinPause
- .align 16
- .type SpinPause,@function
-SpinPause:
+ .globl SYMBOL(SpinPause)
+#ifdef __APPLE__
+ .align 4
+#else
+ .align 16
+#endif
+ ELF_TYPE(SpinPause,@function)
+SYMBOL(SpinPause):
rep
nop
movq $1, %rax
@@ -77,8 +97,8 @@
# rdx - count, treated as ssize_t
#
.p2align 4,,15
- .type _Copy_arrayof_conjoint_bytes,@function
-_Copy_arrayof_conjoint_bytes:
+ ELF_TYPE(_Copy_arrayof_conjoint_bytes,@function)
+SYMBOL(_Copy_arrayof_conjoint_bytes):
movq %rdx,%r8 # byte count
shrq $3,%rdx # qword count
cmpq %rdi,%rsi
@@ -179,10 +199,10 @@
# rdx - count, treated as ssize_t
#
.p2align 4,,15
- .type _Copy_arrayof_conjoint_jshorts,@function
- .type _Copy_conjoint_jshorts_atomic,@function
-_Copy_arrayof_conjoint_jshorts:
-_Copy_conjoint_jshorts_atomic:
+ ELF_TYPE(_Copy_arrayof_conjoint_jshorts,@function)
+ ELF_TYPE(_Copy_conjoint_jshorts_atomic,@function)
+SYMBOL(_Copy_arrayof_conjoint_jshorts):
+SYMBOL(_Copy_conjoint_jshorts_atomic):
movq %rdx,%r8 # word count
shrq $2,%rdx # qword count
cmpq %rdi,%rsi
@@ -269,10 +289,10 @@
# rdx - count, treated as ssize_t
#
.p2align 4,,15
- .type _Copy_arrayof_conjoint_jints,@function
- .type _Copy_conjoint_jints_atomic,@function
-_Copy_arrayof_conjoint_jints:
-_Copy_conjoint_jints_atomic:
+ ELF_TYPE(_Copy_arrayof_conjoint_jints,@function)
+ ELF_TYPE(_Copy_conjoint_jints_atomic,@function)
+SYMBOL(_Copy_arrayof_conjoint_jints):
+SYMBOL(_Copy_conjoint_jints_atomic):
movq %rdx,%r8 # dword count
shrq %rdx # qword count
cmpq %rdi,%rsi
@@ -348,10 +368,10 @@
# rdx - count, treated as ssize_t
#
.p2align 4,,15
- .type _Copy_arrayof_conjoint_jlongs,@function
- .type _Copy_conjoint_jlongs_atomic,@function
-_Copy_arrayof_conjoint_jlongs:
-_Copy_conjoint_jlongs_atomic:
+ ELF_TYPE(_Copy_arrayof_conjoint_jlongs,@function)
+ ELF_TYPE(_Copy_conjoint_jlongs_atomic,@function)
+SYMBOL(_Copy_arrayof_conjoint_jlongs):
+SYMBOL(_Copy_conjoint_jlongs_atomic):
cmpq %rdi,%rsi
leaq -8(%rdi,%rdx,8),%rax # from + count*8 - 8
jbe acl_CopyRight
--- src/os_cpu/linux_x86/vm/bytes_linux_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,10 +22,36 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_BYTES_LINUX_X86_INLINE_HPP
-#define OS_CPU_LINUX_X86_VM_BYTES_LINUX_X86_INLINE_HPP
+#ifndef OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
+#define OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
+#ifndef _ALLBSD_SOURCE
#include <byteswap.h>
+#endif
+
+#ifdef __APPLE__
+#include <libkern/OSByteOrder.h>
+#endif
+
+#if defined(AMD64)
+# if defined(__APPLE__)
+# define bswap_16(x) OSSwapInt16(x)
+# define bswap_32(x) OSSwapInt32(x)
+# define bswap_64(x) OSSwapInt64(x)
+# elif defined(__OpenBSD__)
+# define bswap_16(x) swap16(x)
+# define bswap_32(x) swap32(x)
+# define bswap_64(x) swap64(x)
+# elif defined(__NetBSD__)
+# define bswap_16(x) bswap16(x)
+# define bswap_32(x) bswap32(x)
+# define bswap_64(x) bswap64(x)
+# else
+# define bswap_16(x) __bswap16(x)
+# define bswap_32(x) __bswap32(x)
+# define bswap_64(x) __bswap64(x)
+# endif
+#endif
// Efficient swapping of data bytes from Java byte
// ordering to native byte ordering and vice versa.
@@ -87,4 +113,4 @@
}
#endif // !AMD64
-#endif // OS_CPU_LINUX_X86_VM_BYTES_LINUX_X86_INLINE_HPP
+#endif // OS_CPU_BSD_X86_VM_BYTES_BSD_X86_INLINE_HPP
--- src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/copy_bsd_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_COPY_LINUX_X86_INLINE_HPP
-#define OS_CPU_LINUX_X86_VM_COPY_LINUX_X86_INLINE_HPP
+#ifndef OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
+#define OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
#ifdef AMD64
@@ -306,4 +306,4 @@
#endif // AMD64
}
-#endif // OS_CPU_LINUX_X86_VM_COPY_LINUX_X86_INLINE_HPP
+#endif // OS_CPU_BSD_X86_VM_COPY_BSD_X86_INLINE_HPP
--- src/os_cpu/linux_x86/vm/globals_linux_x86.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/globals_bsd_x86.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,12 +22,13 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP
+#ifndef OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
+#define OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
+//
// Sets the default values for platform dependent flags used by the runtime system.
// (see globals.hpp)
-
+//
define_pd_global(bool, DontYieldALot, false);
#ifdef AMD64
define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default
@@ -41,12 +42,13 @@
#endif // AMD64
define_pd_global(intx, CompilerThreadStackSize, 0);
+define_pd_global(intx, SurvivorRatio, 8);
-define_pd_global(uintx,JVMInvokeMethodSlack, 8192);
+define_pd_global(uintx, JVMInvokeMethodSlack, 8192);
// Only used on 64 bit platforms
-define_pd_global(uintx,HeapBaseMinAddress, 2*G);
+define_pd_global(uintx, HeapBaseMinAddress, 2*G);
// Only used on 64 bit Windows platforms
define_pd_global(bool, UseVectoredExceptions, false);
-#endif // OS_CPU_LINUX_X86_VM_GLOBALS_LINUX_X86_HPP
+#endif // OS_CPU_BSD_X86_VM_GLOBALS_BSD_X86_HPP
--- src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
-#define OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
+#ifndef OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
+#define OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
#include "runtime/atomic.hpp"
#include "runtime/orderAccess.hpp"
@@ -212,4 +212,4 @@
#endif // AMD64
}
-#endif // OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
+#endif // OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
--- src/os_cpu/linux_x86/vm/os_linux_x86.cpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp 2011-07-26 20:21:21.000000000 -0600
@@ -30,11 +30,11 @@
#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"
@@ -49,7 +49,7 @@
#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
@@ -78,23 +78,202 @@
# 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;
@@ -118,24 +297,24 @@
// 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");
@@ -152,9 +331,9 @@
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);
@@ -217,7 +396,7 @@
#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) {
@@ -230,13 +409,13 @@
// 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)) {
@@ -250,7 +429,7 @@
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;
@@ -261,7 +440,7 @@
}
}
/*
- 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;
@@ -276,21 +455,21 @@
//%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) {
+ if (sig == SIGSEGV || sig == SIGBUS) {
address addr = (address) info->si_addr;
// check if fault address is within thread stack
@@ -312,14 +491,15 @@
// 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;
}
@@ -327,6 +507,7 @@
} else {
fatal("recursive segv. expanding stack.");
}
+#endif
}
}
}
@@ -335,9 +516,16 @@
// Java thread running in Java code => find exception handler if any
// a fault inside compiled code, the interpreter, or a stub
- if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
+ 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.
@@ -358,9 +546,31 @@
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
@@ -380,12 +590,12 @@
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 &&
+ } 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);
@@ -409,7 +619,7 @@
// 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) &&
+ 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();
@@ -430,10 +640,10 @@
// 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
@@ -500,12 +710,12 @@
// 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;
}
@@ -515,7 +725,7 @@
}
if (pc == NULL && uc != NULL) {
- pc = os::Linux::ucontext_get_pc(uc);
+ pc = os::Bsd::ucontext_get_pc(uc);
}
// unmask current signal
@@ -530,14 +740,25 @@
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
@@ -547,16 +768,17 @@
#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;
@@ -599,34 +821,37 @@
// 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.
//
@@ -635,7 +860,7 @@
// 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.
//
@@ -646,10 +871,11 @@
#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);
@@ -659,7 +885,7 @@
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());
@@ -699,11 +925,46 @@
// 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;
@@ -725,6 +986,7 @@
pthread_attr_destroy(&attr);
}
+#endif
assert(os::current_stack_pointer() >= *bottom &&
os::current_stack_pointer() < *bottom + *size, "just checking");
}
@@ -753,51 +1015,49 @@
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();
@@ -805,7 +1065,7 @@
// 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));
}
@@ -825,31 +1085,31 @@
// 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]);
-#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("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->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/linux_x86/vm/os_linux_x86.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/os_bsd_x86.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP
+#ifndef OS_CPU_BSD_X86_VM_OS_BSD_X86_HPP
+#define OS_CPU_BSD_X86_VM_OS_BSD_X86_HPP
static void setup_fpu();
static bool supports_sse();
@@ -34,4 +34,4 @@
// Note: Currently only used in 64 bit Windows implementations
static bool register_code_area(char *low, char *high) { return true; }
-#endif // OS_CPU_LINUX_X86_VM_OS_LINUX_X86_HPP
+#endif // OS_CPU_BSD_X86_VM_OS_BSD_X86_HPP
--- src/os_cpu/linux_x86/vm/prefetch_linux_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/prefetch_bsd_x86.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_PREFETCH_LINUX_X86_INLINE_HPP
-#define OS_CPU_LINUX_X86_VM_PREFETCH_LINUX_X86_INLINE_HPP
+#ifndef OS_CPU_BSD_X86_VM_PREFETCH_BSD_X86_INLINE_HPP
+#define OS_CPU_BSD_X86_VM_PREFETCH_BSD_X86_INLINE_HPP
#include "runtime/prefetch.hpp"
@@ -44,4 +44,4 @@
#endif // AMD64
}
-#endif // OS_CPU_LINUX_X86_VM_PREFETCH_LINUX_X86_INLINE_HPP
+#endif // OS_CPU_BSD_X86_VM_PREFETCH_BSD_X86_INLINE_HPP
--- src/os_cpu/linux_x86/vm/threadLS_linux_x86.cpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.cpp 2011-07-26 20:21:21.000000000 -0600
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_linux.inline.hpp"
+#include "thread_bsd.inline.hpp"
// Map stack pointer (%esp) to thread pointer for faster TLS access
//
@@ -41,7 +41,7 @@
//
// If an application creates and destroys a lot of threads, usually the
// stack space freed by a thread will soon get reused by new thread
-// (this is especially true in NPTL or LinuxThreads in fixed-stack mode).
+// (this is especially true in NPTL or BsdThreads in fixed-stack mode).
// No memory page in _sp_map is wasted.
//
// However, it's still possible that we might end up populating &
@@ -49,7 +49,7 @@
// amount of live data in the table could be quite small. The max wastage
// is less than 4M bytes. If it becomes an issue, we could use madvise()
// with MADV_DONTNEED to reclaim unused (i.e. all-zero) pages in _sp_map.
-// MADV_DONTNEED on Linux keeps the virtual memory mapping, but zaps the
+// MADV_DONTNEED on Bsd keeps the virtual memory mapping, but zaps the
// physical memory page (i.e. similar to MADV_FREE on Solaris).
#ifndef AMD64
--- src/os_cpu/linux_x86/vm/threadLS_linux_x86.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/threadLS_bsd_x86.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,16 +22,18 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
+#ifndef OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
+#define OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
// Processor dependent parts of ThreadLocalStorage
#ifndef AMD64
- // map stack pointer to thread pointer - see notes in threadLS_linux_x86.cpp
+ // map stack pointer to thread pointer - see notes in threadLS_bsd_x86.cpp
#define SP_BITLENGTH 32
+#ifndef PAGE_SHIFT
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#endif
static Thread* _sp_map[1UL << (SP_BITLENGTH - PAGE_SHIFT)];
#endif // !AMD64
@@ -51,4 +53,4 @@
#endif // AMD64
}
-#endif // OS_CPU_LINUX_X86_VM_THREADLS_LINUX_X86_HPP
+#endif // OS_CPU_BSD_X86_VM_THREADLS_BSD_X86_HPP
--- src/os_cpu/linux_x86/vm/thread_linux_x86.cpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/thread_bsd_x86.cpp 2011-07-26 20:21:21.000000000 -0600
@@ -24,7 +24,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_linux.inline.hpp"
+#include "thread_bsd.inline.hpp"
// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
// currently interrupted by SIGPROF
@@ -51,7 +51,7 @@
intptr_t* ret_fp;
intptr_t* ret_sp;
- ExtendedPC addr = os::Linux::fetch_frame_from_ucontext(this, uc,
+ ExtendedPC addr = os::Bsd::fetch_frame_from_ucontext(this, uc,
&ret_sp, &ret_fp);
if (addr.pc() == NULL || ret_sp == NULL ) {
// ucontext wasn't useful
--- src/os_cpu/linux_x86/vm/thread_linux_x86.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/thread_bsd_x86.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_THREAD_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_VM_THREAD_LINUX_X86_HPP
+#ifndef OS_CPU_BSD_X86_VM_THREAD_BSD_X86_HPP
+#define OS_CPU_BSD_X86_VM_THREAD_BSD_X86_HPP
private:
void pd_initialize() {
@@ -67,4 +67,4 @@
static void enable_register_stack_guard() {}
static void disable_register_stack_guard() {}
-#endif // OS_CPU_LINUX_X86_VM_THREAD_LINUX_X86_HPP
+#endif // OS_CPU_BSD_X86_VM_THREAD_BSD_X86_HPP
--- src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
+#ifndef OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
+#define OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
// These are the OS and CPU-specific fields, types and integer
// constants required by the Serviceability Agent. This file is
@@ -34,7 +34,7 @@
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
- nonstatic_field(OSThread, _thread_id, pid_t) \
+ nonstatic_field(OSThread, _thread_id, pthread_t) \
nonstatic_field(OSThread, _pthread_id, pthread_t) \
/* This must be the last entry, and must be present */ \
last_entry()
@@ -62,4 +62,4 @@
/* This must be the last entry, and must be present */ \
last_entry()
-#endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
+#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
Files src/os_cpu/linux_x86/vm/vm_version_linux_x86.cpp and src/os_cpu/bsd_x86/vm/vm_version_bsd_x86.cpp are identical
Files src/os_cpu/linux_zero/vm/assembler_linux_zero.cpp and src/os_cpu/bsd_zero/vm/assembler_bsd_zero.cpp are identical
--- src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,144 +23,463 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
-#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
+#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
-#include "orderAccess_linux_zero.inline.hpp"
+#include "orderAccess_bsd_zero.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_zero.hpp"
-// Implementation of class atomic
-
-#ifdef M68K
+#include <sys/types.h>
+#ifdef __NetBSD__
+#include <sys/atomic.h>
+#elif __FreeBSD__
+
+#include <sys/types.h>
+#ifndef SPARC
+#include <machine/atomic.h>
+#else
/*
- * __m68k_cmpxchg
+ * On FreeBSD/sparc64, <machine/atomic.h> pulls in <machine/cpufunc.h>
+ * which includes definitions which cause conflicts with various
+ * definitions within HotSpot source. To avoid that, pull in those
+ * definitions verbatim instead of including the header. Yuck.
+ */
+
+/*-
+ * Copyright (c) 1998 Doug Rabson.
+ * Copyright (c) 2001 Jake Burkholder.
+ * All rights reserved.
*
- * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
- * Returns newval on success and oldval if no exchange happened.
- * This implementation is processor specific and works on
- * 68020 68030 68040 and 68060.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
*
- * It will not work on ColdFire, 68000 and 68010 since they lack the CAS
- * instruction.
- * Using a kernelhelper would be better for arch complete implementation.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*
*/
-static inline int __m68k_cmpxchg(int oldval, int newval, volatile int *ptr) {
- int ret;
- __asm __volatile ("cas%.l %0,%2,%1"
- : "=d" (ret), "+m" (*(ptr))
- : "d" (newval), "0" (oldval));
- return ret;
-}
-
-/* Perform an atomic compare and swap: if the current value of `*PTR'
- is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
- `*PTR' before the operation.*/
-static inline int m68k_compare_and_swap(volatile int *ptr,
- int oldval,
- int newval) {
- for (;;) {
- int prev = *ptr;
- if (prev != oldval)
- return prev;
-
- if (__m68k_cmpxchg (prev, newval, ptr) == newval)
- // Success.
- return prev;
-
- // We failed even though prev == oldval. Try again.
- }
-}
-
-/* Atomically add an int to memory. */
-static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) {
- for (;;) {
- // Loop until success.
-
- int prev = *ptr;
-
- if (__m68k_cmpxchg (prev, prev + add_value, ptr) == prev + add_value)
- return prev + add_value;
- }
-}
-
-/* Atomically write VALUE into `*PTR' and returns the previous
- contents of `*PTR'. */
-static inline int m68k_lock_test_and_set(volatile int *ptr, int newval) {
- for (;;) {
- // Loop until success.
- int prev = *ptr;
-
- if (__m68k_cmpxchg (prev, newval, ptr) == prev)
- return prev;
- }
-}
-#endif // M68K
+#include <machine/asi.h>
-#ifdef ARM
+/*
+ * Membar operand macros for use in other macros when # is a special
+ * character. Keep these in sync with what the hardware expects.
+ */
+#define M_LoadLoad (0)
+#define M_StoreLoad (1)
+#define M_LoadStore (2)
+#define M_StoreStore (3)
+
+#define CMASK_SHIFT (4)
+#define MMASK_SHIFT (0)
+
+#define CMASK_GEN(bit) ((1 << (bit)) << CMASK_SHIFT)
+#define MMASK_GEN(bit) ((1 << (bit)) << MMASK_SHIFT)
+
+#define LoadLoad MMASK_GEN(M_LoadLoad)
+#define StoreLoad MMASK_GEN(M_StoreLoad)
+#define LoadStore MMASK_GEN(M_LoadStore)
+#define StoreStore MMASK_GEN(M_StoreStore)
+
+#define casa(rs1, rs2, rd, asi) ({ \
+ u_int __rd = (uint32_t)(rd); \
+ __asm __volatile("casa [%2] %3, %4, %0" \
+ : "+r" (__rd), "=m" (*rs1) \
+ : "r" (rs1), "n" (asi), "r" (rs2), "m" (*rs1)); \
+ __rd; \
+})
+
+#define casxa(rs1, rs2, rd, asi) ({ \
+ u_long __rd = (uint64_t)(rd); \
+ __asm __volatile("casxa [%2] %3, %4, %0" \
+ : "+r" (__rd), "=m" (*rs1) \
+ : "r" (rs1), "n" (asi), "r" (rs2), "m" (*rs1)); \
+ __rd; \
+})
+
+#define membar(mask) do { \
+ __asm __volatile("membar %0" : : "n" (mask) : "memory"); \
+} while (0)
+
+#ifdef _KERNEL
+#define __ASI_ATOMIC ASI_N
+#else
+#define __ASI_ATOMIC ASI_P
+#endif
+
+#define mb() __asm__ __volatile__ ("membar #MemIssue": : :"memory")
+#define wmb() mb()
+#define rmb() mb()
/*
- * __kernel_cmpxchg
+ * Various simple arithmetic on memory which is atomic in the presence
+ * of interrupts and multiple processors. See atomic(9) for details.
+ * Note that efficient hardware support exists only for the 32 and 64
+ * bit variants; the 8 and 16 bit versions are not provided and should
+ * not be used in MI code.
*
- * Atomically store newval in *ptr if *ptr is equal to oldval for user space.
- * Return zero if *ptr was changed or non-zero if no exchange happened.
- * The C flag is also set if *ptr was changed to allow for assembly
- * optimization in the calling code.
+ * This implementation takes advantage of the fact that the sparc64
+ * cas instruction is both a load and a store. The loop is often coded
+ * as follows:
*
+ * do {
+ * expect = *p;
+ * new = expect + 1;
+ * } while (cas(p, expect, new) != expect);
+ *
+ * which performs an unnnecessary load on each iteration that the cas
+ * operation fails. Modified as follows:
+ *
+ * expect = *p;
+ * for (;;) {
+ * new = expect + 1;
+ * result = cas(p, expect, new);
+ * if (result == expect)
+ * break;
+ * expect = result;
+ * }
+ *
+ * the return value of cas is used to avoid the extra reload.
+ *
+ * The memory barriers provided by the acq and rel variants are intended
+ * to be sufficient for use of relaxed memory ordering. Due to the
+ * suggested assembly syntax of the membar operands containing a #
+ * character, they cannot be used in macros. The cmask and mmask bits
+ * are hard coded in machine/cpufunc.h and used here through macros.
+ * Hopefully sun will choose not to change the bit numbers.
*/
-typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
-#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0)
+#define itype(sz) uint ## sz ## _t
+#define atomic_cas_32(p, e, s) casa(p, e, s, __ASI_ATOMIC)
+#define atomic_cas_64(p, e, s) casxa(p, e, s, __ASI_ATOMIC)
+#define atomic_cas(p, e, s, sz) \
+ atomic_cas_ ## sz(p, e, s)
-/* Perform an atomic compare and swap: if the current value of `*PTR'
- is OLDVAL, then write NEWVAL into `*PTR'. Return the contents of
- `*PTR' before the operation.*/
-static inline int arm_compare_and_swap(volatile int *ptr,
- int oldval,
- int newval) {
- for (;;) {
- int prev = *ptr;
- if (prev != oldval)
- return prev;
+#define atomic_cas_acq(p, e, s, sz) ({ \
+ itype(sz) v; \
+ v = atomic_cas(p, e, s, sz); \
+ membar(LoadLoad | LoadStore); \
+ v; \
+})
+
+#define atomic_cas_rel(p, e, s, sz) ({ \
+ itype(sz) v; \
+ membar(LoadStore | StoreStore); \
+ v = atomic_cas(p, e, s, sz); \
+ v; \
+})
+
+#define atomic_op(p, op, v, sz) ({ \
+ itype(sz) e, r, s; \
+ for (e = *(volatile itype(sz) *)p;; e = r) { \
+ s = e op v; \
+ r = atomic_cas_ ## sz(p, e, s); \
+ if (r == e) \
+ break; \
+ } \
+ e; \
+})
+
+#define atomic_op_acq(p, op, v, sz) ({ \
+ itype(sz) t; \
+ t = atomic_op(p, op, v, sz); \
+ membar(LoadLoad | LoadStore); \
+ t; \
+})
+
+#define atomic_op_rel(p, op, v, sz) ({ \
+ itype(sz) t; \
+ membar(LoadStore | StoreStore); \
+ t = atomic_op(p, op, v, sz); \
+ t; \
+})
+
+#define atomic_load(p, sz) \
+ atomic_cas(p, 0, 0, sz)
+
+#define atomic_load_acq(p, sz) ({ \
+ itype(sz) v; \
+ v = atomic_load(p, sz); \
+ membar(LoadLoad | LoadStore); \
+ v; \
+})
+
+#define atomic_load_clear(p, sz) ({ \
+ itype(sz) e, r; \
+ for (e = *(volatile itype(sz) *)p;; e = r) { \
+ r = atomic_cas(p, e, 0, sz); \
+ if (r == e) \
+ break; \
+ } \
+ e; \
+})
+
+#define atomic_store(p, v, sz) do { \
+ itype(sz) e, r; \
+ for (e = *(volatile itype(sz) *)p;; e = r) { \
+ r = atomic_cas(p, e, v, sz); \
+ if (r == e) \
+ break; \
+ } \
+} while (0)
+
+#define atomic_store_rel(p, v, sz) do { \
+ membar(LoadStore | StoreStore); \
+ atomic_store(p, v, sz); \
+} while (0)
+
+#define ATOMIC_GEN(name, ptype, vtype, atype, sz) \
+ \
+static __inline vtype \
+atomic_add_ ## name(volatile ptype p, atype v) \
+{ \
+ return ((vtype)atomic_op(p, +, v, sz)); \
+} \
+static __inline vtype \
+atomic_add_acq_ ## name(volatile ptype p, atype v) \
+{ \
+ return ((vtype)atomic_op_acq(p, +, v, sz)); \
+} \
+static __inline vtype \
+atomic_add_rel_ ## name(volatile ptype p, atype v) \
+{ \
+ return ((vtype)atomic_op_rel(p, +, v, sz)); \
+} \
+ \
+static __inline int \
+atomic_cmpset_ ## name(volatile ptype p, vtype e, vtype s) \
+{ \
+ return (((vtype)atomic_cas(p, e, s, sz)) == e); \
+} \
+static __inline int \
+atomic_cmpset_acq_ ## name(volatile ptype p, vtype e, vtype s) \
+{ \
+ return (((vtype)atomic_cas_acq(p, e, s, sz)) == e); \
+} \
+static __inline int \
+atomic_cmpset_rel_ ## name(volatile ptype p, vtype e, vtype s) \
+{ \
+ return (((vtype)atomic_cas_rel(p, e, s, sz)) == e); \
+} \
+ \
+static __inline vtype \
+atomic_load_ ## name(volatile ptype p) \
+{ \
+ return ((vtype)atomic_cas(p, 0, 0, sz)); \
+} \
+static __inline vtype \
+atomic_load_acq_ ## name(volatile ptype p) \
+{ \
+ return ((vtype)atomic_cas_acq(p, 0, 0, sz)); \
+} \
+ \
+static __inline void \
+atomic_store_ ## name(volatile ptype p, vtype v) \
+{ \
+ atomic_store(p, v, sz); \
+} \
+static __inline void \
+atomic_store_rel_ ## name(volatile ptype p, vtype v) \
+{ \
+ atomic_store_rel(p, v, sz); \
+}
- if (__kernel_cmpxchg (prev, newval, ptr) == 0)
- // Success.
- return prev;
+inline jlong Atomic::load(volatile jlong* src) {
+ volatile jlong dest;
+ os::atomic_copy64(src, &dest);
+ return dest;
+}
- // We failed even though prev == oldval. Try again.
- }
+inline void Atomic::store(jlong store_value, jlong* dest) {
+ os::atomic_copy64((volatile jlong*)&store_value, (volatile jlong*)dest);
}
-/* Atomically add an int to memory. */
-static inline int arm_add_and_fetch(volatile int *ptr, int add_value) {
- for (;;) {
- // Loop until a __kernel_cmpxchg succeeds.
+inline void Atomic::store(jlong store_value, volatile jlong* dest) {
+ os::atomic_copy64((volatile jlong*)&store_value, dest);
+}
- int prev = *ptr;
+ATOMIC_GEN(int, u_int *, u_int, u_int, 32);
+ATOMIC_GEN(32, uint32_t *, uint32_t, uint32_t, 32);
- if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0)
- return prev + add_value;
- }
-}
+ATOMIC_GEN(long, u_long *, u_long, u_long, 64);
+ATOMIC_GEN(64, uint64_t *, uint64_t, uint64_t, 64);
-/* Atomically write VALUE into `*PTR' and returns the previous
- contents of `*PTR'. */
-static inline int arm_lock_test_and_set(volatile int *ptr, int newval) {
- for (;;) {
- // Loop until a __kernel_cmpxchg succeeds.
- int prev = *ptr;
+ATOMIC_GEN(ptr, uintptr_t *, uintptr_t, uintptr_t, 64);
- if (__kernel_cmpxchg (prev, newval, ptr) == 0)
- return prev;
- }
+#define atomic_fetchadd_int atomic_add_int
+#define atomic_fetchadd_32 atomic_add_32
+#define atomic_fetchadd_long atomic_add_long
+
+#undef ATOMIC_GEN
+#undef atomic_cas
+#undef atomic_cas_acq
+#undef atomic_cas_rel
+#undef atomic_op
+#undef atomic_op_acq
+#undef atomic_op_rel
+#undef atomic_load_acq
+#undef atomic_store_rel
+#undef atomic_load_clear
+#endif
+
+static __inline __attribute__((__always_inline__))
+unsigned int atomic_add_int_nv(volatile unsigned int* dest, unsigned int add_value)
+{
+ atomic_add_acq_int(dest, add_value);
+ return *dest;
+}
+
+static __inline __attribute__((__always_inline__))
+uintptr_t atomic_add_ptr_nv(volatile intptr_t* dest, intptr_t add_value)
+{
+ atomic_add_acq_ptr((volatile uintptr_t*) dest, (uintptr_t) add_value);
+ return *((volatile uintptr_t*) dest);
+}
+
+static __inline __attribute__((__always_inline__))
+unsigned int
+atomic_swap_uint(volatile unsigned int *dest, unsigned int exchange_value)
+{
+ jint prev = *dest;
+ atomic_store_rel_int(dest, exchange_value);
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+void *
+atomic_swap_ptr(volatile void *dest, void *exchange_value)
+{
+ void *prev = *(void **)dest;
+ atomic_store_rel_ptr((volatile uintptr_t*) dest, (uintptr_t) exchange_value);
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+unsigned int
+atomic_cas_uint(volatile unsigned int *dest, unsigned int compare_value,
+ unsigned int exchange_value)
+{
+ unsigned int prev = *dest;
+ atomic_cmpset_acq_int(dest, compare_value, exchange_value);
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+unsigned long
+atomic_cas_ulong(volatile unsigned long *dest, unsigned long compare_value,
+ unsigned long exchange_value)
+{
+ unsigned long prev = *dest;
+ atomic_cmpset_acq_long(dest, compare_value, exchange_value);
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+void *
+atomic_cas_ptr(volatile void *dest, void *compare_value, void *exchange_value)
+{
+ void *prev = *(void **)dest;
+ atomic_cmpset_acq_ptr((volatile uintptr_t*) dest, (uintptr_t) compare_value, (uintptr_t) exchange_value);
+ return prev;
+}
+
+#elif defined(__APPLE__)
+
+#include <libkern/OSAtomic.h>
+
+static __inline __attribute__((__always_inline__))
+unsigned int
+atomic_add_int_nv(volatile unsigned int *target, int delta) {
+ return (unsigned int) OSAtomicAdd32Barrier(delta, (volatile int32_t *) target);
+}
+
+static __inline __attribute__((__always_inline__))
+void *
+atomic_add_ptr_nv(volatile void *target, ssize_t delta) {
+#ifdef __LP64__
+ return (void *) OSAtomicAdd64Barrier(delta, (volatile int64_t *) target);
+#else
+ return (void *) OSAtomicAdd32Barrier(delta, (volatile int32_t *) target);
+#endif
+}
+
+
+static __inline __attribute__((__always_inline__))
+unsigned int
+atomic_swap_uint(volatile unsigned int *dest, unsigned int exchange_value)
+{
+ /* No xchg support in OSAtomic */
+ unsigned int prev;
+ do {
+ prev = *dest;
+ } while (!OSAtomicCompareAndSwapIntBarrier((int) prev, (int) exchange_value, (volatile int *) dest));
+
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+void *
+atomic_swap_ptr(volatile void *dest, void *exchange_value)
+{
+ /* No xchg support in OSAtomic */
+ void *prev;
+ do {
+ prev = *((void * volatile *) dest);
+ } while (!OSAtomicCompareAndSwapPtrBarrier(prev, exchange_value, (void * volatile *) dest));
+
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+unsigned int
+atomic_cas_uint(volatile unsigned int *dest, unsigned int compare_value,
+ unsigned int exchange_value)
+{
+ unsigned int prev = *dest;
+ OSAtomicCompareAndSwapIntBarrier(compare_value, exchange_value, (volatile int *) dest);
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+unsigned long
+atomic_cas_ulong(volatile unsigned long *dest, unsigned long compare_value,
+ unsigned long exchange_value)
+{
+ unsigned long prev = *dest;
+ OSAtomicCompareAndSwapLongBarrier(compare_value, exchange_value, (volatile long *) dest);
+ return prev;
+}
+
+static __inline __attribute__((__always_inline__))
+void *
+atomic_cas_ptr(volatile void *dest, void *compare_value, void *exchange_value)
+{
+ void *prev = *(void **)dest;
+ OSAtomicCompareAndSwapPtrBarrier(compare_value, exchange_value, (void * volatile *) dest);
+ return prev;
}
-#endif // ARM
+
+
+#endif
inline void Atomic::store(jint store_value, volatile jint* dest) {
*dest = store_value;
@@ -171,27 +490,11 @@
}
inline jint Atomic::add(jint add_value, volatile jint* dest) {
-#ifdef ARM
- return arm_add_and_fetch(dest, add_value);
-#else
-#ifdef M68K
- return m68k_add_and_fetch(dest, add_value);
-#else
- return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
-#endif // ARM
+ return (jint)atomic_add_int_nv((volatile unsigned int*) dest, add_value);
}
inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
-#ifdef ARM
- return arm_add_and_fetch(dest, add_value);
-#else
-#ifdef M68K
- return m68k_add_and_fetch(dest, add_value);
-#else
- return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
-#endif // ARM
+ return (intptr_t)atomic_add_ptr_nv(dest, add_value);
}
inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
@@ -223,95 +526,43 @@
}
inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) {
-#ifdef ARM
- return arm_lock_test_and_set(dest, exchange_value);
-#else
-#ifdef M68K
- return m68k_lock_test_and_set(dest, exchange_value);
-#else
- // __sync_lock_test_and_set is a bizarrely named atomic exchange
- // operation. Note that some platforms only support this with the
- // limitation that the only valid value to store is the immediate
- // constant 1. There is a test for this in JNI_CreateJavaVM().
- return __sync_lock_test_and_set (dest, exchange_value);
-#endif // M68K
-#endif // ARM
+ return (jint)atomic_swap_uint((volatile u_int *)dest, (u_int)exchange_value);
}
inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value,
volatile intptr_t* dest) {
-#ifdef ARM
- return arm_lock_test_and_set(dest, exchange_value);
-#else
-#ifdef M68K
- return m68k_lock_test_and_set(dest, exchange_value);
-#else
- return __sync_lock_test_and_set (dest, exchange_value);
-#endif // M68K
-#endif // ARM
+ return (intptr_t)atomic_swap_ptr((volatile void *)dest,
+ (void *)exchange_value);
}
inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
- return (void *) xchg_ptr((intptr_t) exchange_value,
- (volatile intptr_t*) dest);
+ return atomic_swap_ptr(dest, exchange_value);
}
inline jint Atomic::cmpxchg(jint exchange_value,
volatile jint* dest,
jint compare_value) {
-#ifdef ARM
- return arm_compare_and_swap(dest, compare_value, exchange_value);
-#else
-#ifdef M68K
- return m68k_compare_and_swap(dest, compare_value, exchange_value);
-#else
- return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
-#endif // M68K
-#endif // ARM
+ return atomic_cas_uint((volatile u_int *)dest, compare_value, exchange_value);
}
inline jlong Atomic::cmpxchg(jlong exchange_value,
volatile jlong* dest,
jlong compare_value) {
-
- return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
+ return atomic_cas_ulong((volatile u_long *)dest, compare_value,
+ exchange_value);
}
inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value,
volatile intptr_t* dest,
intptr_t compare_value) {
-#ifdef ARM
- return arm_compare_and_swap(dest, compare_value, exchange_value);
-#else
-#ifdef M68K
- return m68k_compare_and_swap(dest, compare_value, exchange_value);
-#else
- return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
-#endif // M68K
-#endif // ARM
+ return (intptr_t)atomic_cas_ptr((volatile void *)dest, (void *)compare_value,
+ (void *)exchange_value);
}
inline void* Atomic::cmpxchg_ptr(void* exchange_value,
volatile void* dest,
void* compare_value) {
-
- return (void *) cmpxchg_ptr((intptr_t) exchange_value,
- (volatile intptr_t*) dest,
- (intptr_t) compare_value);
-}
-
-inline jlong Atomic::load(volatile jlong* src) {
- volatile jlong dest;
- os::atomic_copy64(src, &dest);
- return dest;
-}
-
-inline void Atomic::store(jlong store_value, jlong* dest) {
- os::atomic_copy64((volatile jlong*)&store_value, (volatile jlong*)dest);
-}
-
-inline void Atomic::store(jlong store_value, volatile jlong* dest) {
- os::atomic_copy64((volatile jlong*)&store_value, dest);
+ return atomic_cas_ptr((volatile void *)dest, compare_value, exchange_value);
}
-#endif // OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
+#endif // OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
--- src/os_cpu/linux_zero/vm/bytes_linux_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/bytes_bsd_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,24 +22,31 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_BYTES_LINUX_ZERO_INLINE_HPP
-#define OS_CPU_LINUX_ZERO_VM_BYTES_LINUX_ZERO_INLINE_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_BYTES_BSD_ZERO_INLINE_HPP
+#define OS_CPU_BSD_ZERO_VM_BYTES_BSD_ZERO_INLINE_HPP
// Efficient swapping of data bytes from Java byte
// ordering to native byte ordering and vice versa.
-#include <byteswap.h>
+#ifdef __APPLE__
+#include <libkern/OSByteOrder.h>
+#define bswap16(x) OSSwapInt16(x)
+#define bswap32(x) OSSwapInt32(x)
+#define bswap64(x) OSSwapInt64(x)
+#else
+# include <sys/endian.h>
+#endif
inline u2 Bytes::swap_u2(u2 x) {
- return bswap_16(x);
+ return bswap16(x);
}
inline u4 Bytes::swap_u4(u4 x) {
- return bswap_32(x);
+ return bswap32(x);
}
inline u8 Bytes::swap_u8(u8 x) {
- return bswap_64(x);
+ return bswap64(x);
}
-#endif // OS_CPU_LINUX_ZERO_VM_BYTES_LINUX_ZERO_INLINE_HPP
+#endif // OS_CPU_BSD_ZERO_VM_BYTES_BSD_ZERO_INLINE_HPP
--- src/os_cpu/linux_zero/vm/globals_linux_zero.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/globals_bsd_zero.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,8 +23,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP
-#define OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
+#define OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
//
// Set the default values for platform dependent flags used by the
@@ -46,4 +46,4 @@
// Only used on 64 bit platforms
define_pd_global(uintx, HeapBaseMinAddress, 2*G);
-#endif // OS_CPU_LINUX_ZERO_VM_GLOBALS_LINUX_ZERO_HPP
+#endif // OS_CPU_BSD_ZERO_VM_GLOBALS_BSD_ZERO_HPP
--- src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,8 +23,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_ORDERACCESS_LINUX_ZERO_INLINE_HPP
-#define OS_CPU_LINUX_ZERO_VM_ORDERACCESS_LINUX_ZERO_INLINE_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_ORDERACCESS_BSD_ZERO_INLINE_HPP
+#define OS_CPU_BSD_ZERO_VM_ORDERACCESS_BSD_ZERO_INLINE_HPP
#include "runtime/orderAccess.hpp"
#include "vm_version_zero.hpp"
@@ -46,7 +46,12 @@
#else // ARM
+#ifdef __APPLE__
+#include <libkern/OSAtomic.h>
+#define FULL_MEM_BARRIER OSMemoryBarrier()
+#else
#define FULL_MEM_BARRIER __sync_synchronize()
+#endif // __APPLE__
#ifdef PPC
@@ -172,4 +177,4 @@
inline void OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); }
inline void OrderAccess::release_store_ptr_fence(volatile void* p, void* v) { release_store_ptr(p, v); fence(); }
-#endif // OS_CPU_LINUX_ZERO_VM_ORDERACCESS_LINUX_ZERO_INLINE_HPP
+#endif // OS_CPU_BSD_ZERO_VM_ORDERACCESS_BSD_ZERO_INLINE_HPP
--- src/os_cpu/linux_zero/vm/os_linux_zero.cpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,6 +23,10 @@
*
*/
+#if defined(_ALLBSD_SOURCE) && !defined(__APPLE__) && !defined(__NetBSD__)
+# include <pthread_np.h> /* For pthread_attr_get_np */
+#endif
+
// no precompiled headers
#include "assembler_zero.inline.hpp"
#include "classfile/classLoader.hpp"
@@ -31,11 +35,11 @@
#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_zero.hpp"
-#include "os_share_linux.hpp"
+#include "os_share_bsd.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
@@ -50,7 +54,7 @@
#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
@@ -102,7 +106,7 @@
// Nothing to do.
}
-address os::Linux::ucontext_get_pc(ucontext_t* uc) {
+address os::Bsd::ucontext_get_pc(ucontext_t* uc) {
ShouldNotCallThis();
}
@@ -117,7 +121,7 @@
}
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) {
@@ -130,14 +134,14 @@
// 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
+ // type). When that happens, 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)) {
@@ -151,7 +155,7 @@
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;
@@ -179,15 +183,16 @@
thread->disable_stack_red_zone();
ShouldNotCallThis();
}
+#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.
+ // 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 true;
}
@@ -197,6 +202,7 @@
fatal("recursive segv. expanding stack.");
}
}
+#endif
}
}
@@ -230,7 +236,7 @@
}
// signal-chaining
- if (os::Linux::chained_handler(sig, info, ucVoid)) {
+ if (os::Bsd::chained_handler(sig, info, ucVoid)) {
return true;
}
@@ -260,17 +266,19 @@
fatal(buf);
}
-void os::Linux::init_thread_fpu_state(void) {
+void os::Bsd::init_thread_fpu_state(void) {
// Nothing to do
}
-int os::Linux::get_fpu_control_word() {
+#ifndef _ALLBSD_SOURCE
+int os::Bsd::get_fpu_control_word() {
ShouldNotCallThis();
}
-void os::Linux::set_fpu_control_word(int fpu) {
+void os::Bsd::set_fpu_control_word(int fpu) {
ShouldNotCallThis();
}
+#endif
bool os::is_allocatable(size_t bytes) {
#ifdef _LP64
@@ -293,13 +301,13 @@
///////////////////////////////////////////////////////////////////////////////
// thread stack
-size_t os::Linux::min_stack_allowed = 64 * K;
+size_t os::Bsd::min_stack_allowed = 64 * K;
-bool os::Linux::supports_variable_stack_size() {
+bool os::Bsd::supports_variable_stack_size() {
return true;
}
-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
+size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
#ifdef _LP64
size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
#else
@@ -308,13 +316,55 @@
return s;
}
-size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
+size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
// Only enable glibc guard pages for non-Java threads
// (Java threads have HotSpot guard pages)
return (thr_type == java_thread ? 0 : page_size());
}
static void current_stack_region(address *bottom, size_t *size) {
+ address stack_bottom;
+ address stack_top;
+ size_t stack_bytes;
+
+#ifdef __APPLE__
+ pthread_t self = pthread_self();
+ stack_top = (address) pthread_get_stackaddr_np(self);
+ stack_bytes = pthread_get_stacksize_np(self);
+ stack_bottom = stack_top - stack_bytes;
+#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));
+
+ stack_top = (address) ss.ss_sp;
+ stack_bytes = ss.ss_size;
+ stack_bottom = stacktop - stack_bytes;
+#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 **) &stack_bottom) != 0 ||
+ pthread_attr_getstacksize(&attr, &stack_bytes) != 0) {
+ fatal("Can not locate current stack attributes!");
+ }
+
+ pthread_attr_destroy(&attr);
+
+ stack_top = stack_bottom + stack_bytes;
+#else /* Linux */
pthread_attr_t attr;
int res = pthread_getattr_np(pthread_self(), &attr);
if (res != 0) {
@@ -326,17 +376,15 @@
}
}
- address stack_bottom;
- size_t stack_bytes;
res = pthread_attr_getstack(&attr, (void **) &stack_bottom, &stack_bytes);
if (res != 0) {
fatal(err_msg("pthread_attr_getstack failed with errno = %d", res));
}
- address stack_top = stack_bottom + stack_bytes;
+ stack_top = stack_bottom + stack_bytes;
// The block of memory returned by pthread_attr_getstack() includes
// guard pages where present. We need to trim these off.
- size_t page_bytes = os::Linux::page_size();
+ size_t page_bytes = os::Bsd::page_size();
assert(((intptr_t) stack_bottom & (page_bytes - 1)) == 0, "unaligned stack");
size_t guard_bytes;
@@ -366,7 +414,7 @@
// The initial thread has a growable stack, and the size reported
// by pthread_attr_getstack is the maximum size it could possibly
// be given what currently mapped. This can be huge, so we cap it.
- if (os::Linux::is_initial_thread()) {
+ if (os::Bsd::is_initial_thread()) {
stack_bytes = stack_top - stack_bottom;
if (stack_bytes > JavaThread::stack_size_at_create())
@@ -374,6 +422,7 @@
stack_bottom = stack_top - stack_bytes;
}
+#endif
assert(os::current_stack_pointer() >= stack_bottom, "should do");
assert(os::current_stack_pointer() < stack_top, "should do");
@@ -409,7 +458,7 @@
}
/////////////////////////////////////////////////////////////////////////////
-// Stubs for things that would be in linux_zero.s if it existed.
+// Stubs for things that would be in bsd_zero.s if it existed.
// You probably want to disassemble these monkeys to check they're ok.
extern "C" {
--- src/os_cpu/linux_zero/vm/os_linux_zero.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/os_bsd_zero.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,8 +23,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_OS_LINUX_ZERO_HPP
-#define OS_CPU_LINUX_ZERO_VM_OS_LINUX_ZERO_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_OS_BSD_ZERO_HPP
+#define OS_CPU_BSD_ZERO_VM_OS_BSD_ZERO_HPP
static void setup_fpu() {}
@@ -53,4 +53,4 @@
#endif
}
-#endif // OS_CPU_LINUX_ZERO_VM_OS_LINUX_ZERO_HPP
+#endif // OS_CPU_BSD_ZERO_VM_OS_BSD_ZERO_HPP
--- src/os_cpu/linux_zero/vm/prefetch_linux_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/prefetch_bsd_zero.inline.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,8 +23,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_PREFETCH_LINUX_ZERO_INLINE_HPP
-#define OS_CPU_LINUX_ZERO_VM_PREFETCH_LINUX_ZERO_INLINE_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_PREFETCH_BSD_ZERO_INLINE_HPP
+#define OS_CPU_BSD_ZERO_VM_PREFETCH_BSD_ZERO_INLINE_HPP
#include "runtime/prefetch.hpp"
@@ -34,4 +34,4 @@
inline void Prefetch::write(void* loc, intx interval) {
}
-#endif // OS_CPU_LINUX_ZERO_VM_PREFETCH_LINUX_ZERO_INLINE_HPP
+#endif // OS_CPU_BSD_ZERO_VM_PREFETCH_BSD_ZERO_INLINE_HPP
--- src/os_cpu/linux_zero/vm/threadLS_linux_zero.cpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.cpp 2011-07-26 20:21:21.000000000 -0600
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "runtime/threadLocalStorage.hpp"
-#include "thread_linux.inline.hpp"
+#include "thread_bsd.inline.hpp"
void ThreadLocalStorage::generate_code_for_get_thread() {
// nothing to do
--- src/os_cpu/linux_zero/vm/threadLS_linux_zero.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/threadLS_bsd_zero.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -22,8 +22,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_THREADLS_LINUX_ZERO_HPP
-#define OS_CPU_LINUX_ZERO_VM_THREADLS_LINUX_ZERO_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
+#define OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
// Processor dependent parts of ThreadLocalStorage
@@ -32,4 +32,4 @@
return (Thread*) os::thread_local_storage_at(thread_index());
}
-#endif // OS_CPU_LINUX_ZERO_VM_THREADLS_LINUX_ZERO_HPP
+#endif // OS_CPU_BSD_ZERO_VM_THREADLS_BSD_ZERO_HPP
--- src/os_cpu/linux_zero/vm/thread_linux_zero.cpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/thread_bsd_zero.cpp 2011-07-26 20:21:21.000000000 -0600
@@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "runtime/frame.inline.hpp"
-#include "thread_linux.inline.hpp"
+#include "thread_bsd.inline.hpp"
void JavaThread::cache_global_variables() {
// nothing to do
--- src/os_cpu/linux_zero/vm/thread_linux_zero.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/thread_bsd_zero.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,8 +23,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_THREAD_LINUX_ZERO_HPP
-#define OS_CPU_LINUX_ZERO_VM_THREAD_LINUX_ZERO_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_THREAD_BSD_ZERO_HPP
+#define OS_CPU_BSD_ZERO_VM_THREAD_BSD_ZERO_HPP
private:
ZeroStack _zero_stack;
@@ -118,4 +118,4 @@
static void enable_register_stack_guard() {}
static void disable_register_stack_guard() {}
-#endif // OS_CPU_LINUX_ZERO_VM_THREAD_LINUX_ZERO_HPP
+#endif // OS_CPU_BSD_ZERO_VM_THREAD_BSD_ZERO_HPP
--- src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp 2011-07-26 20:21:21.000000000 -0600
+++ src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp 2011-07-26 20:21:21.000000000 -0600
@@ -23,8 +23,8 @@
*
*/
-#ifndef OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
-#define OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
+#ifndef OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
+#define OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
// These are the OS and CPU-specific fields, types and integer
// constants required by the Serviceability Agent. This file is
@@ -47,4 +47,4 @@
/* This must be the last entry, and must be present */ \
last_entry()
-#endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
+#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
Files src/os_cpu/linux_zero/vm/vm_version_linux_zero.cpp and src/os_cpu/bsd_zero/vm/vm_version_bsd_zero.cpp are identical
|