# HG changeset patch # User dholmes # Date 1471827397 14400 # Node ID 9f644073d3a0ddc4d00a7defd98a950f210f34ea # Parent d4f8e348420a9833e065bb89f6a66023774ce71a 8157907: Incorrect inclusion of atomic.hpp instead of atomic.inline.hpp Summary: Remove atomic.inline.hpp and move the contents back into atomic.hpp Reviewed-by: stefank, pliden, simonis diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp --- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,6 +28,7 @@ #include "runtime/globals_extension.hpp" #include "runtime/vm_version.hpp" +#include "utilities/sizes.hpp" class VM_Version : public Abstract_VM_Version { friend class JVMCIVMStructs; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -37,7 +37,7 @@ #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -52,7 +52,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -42,7 +42,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -42,7 +42,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -42,7 +42,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -45,7 +45,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os/windows/vm/threadCritical_windows.cpp --- a/hotspot/src/os/windows/vm/threadCritical_windows.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os/windows/vm/threadCritical_windows.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/thread.inline.hpp" #include "runtime/threadCritical.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,479 @@ +/* + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014 SAP SE. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_HPP +#define OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_HPP + +#ifndef _LP64 +#error "Atomic currently only impleneted for PPC64" +#endif + +// Implementation of class atomic + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +// +// machine barrier instructions: +// +// - ppc_sync two-way memory barrier, aka fence +// - ppc_lwsync orders Store|Store, +// Load|Store, +// Load|Load, +// but not Store|Load +// - ppc_eieio orders memory accesses for device memory (only) +// - ppc_isync invalidates speculatively executed instructions +// From the POWER ISA 2.06 documentation: +// "[...] an isync instruction prevents the execution of +// instructions following the isync until instructions +// preceding the isync have completed, [...]" +// From IBM's AIX assembler reference: +// "The isync [...] instructions causes the processor to +// refetch any instructions that might have been fetched +// prior to the isync instruction. The instruction isync +// causes the processor to wait for all previous instructions +// to complete. Then any instructions already fetched are +// discarded and instruction processing continues in the +// environment established by the previous instructions." +// +// semantic barrier instructions: +// (as defined in orderAccess.hpp) +// +// - ppc_release orders Store|Store, (maps to ppc_lwsync) +// Load|Store +// - ppc_acquire orders Load|Store, (maps to ppc_lwsync) +// Load|Load +// - ppc_fence orders Store|Store, (maps to ppc_sync) +// Load|Store, +// Load|Load, +// Store|Load +// + +#define strasm_sync "\n sync \n" +#define strasm_lwsync "\n lwsync \n" +#define strasm_isync "\n isync \n" +#define strasm_release strasm_lwsync +#define strasm_acquire strasm_lwsync +#define strasm_fence strasm_sync +#define strasm_nobarrier "" +#define strasm_nobarrier_clobber_memory "" + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + + unsigned int result; + + __asm__ __volatile__ ( + strasm_lwsync + "1: lwarx %0, 0, %2 \n" + " add %0, %0, %1 \n" + " stwcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_isync + : /*%0*/"=&r" (result) + : /*%1*/"r" (add_value), /*%2*/"r" (dest) + : "cc", "memory" ); + + return (jint) result; +} + + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + + long result; + + __asm__ __volatile__ ( + strasm_lwsync + "1: ldarx %0, 0, %2 \n" + " add %0, %0, %1 \n" + " stdcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_isync + : /*%0*/"=&r" (result) + : /*%1*/"r" (add_value), /*%2*/"r" (dest) + : "cc", "memory" ); + + return (intptr_t) result; +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add_ptr(add_value, (volatile intptr_t*)dest); +} + + +inline void Atomic::inc (volatile jint* dest) { + + unsigned int temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: lwarx %0, 0, %2 \n" + " addic %0, %0, 1 \n" + " stwcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + + long temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: ldarx %0, 0, %2 \n" + " addic %0, %0, 1 \n" + " stdcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::inc_ptr(volatile void* dest) { + inc_ptr((volatile intptr_t*)dest); +} + + +inline void Atomic::dec (volatile jint* dest) { + + unsigned int temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: lwarx %0, 0, %2 \n" + " addic %0, %0, -1 \n" + " stwcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + + long temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: ldarx %0, 0, %2 \n" + " addic %0, %0, -1 \n" + " stdcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::dec_ptr(volatile void* dest) { + dec_ptr((volatile intptr_t*)dest); +} + +inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { + + // Note that xchg_ptr doesn't necessarily do an acquire + // (see synchronizer.cpp). + + unsigned int old_value; + const uint64_t zero = 0; + + __asm__ __volatile__ ( + /* lwsync */ + strasm_lwsync + /* atomic loop */ + "1: \n" + " lwarx %[old_value], %[dest], %[zero] \n" + " stwcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* isync */ + strasm_sync + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + return (jint) old_value; +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + + // Note that xchg_ptr doesn't necessarily do an acquire + // (see synchronizer.cpp). + + long old_value; + const uint64_t zero = 0; + + __asm__ __volatile__ ( + /* lwsync */ + strasm_lwsync + /* atomic loop */ + "1: \n" + " ldarx %[old_value], %[dest], %[zero] \n" + " stdcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* isync */ + strasm_sync + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + return (intptr_t) old_value; +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); +} + +inline void cmpxchg_pre_membar(cmpxchg_memory_order order) { + if (order != memory_order_relaxed) { + __asm__ __volatile__ ( + /* fence */ + strasm_sync + ); + } +} + +inline void cmpxchg_post_membar(cmpxchg_memory_order order) { + if (order != memory_order_relaxed) { + __asm__ __volatile__ ( + /* fence */ + strasm_sync + ); + } +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + + // Note that cmpxchg guarantees a two-way memory barrier across + // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not + // specified otherwise (see atomic.hpp). + + // Using 32 bit internally. + volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3); + +#ifdef VM_LITTLE_ENDIAN + const unsigned int shift_amount = ((uintptr_t)dest & 3) * 8; +#else + const unsigned int shift_amount = ((~(uintptr_t)dest) & 3) * 8; +#endif + const unsigned int masked_compare_val = ((unsigned int)(unsigned char)compare_value), + masked_exchange_val = ((unsigned int)(unsigned char)exchange_value), + xor_value = (masked_compare_val ^ masked_exchange_val) << shift_amount; + + unsigned int old_value, value32; + + cmpxchg_pre_membar(order); + + __asm__ __volatile__ ( + /* simple guard */ + " lbz %[old_value], 0(%[dest]) \n" + " cmpw %[masked_compare_val], %[old_value] \n" + " bne- 2f \n" + /* atomic loop */ + "1: \n" + " lwarx %[value32], 0, %[dest_base] \n" + /* extract byte and compare */ + " srd %[old_value], %[value32], %[shift_amount] \n" + " clrldi %[old_value], %[old_value], 56 \n" + " cmpw %[masked_compare_val], %[old_value] \n" + " bne- 2f \n" + /* replace byte and try to store */ + " xor %[value32], %[xor_value], %[value32] \n" + " stwcx. %[value32], 0, %[dest_base] \n" + " bne- 1b \n" + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + [value32] "=&r" (value32), + "=m" (*dest), + "=m" (*dest_base) + /* in */ + : [dest] "b" (dest), + [dest_base] "b" (dest_base), + [shift_amount] "r" (shift_amount), + [masked_compare_val] "r" (masked_compare_val), + [xor_value] "r" (xor_value), + "m" (*dest), + "m" (*dest_base) + /* clobber */ + : "cc", + "memory" + ); + + cmpxchg_post_membar(order); + + return (jbyte)(unsigned char)old_value; +} + +inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + + // Note that cmpxchg guarantees a two-way memory barrier across + // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not + // specified otherwise (see atomic.hpp). + + unsigned int old_value; + const uint64_t zero = 0; + + cmpxchg_pre_membar(order); + + __asm__ __volatile__ ( + /* simple guard */ + " lwz %[old_value], 0(%[dest]) \n" + " cmpw %[compare_value], %[old_value] \n" + " bne- 2f \n" + /* atomic loop */ + "1: \n" + " lwarx %[old_value], %[dest], %[zero] \n" + " cmpw %[compare_value], %[old_value] \n" + " bne- 2f \n" + " stwcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [compare_value] "r" (compare_value), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + cmpxchg_post_membar(order); + + return (jint) old_value; +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + + // Note that cmpxchg guarantees a two-way memory barrier across + // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not + // specified otherwise (see atomic.hpp). + + long old_value; + const uint64_t zero = 0; + + cmpxchg_pre_membar(order); + + __asm__ __volatile__ ( + /* simple guard */ + " ld %[old_value], 0(%[dest]) \n" + " cmpd %[compare_value], %[old_value] \n" + " bne- 2f \n" + /* atomic loop */ + "1: \n" + " ldarx %[old_value], %[dest], %[zero] \n" + " cmpd %[compare_value], %[old_value] \n" + " bne- 2f \n" + " stdcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [compare_value] "r" (compare_value), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + cmpxchg_post_membar(order); + + return (jlong) old_value; +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +#undef strasm_sync +#undef strasm_lwsync +#undef strasm_isync +#undef strasm_release +#undef strasm_acquire +#undef strasm_fence +#undef strasm_nobarrier +#undef strasm_nobarrier_clobber_memory + +#endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp --- a/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,482 +0,0 @@ -/* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP -#define OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -#ifndef _LP64 -#error "Atomic currently only impleneted for PPC64" -#endif - -// Implementation of class atomic - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -// -// machine barrier instructions: -// -// - ppc_sync two-way memory barrier, aka fence -// - ppc_lwsync orders Store|Store, -// Load|Store, -// Load|Load, -// but not Store|Load -// - ppc_eieio orders memory accesses for device memory (only) -// - ppc_isync invalidates speculatively executed instructions -// From the POWER ISA 2.06 documentation: -// "[...] an isync instruction prevents the execution of -// instructions following the isync until instructions -// preceding the isync have completed, [...]" -// From IBM's AIX assembler reference: -// "The isync [...] instructions causes the processor to -// refetch any instructions that might have been fetched -// prior to the isync instruction. The instruction isync -// causes the processor to wait for all previous instructions -// to complete. Then any instructions already fetched are -// discarded and instruction processing continues in the -// environment established by the previous instructions." -// -// semantic barrier instructions: -// (as defined in orderAccess.hpp) -// -// - ppc_release orders Store|Store, (maps to ppc_lwsync) -// Load|Store -// - ppc_acquire orders Load|Store, (maps to ppc_lwsync) -// Load|Load -// - ppc_fence orders Store|Store, (maps to ppc_sync) -// Load|Store, -// Load|Load, -// Store|Load -// - -#define strasm_sync "\n sync \n" -#define strasm_lwsync "\n lwsync \n" -#define strasm_isync "\n isync \n" -#define strasm_release strasm_lwsync -#define strasm_acquire strasm_lwsync -#define strasm_fence strasm_sync -#define strasm_nobarrier "" -#define strasm_nobarrier_clobber_memory "" - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - - unsigned int result; - - __asm__ __volatile__ ( - strasm_lwsync - "1: lwarx %0, 0, %2 \n" - " add %0, %0, %1 \n" - " stwcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_isync - : /*%0*/"=&r" (result) - : /*%1*/"r" (add_value), /*%2*/"r" (dest) - : "cc", "memory" ); - - return (jint) result; -} - - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - - long result; - - __asm__ __volatile__ ( - strasm_lwsync - "1: ldarx %0, 0, %2 \n" - " add %0, %0, %1 \n" - " stdcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_isync - : /*%0*/"=&r" (result) - : /*%1*/"r" (add_value), /*%2*/"r" (dest) - : "cc", "memory" ); - - return (intptr_t) result; -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add_ptr(add_value, (volatile intptr_t*)dest); -} - - -inline void Atomic::inc (volatile jint* dest) { - - unsigned int temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: lwarx %0, 0, %2 \n" - " addic %0, %0, 1 \n" - " stwcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - - long temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: ldarx %0, 0, %2 \n" - " addic %0, %0, 1 \n" - " stdcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::inc_ptr(volatile void* dest) { - inc_ptr((volatile intptr_t*)dest); -} - - -inline void Atomic::dec (volatile jint* dest) { - - unsigned int temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: lwarx %0, 0, %2 \n" - " addic %0, %0, -1 \n" - " stwcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - - long temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: ldarx %0, 0, %2 \n" - " addic %0, %0, -1 \n" - " stdcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::dec_ptr(volatile void* dest) { - dec_ptr((volatile intptr_t*)dest); -} - -inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { - - // Note that xchg_ptr doesn't necessarily do an acquire - // (see synchronizer.cpp). - - unsigned int old_value; - const uint64_t zero = 0; - - __asm__ __volatile__ ( - /* lwsync */ - strasm_lwsync - /* atomic loop */ - "1: \n" - " lwarx %[old_value], %[dest], %[zero] \n" - " stwcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* isync */ - strasm_sync - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - return (jint) old_value; -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - - // Note that xchg_ptr doesn't necessarily do an acquire - // (see synchronizer.cpp). - - long old_value; - const uint64_t zero = 0; - - __asm__ __volatile__ ( - /* lwsync */ - strasm_lwsync - /* atomic loop */ - "1: \n" - " ldarx %[old_value], %[dest], %[zero] \n" - " stdcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* isync */ - strasm_sync - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - return (intptr_t) old_value; -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); -} - -inline void cmpxchg_pre_membar(cmpxchg_memory_order order) { - if (order != memory_order_relaxed) { - __asm__ __volatile__ ( - /* fence */ - strasm_sync - ); - } -} - -inline void cmpxchg_post_membar(cmpxchg_memory_order order) { - if (order != memory_order_relaxed) { - __asm__ __volatile__ ( - /* fence */ - strasm_sync - ); - } -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - - // Note that cmpxchg guarantees a two-way memory barrier across - // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not - // specified otherwise (see atomic.hpp). - - // Using 32 bit internally. - volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3); - -#ifdef VM_LITTLE_ENDIAN - const unsigned int shift_amount = ((uintptr_t)dest & 3) * 8; -#else - const unsigned int shift_amount = ((~(uintptr_t)dest) & 3) * 8; -#endif - const unsigned int masked_compare_val = ((unsigned int)(unsigned char)compare_value), - masked_exchange_val = ((unsigned int)(unsigned char)exchange_value), - xor_value = (masked_compare_val ^ masked_exchange_val) << shift_amount; - - unsigned int old_value, value32; - - cmpxchg_pre_membar(order); - - __asm__ __volatile__ ( - /* simple guard */ - " lbz %[old_value], 0(%[dest]) \n" - " cmpw %[masked_compare_val], %[old_value] \n" - " bne- 2f \n" - /* atomic loop */ - "1: \n" - " lwarx %[value32], 0, %[dest_base] \n" - /* extract byte and compare */ - " srd %[old_value], %[value32], %[shift_amount] \n" - " clrldi %[old_value], %[old_value], 56 \n" - " cmpw %[masked_compare_val], %[old_value] \n" - " bne- 2f \n" - /* replace byte and try to store */ - " xor %[value32], %[xor_value], %[value32] \n" - " stwcx. %[value32], 0, %[dest_base] \n" - " bne- 1b \n" - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - [value32] "=&r" (value32), - "=m" (*dest), - "=m" (*dest_base) - /* in */ - : [dest] "b" (dest), - [dest_base] "b" (dest_base), - [shift_amount] "r" (shift_amount), - [masked_compare_val] "r" (masked_compare_val), - [xor_value] "r" (xor_value), - "m" (*dest), - "m" (*dest_base) - /* clobber */ - : "cc", - "memory" - ); - - cmpxchg_post_membar(order); - - return (jbyte)(unsigned char)old_value; -} - -inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - - // Note that cmpxchg guarantees a two-way memory barrier across - // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not - // specified otherwise (see atomic.hpp). - - unsigned int old_value; - const uint64_t zero = 0; - - cmpxchg_pre_membar(order); - - __asm__ __volatile__ ( - /* simple guard */ - " lwz %[old_value], 0(%[dest]) \n" - " cmpw %[compare_value], %[old_value] \n" - " bne- 2f \n" - /* atomic loop */ - "1: \n" - " lwarx %[old_value], %[dest], %[zero] \n" - " cmpw %[compare_value], %[old_value] \n" - " bne- 2f \n" - " stwcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [compare_value] "r" (compare_value), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - cmpxchg_post_membar(order); - - return (jint) old_value; -} - -inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - - // Note that cmpxchg guarantees a two-way memory barrier across - // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not - // specified otherwise (see atomic.hpp). - - long old_value; - const uint64_t zero = 0; - - cmpxchg_pre_membar(order); - - __asm__ __volatile__ ( - /* simple guard */ - " ld %[old_value], 0(%[dest]) \n" - " cmpd %[compare_value], %[old_value] \n" - " bne- 2f \n" - /* atomic loop */ - "1: \n" - " ldarx %[old_value], %[dest], %[zero] \n" - " cmpd %[compare_value], %[old_value] \n" - " bne- 2f \n" - " stdcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [compare_value] "r" (compare_value), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - cmpxchg_post_membar(order); - - return (jlong) old_value; -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -#undef strasm_sync -#undef strasm_lwsync -#undef strasm_isync -#undef strasm_release -#undef strasm_acquire -#undef strasm_fence -#undef strasm_nobarrier -#undef strasm_nobarrier_clobber_memory - -#endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,227 @@ +/* + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP +#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP + +#include "runtime/os.hpp" + +// Implementation of class atomic + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + + +// Adding a lock prefix to an instruction on MP machine +#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: " + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + jint addend = add_value; + int mp = os::is_MP(); + __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)" + : "=r" (addend) + : "0" (addend), "r" (dest), "r" (mp) + : "cc", "memory"); + return addend + add_value; +} + +inline void Atomic::inc (volatile jint* dest) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" : + : "r" (dest), "r" (mp) : "cc", "memory"); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + inc_ptr((volatile intptr_t*)dest); +} + +inline void Atomic::dec (volatile jint* dest) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" : + : "r" (dest), "r" (mp) : "cc", "memory"); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + dec_ptr((volatile intptr_t*)dest); +} + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + __asm__ volatile ( "xchgl (%2),%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return 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); +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" + : "=a" (exchange_value) + : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +} + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" + : "=a" (exchange_value) + : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +} + +#ifdef AMD64 +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + intptr_t addend = add_value; + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" + : "=r" (addend) + : "0" (addend), "r" (dest), "r" (mp) + : "cc", "memory"); + return addend + add_value; +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add_ptr(add_value, (volatile intptr_t*)dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)" + : + : "r" (dest), "r" (mp) + : "cc", "memory"); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)" + : + : "r" (dest), "r" (mp) + : "cc", "memory"); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + __asm__ __volatile__ ("xchgq (%2),%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return exchange_value; +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" + : "=a" (exchange_value) + : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +#else // !AMD64 + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)Atomic::add((jint)add_value, (volatile jint*)dest); +} + + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + inc((volatile jint*)dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + dec((volatile jint*)dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); +} + +extern "C" { + // defined in bsd_x86.s + jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool); + void _Atomic_move_long(volatile jlong* src, volatile jlong* dst); +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP()); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline jlong Atomic::load(volatile jlong* src) { + volatile jlong dest; + _Atomic_move_long(src, &dest); + return dest; +} + +inline void Atomic::store(jlong store_value, jlong* dest) { + _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); +} + +inline void Atomic::store(jlong store_value, volatile jlong* dest) { + _Atomic_move_long((volatile jlong*)&store_value, dest); +} + +#endif // AMD64 + +#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp --- a/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP -#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -// Implementation of class atomic - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - - -// Adding a lock prefix to an instruction on MP machine -#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: " - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - jint addend = add_value; - int mp = os::is_MP(); - __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)" - : "=r" (addend) - : "0" (addend), "r" (dest), "r" (mp) - : "cc", "memory"); - return addend + add_value; -} - -inline void Atomic::inc (volatile jint* dest) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" : - : "r" (dest), "r" (mp) : "cc", "memory"); -} - -inline void Atomic::inc_ptr(volatile void* dest) { - inc_ptr((volatile intptr_t*)dest); -} - -inline void Atomic::dec (volatile jint* dest) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" : - : "r" (dest), "r" (mp) : "cc", "memory"); -} - -inline void Atomic::dec_ptr(volatile void* dest) { - dec_ptr((volatile intptr_t*)dest); -} - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - __asm__ volatile ( "xchgl (%2),%0" - : "=r" (exchange_value) - : "0" (exchange_value), "r" (dest) - : "memory"); - return 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); -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" - : "=a" (exchange_value) - : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -} - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" - : "=a" (exchange_value) - : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -} - -#ifdef AMD64 -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - intptr_t addend = add_value; - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" - : "=r" (addend) - : "0" (addend), "r" (dest), "r" (mp) - : "cc", "memory"); - return addend + add_value; -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add_ptr(add_value, (volatile intptr_t*)dest); -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)" - : - : "r" (dest), "r" (mp) - : "cc", "memory"); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)" - : - : "r" (dest), "r" (mp) - : "cc", "memory"); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - __asm__ __volatile__ ("xchgq (%2),%0" - : "=r" (exchange_value) - : "0" (exchange_value), "r" (dest) - : "memory"); - return exchange_value; -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" - : "=a" (exchange_value) - : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -#else // !AMD64 - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)Atomic::add((jint)add_value, (volatile jint*)dest); -} - - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - inc((volatile jint*)dest); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - dec((volatile jint*)dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); -} - -extern "C" { - // defined in bsd_x86.s - jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool); - void _Atomic_move_long(volatile jlong* src, volatile jlong* dst); -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP()); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline jlong Atomic::load(volatile jlong* src) { - volatile jlong dest; - _Atomic_move_long(src, &dest); - return dest; -} - -inline void Atomic::store(jlong store_value, jlong* dest) { - _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); -} - -inline void Atomic::store(jlong store_value, volatile jlong* dest) { - _Atomic_move_long((volatile jlong*)&store_value, dest); -} - -#endif // AMD64 - -#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp --- a/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #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.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_HPP +#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_HPP + +#include "runtime/os.hpp" + +// Implementation of class atomic + +#ifdef M68K + +/* + * __m68k_cmpxchg + * + * 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. + * + * 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. + * + */ + +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 + +#ifdef ARM + +/* + * __kernel_cmpxchg + * + * 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. + * + */ + +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) + + + +/* 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; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + // Success. + return prev; + + // We failed even though prev == oldval. Try again. + } +} + +/* 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. + + int prev = *ptr; + + if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) + return prev + add_value; + } +} + +/* 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; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + return prev; + } +} +#endif // ARM + +inline void Atomic::store(jint store_value, volatile jint* dest) { +#if !defined(ARM) && !defined(M68K) + __sync_synchronize(); +#endif + *dest = store_value; +} + +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { +#if !defined(ARM) && !defined(M68K) + __sync_synchronize(); +#endif + *dest = store_value; +} + +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 +} + +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 +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void *) add_ptr(add_value, (volatile intptr_t *) dest); +} + +inline void Atomic::inc(volatile jint* dest) { + add(1, dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + add_ptr(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + add_ptr(1, dest); +} + +inline void Atomic::dec(volatile jint* dest) { + add(-1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + add_ptr(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + add_ptr(-1, dest); +} + +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(). + jint result = __sync_lock_test_and_set (dest, exchange_value); + // All atomic operations are expected to be full memory barriers + // (see atomic.hpp). However, __sync_lock_test_and_set is not + // a full memory barrier, but an acquire barrier. Hence, this added + // barrier. + __sync_synchronize(); + return result; +#endif // M68K +#endif // ARM +} + +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 + intptr_t result = __sync_lock_test_and_set (dest, exchange_value); + __sync_synchronize(); + return result; +#endif // M68K +#endif // ARM +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void *) xchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest); +} + +inline jint Atomic::cmpxchg(jint exchange_value, + volatile jint* dest, + jint compare_value, + cmpxchg_memory_order order) { +#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 +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, + volatile jlong* dest, + jlong compare_value, + cmpxchg_memory_order order) { + + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, + volatile intptr_t* dest, + intptr_t compare_value, + cmpxchg_memory_order order) { +#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 +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, + volatile void* dest, + void* compare_value, + cmpxchg_memory_order order) { + + return (void *) cmpxchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest, + (intptr_t) compare_value, + order); +} + +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); +} + +#endif // OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp --- a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,334 +0,0 @@ -/* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP -#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -// Implementation of class atomic - -#ifdef M68K - -/* - * __m68k_cmpxchg - * - * 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. - * - * 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. - * - */ - -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 - -#ifdef ARM - -/* - * __kernel_cmpxchg - * - * 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. - * - */ - -typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); -#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) - - - -/* 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; - - if (__kernel_cmpxchg (prev, newval, ptr) == 0) - // Success. - return prev; - - // We failed even though prev == oldval. Try again. - } -} - -/* 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. - - int prev = *ptr; - - if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) - return prev + add_value; - } -} - -/* 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; - - if (__kernel_cmpxchg (prev, newval, ptr) == 0) - return prev; - } -} -#endif // ARM - -inline void Atomic::store(jint store_value, volatile jint* dest) { -#if !defined(ARM) && !defined(M68K) - __sync_synchronize(); -#endif - *dest = store_value; -} - -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { -#if !defined(ARM) && !defined(M68K) - __sync_synchronize(); -#endif - *dest = store_value; -} - -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 -} - -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 -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void *) add_ptr(add_value, (volatile intptr_t *) dest); -} - -inline void Atomic::inc(volatile jint* dest) { - add(1, dest); -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - add_ptr(1, dest); -} - -inline void Atomic::inc_ptr(volatile void* dest) { - add_ptr(1, dest); -} - -inline void Atomic::dec(volatile jint* dest) { - add(-1, dest); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - add_ptr(-1, dest); -} - -inline void Atomic::dec_ptr(volatile void* dest) { - add_ptr(-1, dest); -} - -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(). - jint result = __sync_lock_test_and_set (dest, exchange_value); - // All atomic operations are expected to be full memory barriers - // (see atomic.hpp). However, __sync_lock_test_and_set is not - // a full memory barrier, but an acquire barrier. Hence, this added - // barrier. - __sync_synchronize(); - return result; -#endif // M68K -#endif // ARM -} - -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 - intptr_t result = __sync_lock_test_and_set (dest, exchange_value); - __sync_synchronize(); - return result; -#endif // M68K -#endif // ARM -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void *) xchg_ptr((intptr_t) exchange_value, - (volatile intptr_t*) dest); -} - -inline jint Atomic::cmpxchg(jint exchange_value, - volatile jint* dest, - jint compare_value, - cmpxchg_memory_order order) { -#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 -} - -inline jlong Atomic::cmpxchg(jlong exchange_value, - volatile jlong* dest, - jlong compare_value, - cmpxchg_memory_order order) { - - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, - volatile intptr_t* dest, - intptr_t compare_value, - cmpxchg_memory_order order) { -#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 -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, - volatile void* dest, - void* compare_value, - cmpxchg_memory_order order) { - - return (void *) cmpxchg_ptr((intptr_t) exchange_value, - (volatile intptr_t*) dest, - (intptr_t) compare_value, - order); -} - -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); -} - -#endif // OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_HPP +#define OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_HPP + +#include "vm_version_aarch64.hpp" + +// Implementation of class atomic + +#define FULL_MEM_BARRIER __sync_synchronize() +#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); +#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + + +inline jint Atomic::add(jint add_value, volatile jint* dest) +{ + return __sync_add_and_fetch(dest, add_value); +} + +inline void Atomic::inc(volatile jint* dest) +{ + add(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) +{ + add_ptr(1, dest); +} + +inline void Atomic::dec (volatile jint* dest) +{ + add(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) +{ + add_ptr(-1, dest); +} + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) +{ + jint res = __sync_lock_test_and_set (dest, exchange_value); + FULL_MEM_BARRIER; + return res; +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) +{ + return (void *) xchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest); +} + +template T generic_cmpxchg(T exchange_value, volatile T* dest, + T compare_value, cmpxchg_memory_order order) +{ + if (order == memory_order_relaxed) { + T value = compare_value; + __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, + __ATOMIC_RELAXED, __ATOMIC_RELAXED); + return value; + } else { + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); + } +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) +{ + return generic_cmpxchg(exchange_value, dest, compare_value, order); +} + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) +{ + return generic_cmpxchg(exchange_value, dest, compare_value, order); +} + +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) +{ + return __sync_add_and_fetch(dest, add_value); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) +{ + return (void *) add_ptr(add_value, (volatile intptr_t *) dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) +{ + add_ptr(1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) +{ + add_ptr(-1, dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) +{ + intptr_t res = __sync_lock_test_and_set (dest, exchange_value); + FULL_MEM_BARRIER; + return res; +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) +{ + return generic_cmpxchg(exchange_value, dest, compare_value, order); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) +{ + return generic_cmpxchg(exchange_value, dest, compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) +{ + return (void *) cmpxchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest, + (intptr_t) compare_value, + order); +} + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +#endif // OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.inline.hpp --- a/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -/* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2014, Red Hat Inc. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP -#define OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" -#include "vm_version_aarch64.hpp" - -// Implementation of class atomic - -#define FULL_MEM_BARRIER __sync_synchronize() -#define READ_MEM_BARRIER __atomic_thread_fence(__ATOMIC_ACQUIRE); -#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE); - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - - -inline jint Atomic::add(jint add_value, volatile jint* dest) -{ - return __sync_add_and_fetch(dest, add_value); -} - -inline void Atomic::inc(volatile jint* dest) -{ - add(1, dest); -} - -inline void Atomic::inc_ptr(volatile void* dest) -{ - add_ptr(1, dest); -} - -inline void Atomic::dec (volatile jint* dest) -{ - add(-1, dest); -} - -inline void Atomic::dec_ptr(volatile void* dest) -{ - add_ptr(-1, dest); -} - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) -{ - jint res = __sync_lock_test_and_set (dest, exchange_value); - FULL_MEM_BARRIER; - return res; -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) -{ - return (void *) xchg_ptr((intptr_t) exchange_value, - (volatile intptr_t*) dest); -} - -template T generic_cmpxchg(T exchange_value, volatile T* dest, - T compare_value, cmpxchg_memory_order order) -{ - if (order == memory_order_relaxed) { - T value = compare_value; - __atomic_compare_exchange(dest, &value, &exchange_value, /*weak*/false, - __ATOMIC_RELAXED, __ATOMIC_RELAXED); - return value; - } else { - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); - } -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) -{ - return generic_cmpxchg(exchange_value, dest, compare_value, order); -} - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) -{ - return generic_cmpxchg(exchange_value, dest, compare_value, order); -} - -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) -{ - return __sync_add_and_fetch(dest, add_value); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) -{ - return (void *) add_ptr(add_value, (volatile intptr_t *) dest); -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) -{ - add_ptr(1, dest); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) -{ - add_ptr(-1, dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) -{ - intptr_t res = __sync_lock_test_and_set (dest, exchange_value); - FULL_MEM_BARRIER; - return res; -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) -{ - return generic_cmpxchg(exchange_value, dest, compare_value, order); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) -{ - return generic_cmpxchg(exchange_value, dest, compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) -{ - return (void *) cmpxchg_ptr((intptr_t) exchange_value, - (volatile intptr_t*) dest, - (intptr_t) compare_value, - order); -} - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -#endif // OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp --- a/hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/linux_aarch64/vm/orderAccess_linux_aarch64.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -26,7 +26,7 @@ #ifndef OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP #define OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" #include "vm_version_aarch64.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,479 @@ +/* + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014 SAP SE. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_HPP +#define OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_HPP + +#ifndef PPC64 +#error "Atomic currently only implemented for PPC64" +#endif + +// Implementation of class atomic + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +// +// machine barrier instructions: +// +// - sync two-way memory barrier, aka fence +// - lwsync orders Store|Store, +// Load|Store, +// Load|Load, +// but not Store|Load +// - eieio orders memory accesses for device memory (only) +// - isync invalidates speculatively executed instructions +// From the POWER ISA 2.06 documentation: +// "[...] an isync instruction prevents the execution of +// instructions following the isync until instructions +// preceding the isync have completed, [...]" +// From IBM's AIX assembler reference: +// "The isync [...] instructions causes the processor to +// refetch any instructions that might have been fetched +// prior to the isync instruction. The instruction isync +// causes the processor to wait for all previous instructions +// to complete. Then any instructions already fetched are +// discarded and instruction processing continues in the +// environment established by the previous instructions." +// +// semantic barrier instructions: +// (as defined in orderAccess.hpp) +// +// - release orders Store|Store, (maps to lwsync) +// Load|Store +// - acquire orders Load|Store, (maps to lwsync) +// Load|Load +// - fence orders Store|Store, (maps to sync) +// Load|Store, +// Load|Load, +// Store|Load +// + +#define strasm_sync "\n sync \n" +#define strasm_lwsync "\n lwsync \n" +#define strasm_isync "\n isync \n" +#define strasm_release strasm_lwsync +#define strasm_acquire strasm_lwsync +#define strasm_fence strasm_sync +#define strasm_nobarrier "" +#define strasm_nobarrier_clobber_memory "" + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + + unsigned int result; + + __asm__ __volatile__ ( + strasm_lwsync + "1: lwarx %0, 0, %2 \n" + " add %0, %0, %1 \n" + " stwcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_isync + : /*%0*/"=&r" (result) + : /*%1*/"r" (add_value), /*%2*/"r" (dest) + : "cc", "memory" ); + + return (jint) result; +} + + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + + long result; + + __asm__ __volatile__ ( + strasm_lwsync + "1: ldarx %0, 0, %2 \n" + " add %0, %0, %1 \n" + " stdcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_isync + : /*%0*/"=&r" (result) + : /*%1*/"r" (add_value), /*%2*/"r" (dest) + : "cc", "memory" ); + + return (intptr_t) result; +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add_ptr(add_value, (volatile intptr_t*)dest); +} + + +inline void Atomic::inc (volatile jint* dest) { + + unsigned int temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: lwarx %0, 0, %2 \n" + " addic %0, %0, 1 \n" + " stwcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + + long temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: ldarx %0, 0, %2 \n" + " addic %0, %0, 1 \n" + " stdcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::inc_ptr(volatile void* dest) { + inc_ptr((volatile intptr_t*)dest); +} + + +inline void Atomic::dec (volatile jint* dest) { + + unsigned int temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: lwarx %0, 0, %2 \n" + " addic %0, %0, -1 \n" + " stwcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + + long temp; + + __asm__ __volatile__ ( + strasm_nobarrier + "1: ldarx %0, 0, %2 \n" + " addic %0, %0, -1 \n" + " stdcx. %0, 0, %2 \n" + " bne- 1b \n" + strasm_nobarrier + : /*%0*/"=&r" (temp), "=m" (*dest) + : /*%2*/"r" (dest), "m" (*dest) + : "cc" strasm_nobarrier_clobber_memory); + +} + +inline void Atomic::dec_ptr(volatile void* dest) { + dec_ptr((volatile intptr_t*)dest); +} + +inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { + + // Note that xchg_ptr doesn't necessarily do an acquire + // (see synchronizer.cpp). + + unsigned int old_value; + const uint64_t zero = 0; + + __asm__ __volatile__ ( + /* lwsync */ + strasm_lwsync + /* atomic loop */ + "1: \n" + " lwarx %[old_value], %[dest], %[zero] \n" + " stwcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* isync */ + strasm_sync + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + return (jint) old_value; +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + + // Note that xchg_ptr doesn't necessarily do an acquire + // (see synchronizer.cpp). + + long old_value; + const uint64_t zero = 0; + + __asm__ __volatile__ ( + /* lwsync */ + strasm_lwsync + /* atomic loop */ + "1: \n" + " ldarx %[old_value], %[dest], %[zero] \n" + " stdcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* isync */ + strasm_sync + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + return (intptr_t) old_value; +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); +} + +inline void cmpxchg_pre_membar(cmpxchg_memory_order order) { + if (order != memory_order_relaxed) { + __asm__ __volatile__ ( + /* fence */ + strasm_sync + ); + } +} + +inline void cmpxchg_post_membar(cmpxchg_memory_order order) { + if (order != memory_order_relaxed) { + __asm__ __volatile__ ( + /* fence */ + strasm_sync + ); + } +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + + // Note that cmpxchg guarantees a two-way memory barrier across + // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not + // specified otherwise (see atomic.hpp). + + // Using 32 bit internally. + volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3); + +#ifdef VM_LITTLE_ENDIAN + const unsigned int shift_amount = ((uintptr_t)dest & 3) * 8; +#else + const unsigned int shift_amount = ((~(uintptr_t)dest) & 3) * 8; +#endif + const unsigned int masked_compare_val = ((unsigned int)(unsigned char)compare_value), + masked_exchange_val = ((unsigned int)(unsigned char)exchange_value), + xor_value = (masked_compare_val ^ masked_exchange_val) << shift_amount; + + unsigned int old_value, value32; + + cmpxchg_pre_membar(order); + + __asm__ __volatile__ ( + /* simple guard */ + " lbz %[old_value], 0(%[dest]) \n" + " cmpw %[masked_compare_val], %[old_value] \n" + " bne- 2f \n" + /* atomic loop */ + "1: \n" + " lwarx %[value32], 0, %[dest_base] \n" + /* extract byte and compare */ + " srd %[old_value], %[value32], %[shift_amount] \n" + " clrldi %[old_value], %[old_value], 56 \n" + " cmpw %[masked_compare_val], %[old_value] \n" + " bne- 2f \n" + /* replace byte and try to store */ + " xor %[value32], %[xor_value], %[value32] \n" + " stwcx. %[value32], 0, %[dest_base] \n" + " bne- 1b \n" + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + [value32] "=&r" (value32), + "=m" (*dest), + "=m" (*dest_base) + /* in */ + : [dest] "b" (dest), + [dest_base] "b" (dest_base), + [shift_amount] "r" (shift_amount), + [masked_compare_val] "r" (masked_compare_val), + [xor_value] "r" (xor_value), + "m" (*dest), + "m" (*dest_base) + /* clobber */ + : "cc", + "memory" + ); + + cmpxchg_post_membar(order); + + return (jbyte)(unsigned char)old_value; +} + +inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + + // Note that cmpxchg guarantees a two-way memory barrier across + // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not + // specified otherwise (see atomic.hpp). + + unsigned int old_value; + const uint64_t zero = 0; + + cmpxchg_pre_membar(order); + + __asm__ __volatile__ ( + /* simple guard */ + " lwz %[old_value], 0(%[dest]) \n" + " cmpw %[compare_value], %[old_value] \n" + " bne- 2f \n" + /* atomic loop */ + "1: \n" + " lwarx %[old_value], %[dest], %[zero] \n" + " cmpw %[compare_value], %[old_value] \n" + " bne- 2f \n" + " stwcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [compare_value] "r" (compare_value), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + cmpxchg_post_membar(order); + + return (jint) old_value; +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + + // Note that cmpxchg guarantees a two-way memory barrier across + // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not + // specified otherwise (see atomic.hpp). + + long old_value; + const uint64_t zero = 0; + + cmpxchg_pre_membar(order); + + __asm__ __volatile__ ( + /* simple guard */ + " ld %[old_value], 0(%[dest]) \n" + " cmpd %[compare_value], %[old_value] \n" + " bne- 2f \n" + /* atomic loop */ + "1: \n" + " ldarx %[old_value], %[dest], %[zero] \n" + " cmpd %[compare_value], %[old_value] \n" + " bne- 2f \n" + " stdcx. %[exchange_value], %[dest], %[zero] \n" + " bne- 1b \n" + /* exit */ + "2: \n" + /* out */ + : [old_value] "=&r" (old_value), + "=m" (*dest) + /* in */ + : [dest] "b" (dest), + [zero] "r" (zero), + [compare_value] "r" (compare_value), + [exchange_value] "r" (exchange_value), + "m" (*dest) + /* clobber */ + : "cc", + "memory" + ); + + cmpxchg_post_membar(order); + + return (jlong) old_value; +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +#undef strasm_sync +#undef strasm_lwsync +#undef strasm_isync +#undef strasm_release +#undef strasm_acquire +#undef strasm_fence +#undef strasm_nobarrier +#undef strasm_nobarrier_clobber_memory + +#endif // OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp --- a/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,482 +0,0 @@ -/* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, 2014 SAP SE. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP -#define OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -#ifndef PPC64 -#error "Atomic currently only implemented for PPC64" -#endif - -// Implementation of class atomic - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -// -// machine barrier instructions: -// -// - sync two-way memory barrier, aka fence -// - lwsync orders Store|Store, -// Load|Store, -// Load|Load, -// but not Store|Load -// - eieio orders memory accesses for device memory (only) -// - isync invalidates speculatively executed instructions -// From the POWER ISA 2.06 documentation: -// "[...] an isync instruction prevents the execution of -// instructions following the isync until instructions -// preceding the isync have completed, [...]" -// From IBM's AIX assembler reference: -// "The isync [...] instructions causes the processor to -// refetch any instructions that might have been fetched -// prior to the isync instruction. The instruction isync -// causes the processor to wait for all previous instructions -// to complete. Then any instructions already fetched are -// discarded and instruction processing continues in the -// environment established by the previous instructions." -// -// semantic barrier instructions: -// (as defined in orderAccess.hpp) -// -// - release orders Store|Store, (maps to lwsync) -// Load|Store -// - acquire orders Load|Store, (maps to lwsync) -// Load|Load -// - fence orders Store|Store, (maps to sync) -// Load|Store, -// Load|Load, -// Store|Load -// - -#define strasm_sync "\n sync \n" -#define strasm_lwsync "\n lwsync \n" -#define strasm_isync "\n isync \n" -#define strasm_release strasm_lwsync -#define strasm_acquire strasm_lwsync -#define strasm_fence strasm_sync -#define strasm_nobarrier "" -#define strasm_nobarrier_clobber_memory "" - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - - unsigned int result; - - __asm__ __volatile__ ( - strasm_lwsync - "1: lwarx %0, 0, %2 \n" - " add %0, %0, %1 \n" - " stwcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_isync - : /*%0*/"=&r" (result) - : /*%1*/"r" (add_value), /*%2*/"r" (dest) - : "cc", "memory" ); - - return (jint) result; -} - - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - - long result; - - __asm__ __volatile__ ( - strasm_lwsync - "1: ldarx %0, 0, %2 \n" - " add %0, %0, %1 \n" - " stdcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_isync - : /*%0*/"=&r" (result) - : /*%1*/"r" (add_value), /*%2*/"r" (dest) - : "cc", "memory" ); - - return (intptr_t) result; -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add_ptr(add_value, (volatile intptr_t*)dest); -} - - -inline void Atomic::inc (volatile jint* dest) { - - unsigned int temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: lwarx %0, 0, %2 \n" - " addic %0, %0, 1 \n" - " stwcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - - long temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: ldarx %0, 0, %2 \n" - " addic %0, %0, 1 \n" - " stdcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::inc_ptr(volatile void* dest) { - inc_ptr((volatile intptr_t*)dest); -} - - -inline void Atomic::dec (volatile jint* dest) { - - unsigned int temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: lwarx %0, 0, %2 \n" - " addic %0, %0, -1 \n" - " stwcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - - long temp; - - __asm__ __volatile__ ( - strasm_nobarrier - "1: ldarx %0, 0, %2 \n" - " addic %0, %0, -1 \n" - " stdcx. %0, 0, %2 \n" - " bne- 1b \n" - strasm_nobarrier - : /*%0*/"=&r" (temp), "=m" (*dest) - : /*%2*/"r" (dest), "m" (*dest) - : "cc" strasm_nobarrier_clobber_memory); - -} - -inline void Atomic::dec_ptr(volatile void* dest) { - dec_ptr((volatile intptr_t*)dest); -} - -inline jint Atomic::xchg(jint exchange_value, volatile jint* dest) { - - // Note that xchg_ptr doesn't necessarily do an acquire - // (see synchronizer.cpp). - - unsigned int old_value; - const uint64_t zero = 0; - - __asm__ __volatile__ ( - /* lwsync */ - strasm_lwsync - /* atomic loop */ - "1: \n" - " lwarx %[old_value], %[dest], %[zero] \n" - " stwcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* isync */ - strasm_sync - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - return (jint) old_value; -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - - // Note that xchg_ptr doesn't necessarily do an acquire - // (see synchronizer.cpp). - - long old_value; - const uint64_t zero = 0; - - __asm__ __volatile__ ( - /* lwsync */ - strasm_lwsync - /* atomic loop */ - "1: \n" - " ldarx %[old_value], %[dest], %[zero] \n" - " stdcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* isync */ - strasm_sync - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - return (intptr_t) old_value; -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); -} - -inline void cmpxchg_pre_membar(cmpxchg_memory_order order) { - if (order != memory_order_relaxed) { - __asm__ __volatile__ ( - /* fence */ - strasm_sync - ); - } -} - -inline void cmpxchg_post_membar(cmpxchg_memory_order order) { - if (order != memory_order_relaxed) { - __asm__ __volatile__ ( - /* fence */ - strasm_sync - ); - } -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - - // Note that cmpxchg guarantees a two-way memory barrier across - // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not - // specified otherwise (see atomic.hpp). - - // Using 32 bit internally. - volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3); - -#ifdef VM_LITTLE_ENDIAN - const unsigned int shift_amount = ((uintptr_t)dest & 3) * 8; -#else - const unsigned int shift_amount = ((~(uintptr_t)dest) & 3) * 8; -#endif - const unsigned int masked_compare_val = ((unsigned int)(unsigned char)compare_value), - masked_exchange_val = ((unsigned int)(unsigned char)exchange_value), - xor_value = (masked_compare_val ^ masked_exchange_val) << shift_amount; - - unsigned int old_value, value32; - - cmpxchg_pre_membar(order); - - __asm__ __volatile__ ( - /* simple guard */ - " lbz %[old_value], 0(%[dest]) \n" - " cmpw %[masked_compare_val], %[old_value] \n" - " bne- 2f \n" - /* atomic loop */ - "1: \n" - " lwarx %[value32], 0, %[dest_base] \n" - /* extract byte and compare */ - " srd %[old_value], %[value32], %[shift_amount] \n" - " clrldi %[old_value], %[old_value], 56 \n" - " cmpw %[masked_compare_val], %[old_value] \n" - " bne- 2f \n" - /* replace byte and try to store */ - " xor %[value32], %[xor_value], %[value32] \n" - " stwcx. %[value32], 0, %[dest_base] \n" - " bne- 1b \n" - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - [value32] "=&r" (value32), - "=m" (*dest), - "=m" (*dest_base) - /* in */ - : [dest] "b" (dest), - [dest_base] "b" (dest_base), - [shift_amount] "r" (shift_amount), - [masked_compare_val] "r" (masked_compare_val), - [xor_value] "r" (xor_value), - "m" (*dest), - "m" (*dest_base) - /* clobber */ - : "cc", - "memory" - ); - - cmpxchg_post_membar(order); - - return (jbyte)(unsigned char)old_value; -} - -inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - - // Note that cmpxchg guarantees a two-way memory barrier across - // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not - // specified otherwise (see atomic.hpp). - - unsigned int old_value; - const uint64_t zero = 0; - - cmpxchg_pre_membar(order); - - __asm__ __volatile__ ( - /* simple guard */ - " lwz %[old_value], 0(%[dest]) \n" - " cmpw %[compare_value], %[old_value] \n" - " bne- 2f \n" - /* atomic loop */ - "1: \n" - " lwarx %[old_value], %[dest], %[zero] \n" - " cmpw %[compare_value], %[old_value] \n" - " bne- 2f \n" - " stwcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [compare_value] "r" (compare_value), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - cmpxchg_post_membar(order); - - return (jint) old_value; -} - -inline jlong Atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - - // Note that cmpxchg guarantees a two-way memory barrier across - // the cmpxchg, so it's really a a 'fence_cmpxchg_fence' if not - // specified otherwise (see atomic.hpp). - - long old_value; - const uint64_t zero = 0; - - cmpxchg_pre_membar(order); - - __asm__ __volatile__ ( - /* simple guard */ - " ld %[old_value], 0(%[dest]) \n" - " cmpd %[compare_value], %[old_value] \n" - " bne- 2f \n" - /* atomic loop */ - "1: \n" - " ldarx %[old_value], %[dest], %[zero] \n" - " cmpd %[compare_value], %[old_value] \n" - " bne- 2f \n" - " stdcx. %[exchange_value], %[dest], %[zero] \n" - " bne- 1b \n" - /* exit */ - "2: \n" - /* out */ - : [old_value] "=&r" (old_value), - "=m" (*dest) - /* in */ - : [dest] "b" (dest), - [zero] "r" (zero), - [compare_value] "r" (compare_value), - [exchange_value] "r" (exchange_value), - "m" (*dest) - /* clobber */ - : "cc", - "memory" - ); - - cmpxchg_post_membar(order); - - return (jlong) old_value; -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -#undef strasm_sync -#undef strasm_lwsync -#undef strasm_isync -#undef strasm_release -#undef strasm_acquire -#undef strasm_fence -#undef strasm_nobarrier -#undef strasm_nobarrier_clobber_memory - -#endif // OS_CPU_LINUX_PPC_VM_ATOMIC_LINUX_PPC_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp --- a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,6 @@ #ifndef OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP #define OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - // Implementation of class atomic inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,227 @@ +/* + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP +#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP + +#include "runtime/os.hpp" + +// Implementation of class atomic + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + + +// Adding a lock prefix to an instruction on MP machine +#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: " + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + jint addend = add_value; + int mp = os::is_MP(); + __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)" + : "=r" (addend) + : "0" (addend), "r" (dest), "r" (mp) + : "cc", "memory"); + return addend + add_value; +} + +inline void Atomic::inc (volatile jint* dest) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" : + : "r" (dest), "r" (mp) : "cc", "memory"); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + inc_ptr((volatile intptr_t*)dest); +} + +inline void Atomic::dec (volatile jint* dest) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" : + : "r" (dest), "r" (mp) : "cc", "memory"); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + dec_ptr((volatile intptr_t*)dest); +} + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + __asm__ volatile ( "xchgl (%2),%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return 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); +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" + : "=a" (exchange_value) + : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +} + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + int mp = os::is_MP(); + __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" + : "=a" (exchange_value) + : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +} + +#ifdef AMD64 +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + intptr_t addend = add_value; + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" + : "=r" (addend) + : "0" (addend), "r" (dest), "r" (mp) + : "cc", "memory"); + return addend + add_value; +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add_ptr(add_value, (volatile intptr_t*)dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)" + : + : "r" (dest), "r" (mp) + : "cc", "memory"); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)" + : + : "r" (dest), "r" (mp) + : "cc", "memory"); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + __asm__ __volatile__ ("xchgq (%2),%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return exchange_value; +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + bool mp = os::is_MP(); + __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" + : "=a" (exchange_value) + : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +#else // !AMD64 + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)Atomic::add((jint)add_value, (volatile jint*)dest); +} + + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + inc((volatile jint*)dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + dec((volatile jint*)dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); +} + +extern "C" { + // defined in linux_x86.s + jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool); + void _Atomic_move_long(volatile jlong* src, volatile jlong* dst); +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP()); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline jlong Atomic::load(volatile jlong* src) { + volatile jlong dest; + _Atomic_move_long(src, &dest); + return dest; +} + +inline void Atomic::store(jlong store_value, jlong* dest) { + _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); +} + +inline void Atomic::store(jlong store_value, volatile jlong* dest) { + _Atomic_move_long((volatile jlong*)&store_value, dest); +} + +#endif // AMD64 + +#endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp --- a/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -/* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP -#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -// Implementation of class atomic - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - - -// Adding a lock prefix to an instruction on MP machine -#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: " - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - jint addend = add_value; - int mp = os::is_MP(); - __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)" - : "=r" (addend) - : "0" (addend), "r" (dest), "r" (mp) - : "cc", "memory"); - return addend + add_value; -} - -inline void Atomic::inc (volatile jint* dest) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%1) "addl $1,(%0)" : - : "r" (dest), "r" (mp) : "cc", "memory"); -} - -inline void Atomic::inc_ptr(volatile void* dest) { - inc_ptr((volatile intptr_t*)dest); -} - -inline void Atomic::dec (volatile jint* dest) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%1) "subl $1,(%0)" : - : "r" (dest), "r" (mp) : "cc", "memory"); -} - -inline void Atomic::dec_ptr(volatile void* dest) { - dec_ptr((volatile intptr_t*)dest); -} - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - __asm__ volatile ( "xchgl (%2),%0" - : "=r" (exchange_value) - : "0" (exchange_value), "r" (dest) - : "memory"); - return 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); -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" - : "=a" (exchange_value) - : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -} - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - int mp = os::is_MP(); - __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" - : "=a" (exchange_value) - : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -} - -#ifdef AMD64 -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - intptr_t addend = add_value; - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" - : "=r" (addend) - : "0" (addend), "r" (dest), "r" (mp) - : "cc", "memory"); - return addend + add_value; -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add_ptr(add_value, (volatile intptr_t*)dest); -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%1) "addq $1,(%0)" - : - : "r" (dest), "r" (mp) - : "cc", "memory"); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%1) "subq $1,(%0)" - : - : "r" (dest), "r" (mp) - : "cc", "memory"); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - __asm__ __volatile__ ("xchgq (%2),%0" - : "=r" (exchange_value) - : "0" (exchange_value), "r" (dest) - : "memory"); - return exchange_value; -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - bool mp = os::is_MP(); - __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" - : "=a" (exchange_value) - : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -#else // !AMD64 - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)Atomic::add((jint)add_value, (volatile jint*)dest); -} - - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - inc((volatile jint*)dest); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - dec((volatile jint*)dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); -} - -extern "C" { - // defined in linux_x86.s - jlong _Atomic_cmpxchg_long(jlong, volatile jlong*, jlong, bool); - void _Atomic_move_long(volatile jlong* src, volatile jlong* dst); -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP()); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline jlong Atomic::load(volatile jlong* src) { - volatile jlong dest; - _Atomic_move_long(src, &dest); - return dest; -} - -inline void Atomic::store(jlong store_value, jlong* dest) { - _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); -} - -inline void Atomic::store(jlong store_value, volatile jlong* dest) { - _Atomic_move_long((volatile jlong*)&store_value, dest); -} - -#endif // AMD64 - -#endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp --- a/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP #define OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_HPP +#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_HPP + +#include "runtime/os.hpp" + +// Implementation of class atomic + +#ifdef M68K + +/* + * __m68k_cmpxchg + * + * 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. + * + * 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. + * + */ + +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 + +#ifdef ARM + +/* + * __kernel_cmpxchg + * + * 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. + * + */ + +typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); +#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) + + + +/* 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; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + // Success. + return prev; + + // We failed even though prev == oldval. Try again. + } +} + +/* 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. + + int prev = *ptr; + + if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) + return prev + add_value; + } +} + +/* 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; + + if (__kernel_cmpxchg (prev, newval, ptr) == 0) + return prev; + } +} +#endif // ARM + +inline void Atomic::store(jint store_value, volatile jint* dest) { + *dest = store_value; +} + +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { + *dest = store_value; +} + +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 +} + +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 +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void *) add_ptr(add_value, (volatile intptr_t *) dest); +} + +inline void Atomic::inc(volatile jint* dest) { + add(1, dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + add_ptr(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + add_ptr(1, dest); +} + +inline void Atomic::dec(volatile jint* dest) { + add(-1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + add_ptr(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + add_ptr(-1, dest); +} + +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(). + jint result = __sync_lock_test_and_set (dest, exchange_value); + // All atomic operations are expected to be full memory barriers + // (see atomic.hpp). However, __sync_lock_test_and_set is not + // a full memory barrier, but an acquire barrier. Hence, this added + // barrier. + __sync_synchronize(); + return result; +#endif // M68K +#endif // ARM +} + +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 + intptr_t result = __sync_lock_test_and_set (dest, exchange_value); + __sync_synchronize(); + return result; +#endif // M68K +#endif // ARM +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void *) xchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest); +} + +inline jint Atomic::cmpxchg(jint exchange_value, + volatile jint* dest, + jint compare_value, + cmpxchg_memory_order order) { +#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 +} + +inline jlong Atomic::cmpxchg(jlong exchange_value, + volatile jlong* dest, + jlong compare_value, + cmpxchg_memory_order order) { + + return __sync_val_compare_and_swap(dest, compare_value, exchange_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, + volatile intptr_t* dest, + intptr_t compare_value, + cmpxchg_memory_order order) { +#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 +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, + volatile void* dest, + void* compare_value, + cmpxchg_memory_order order) { + + return (void *) cmpxchg_ptr((intptr_t) exchange_value, + (volatile intptr_t*) dest, + (intptr_t) compare_value, + order); +} + +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); +} + +#endif // OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp --- a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,328 +0,0 @@ -/* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. - * Copyright 2007, 2008, 2011, 2015, Red Hat, Inc. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP -#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -// Implementation of class atomic - -#ifdef M68K - -/* - * __m68k_cmpxchg - * - * 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. - * - * 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. - * - */ - -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 - -#ifdef ARM - -/* - * __kernel_cmpxchg - * - * 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. - * - */ - -typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr); -#define __kernel_cmpxchg (*(__kernel_cmpxchg_t *) 0xffff0fc0) - - - -/* 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; - - if (__kernel_cmpxchg (prev, newval, ptr) == 0) - // Success. - return prev; - - // We failed even though prev == oldval. Try again. - } -} - -/* 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. - - int prev = *ptr; - - if (__kernel_cmpxchg (prev, prev + add_value, ptr) == 0) - return prev + add_value; - } -} - -/* 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; - - if (__kernel_cmpxchg (prev, newval, ptr) == 0) - return prev; - } -} -#endif // ARM - -inline void Atomic::store(jint store_value, volatile jint* dest) { - *dest = store_value; -} - -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { - *dest = store_value; -} - -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 -} - -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 -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void *) add_ptr(add_value, (volatile intptr_t *) dest); -} - -inline void Atomic::inc(volatile jint* dest) { - add(1, dest); -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - add_ptr(1, dest); -} - -inline void Atomic::inc_ptr(volatile void* dest) { - add_ptr(1, dest); -} - -inline void Atomic::dec(volatile jint* dest) { - add(-1, dest); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - add_ptr(-1, dest); -} - -inline void Atomic::dec_ptr(volatile void* dest) { - add_ptr(-1, dest); -} - -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(). - jint result = __sync_lock_test_and_set (dest, exchange_value); - // All atomic operations are expected to be full memory barriers - // (see atomic.hpp). However, __sync_lock_test_and_set is not - // a full memory barrier, but an acquire barrier. Hence, this added - // barrier. - __sync_synchronize(); - return result; -#endif // M68K -#endif // ARM -} - -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 - intptr_t result = __sync_lock_test_and_set (dest, exchange_value); - __sync_synchronize(); - return result; -#endif // M68K -#endif // ARM -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void *) xchg_ptr((intptr_t) exchange_value, - (volatile intptr_t*) dest); -} - -inline jint Atomic::cmpxchg(jint exchange_value, - volatile jint* dest, - jint compare_value, - cmpxchg_memory_order order) { -#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 -} - -inline jlong Atomic::cmpxchg(jlong exchange_value, - volatile jlong* dest, - jlong compare_value, - cmpxchg_memory_order order) { - - return __sync_val_compare_and_swap(dest, compare_value, exchange_value); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, - volatile intptr_t* dest, - intptr_t compare_value, - cmpxchg_memory_order order) { -#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 -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, - volatile void* dest, - void* compare_value, - cmpxchg_memory_order order) { - - return (void *) cmpxchg_ptr((intptr_t) exchange_value, - (volatile intptr_t*) dest, - (intptr_t) compare_value, - order); -} - -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); -} - -#endif // OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,376 @@ +/* + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_HPP +#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_HPP + +#include "runtime/os.hpp" + +// Implementation of class atomic + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + +inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); } +inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); } +inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); } + +inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); } +inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } +inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } + + +#ifdef _LP64 + +inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; } +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +#else + +extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst); + +inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) { + _Atomic_move_long_v9(src, dst); +} + +inline jlong Atomic::load(volatile jlong* src) { + volatile jlong dest; + Atomic_move_long(src, &dest); + return dest; +} + +inline void Atomic::store(jlong store_value, jlong* dest) { + Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); +} + +inline void Atomic::store(jlong store_value, volatile jlong* dest) { + Atomic_move_long((volatile jlong*)&store_value, dest); +} + +#endif + +#ifdef _GNU_SOURCE + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + intptr_t rv; + __asm__ volatile( + "1: \n\t" + " ld [%2], %%o2\n\t" + " add %1, %%o2, %%o3\n\t" + " cas [%2], %%o2, %%o3\n\t" + " cmp %%o2, %%o3\n\t" + " bne 1b\n\t" + " nop\n\t" + " add %1, %%o2, %0\n\t" + : "=r" (rv) + : "r" (add_value), "r" (dest) + : "memory", "o2", "o3"); + return rv; +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + intptr_t rv; +#ifdef _LP64 + __asm__ volatile( + "1: \n\t" + " ldx [%2], %%o2\n\t" + " add %0, %%o2, %%o3\n\t" + " casx [%2], %%o2, %%o3\n\t" + " cmp %%o2, %%o3\n\t" + " bne %%xcc, 1b\n\t" + " nop\n\t" + " add %0, %%o2, %0\n\t" + : "=r" (rv) + : "r" (add_value), "r" (dest) + : "memory", "o2", "o3"); +#else //_LP64 + __asm__ volatile( + "1: \n\t" + " ld [%2], %%o2\n\t" + " add %1, %%o2, %%o3\n\t" + " cas [%2], %%o2, %%o3\n\t" + " cmp %%o2, %%o3\n\t" + " bne 1b\n\t" + " nop\n\t" + " add %1, %%o2, %0\n\t" + : "=r" (rv) + : "r" (add_value), "r" (dest) + : "memory", "o2", "o3"); +#endif // _LP64 + return rv; +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest); +} + + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + intptr_t rv = exchange_value; + __asm__ volatile( + " swap [%2],%1\n\t" + : "=r" (rv) + : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) + : "memory"); + return rv; +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + intptr_t rv = exchange_value; +#ifdef _LP64 + __asm__ volatile( + "1:\n\t" + " mov %1, %%o3\n\t" + " ldx [%2], %%o2\n\t" + " casx [%2], %%o2, %%o3\n\t" + " cmp %%o2, %%o3\n\t" + " bne %%xcc, 1b\n\t" + " nop\n\t" + " mov %%o2, %0\n\t" + : "=r" (rv) + : "r" (exchange_value), "r" (dest) + : "memory", "o2", "o3"); +#else //_LP64 + __asm__ volatile( + "swap [%2],%1\n\t" + : "=r" (rv) + : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) + : "memory"); +#endif // _LP64 + return rv; +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); +} + + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + jint rv; + __asm__ volatile( + " cas [%2], %3, %0" + : "=r" (rv) + : "0" (exchange_value), "r" (dest), "r" (compare_value) + : "memory"); + return rv; +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { +#ifdef _LP64 + jlong rv; + __asm__ volatile( + " casx [%2], %3, %0" + : "=r" (rv) + : "0" (exchange_value), "r" (dest), "r" (compare_value) + : "memory"); + return rv; +#else //_LP64 + volatile jlong_accessor evl, cvl, rv; + evl.long_value = exchange_value; + cvl.long_value = compare_value; + + __asm__ volatile( + " sllx %2, 32, %2\n\t" + " srl %3, 0, %3\n\t" + " or %2, %3, %2\n\t" + " sllx %5, 32, %5\n\t" + " srl %6, 0, %6\n\t" + " or %5, %6, %5\n\t" + " casx [%4], %5, %2\n\t" + " srl %2, 0, %1\n\t" + " srlx %2, 32, %0\n\t" + : "=r" (rv.words[0]), "=r" (rv.words[1]) + : "r" (evl.words[0]), "r" (evl.words[1]), "r" (dest), "r" (cvl.words[0]), "r" (cvl.words[1]) + : "memory"); + + return rv.long_value; +#endif //_LP64 +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + intptr_t rv; +#ifdef _LP64 + __asm__ volatile( + " casx [%2], %3, %0" + : "=r" (rv) + : "0" (exchange_value), "r" (dest), "r" (compare_value) + : "memory"); +#else //_LP64 + __asm__ volatile( + " cas [%2], %3, %0" + : "=r" (rv) + : "0" (exchange_value), "r" (dest), "r" (compare_value) + : "memory"); +#endif // _LP64 + return rv; +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value, order); +} + +#else // _GNU_SOURCE + +#if defined(COMPILER2) || defined(_LP64) + +// This is the interface to the atomic instructions in solaris_sparc.il. +// It's very messy because we need to support v8 and these instructions +// are illegal there. When sparc v8 is dropped, we can drop out lots of +// this code. Also compiler2 does not support v8 so the conditional code +// omits the instruction set check. + +extern "C" jint _Atomic_swap32(jint exchange_value, volatile jint* dest); +extern "C" intptr_t _Atomic_swap64(intptr_t exchange_value, volatile intptr_t* dest); + +extern "C" jint _Atomic_cas32(jint exchange_value, volatile jint* dest, jint compare_value); +extern "C" intptr_t _Atomic_cas64(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value); +extern "C" jlong _Atomic_casl (jlong exchange_value, volatile jlong* dest, jlong compare_value); + +extern "C" jint _Atomic_add32(jint inc, volatile jint* dest); +extern "C" intptr_t _Atomic_add64(intptr_t add_value, volatile intptr_t* dest); + + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + return _Atomic_add32(add_value, dest); +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { +#ifdef _LP64 + return _Atomic_add64(add_value, dest); +#else //_LP64 + return _Atomic_add32(add_value, dest); +#endif // _LP64 +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest); +} + + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + return _Atomic_swap32(exchange_value, dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { +#ifdef _LP64 + return _Atomic_swap64(exchange_value, dest); +#else // _LP64 + return _Atomic_swap32(exchange_value, dest); +#endif // _LP64 +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); +} + + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + return _Atomic_cas32(exchange_value, dest, compare_value); +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { +#ifdef _LP64 + // Return 64 bit value in %o0 + return _Atomic_cas64((intptr_t)exchange_value, (intptr_t *)dest, (intptr_t)compare_value); +#else // _LP64 + // Return 64 bit value in %o0,%o1 by hand + return _Atomic_casl(exchange_value, dest, compare_value); +#endif // _LP64 +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { +#ifdef _LP64 + return _Atomic_cas64(exchange_value, dest, compare_value); +#else // _LP64 + return _Atomic_cas32(exchange_value, dest, compare_value); +#endif // _LP64 +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value, order); +} + + +#else // _LP64 || COMPILER2 + + +// 32-bit compiler1 only + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + return (*os::atomic_add_func)(add_value, dest); +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)add((jint)add_value, (volatile jint*)dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add((jint)add_value, (volatile jint*)dest); +} + + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + return (*os::atomic_xchg_func)(exchange_value, dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg((jint)exchange_value, (volatile jint*)dest); +} + + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value); +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +#endif // _LP64 || COMPILER2 + +#endif // _GNU_SOURCE + +#endif // OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,377 +0,0 @@ -/* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP -#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -// Implementation of class atomic - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - -inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); } -inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); } -inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); } - -inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); } -inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } -inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } - - -#ifdef _LP64 - -inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; } -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -#else - -extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst); - -inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) { - _Atomic_move_long_v9(src, dst); -} - -inline jlong Atomic::load(volatile jlong* src) { - volatile jlong dest; - Atomic_move_long(src, &dest); - return dest; -} - -inline void Atomic::store(jlong store_value, jlong* dest) { - Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); -} - -inline void Atomic::store(jlong store_value, volatile jlong* dest) { - Atomic_move_long((volatile jlong*)&store_value, dest); -} - -#endif - -#ifdef _GNU_SOURCE - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - intptr_t rv; - __asm__ volatile( - "1: \n\t" - " ld [%2], %%o2\n\t" - " add %1, %%o2, %%o3\n\t" - " cas [%2], %%o2, %%o3\n\t" - " cmp %%o2, %%o3\n\t" - " bne 1b\n\t" - " nop\n\t" - " add %1, %%o2, %0\n\t" - : "=r" (rv) - : "r" (add_value), "r" (dest) - : "memory", "o2", "o3"); - return rv; -} - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - intptr_t rv; -#ifdef _LP64 - __asm__ volatile( - "1: \n\t" - " ldx [%2], %%o2\n\t" - " add %0, %%o2, %%o3\n\t" - " casx [%2], %%o2, %%o3\n\t" - " cmp %%o2, %%o3\n\t" - " bne %%xcc, 1b\n\t" - " nop\n\t" - " add %0, %%o2, %0\n\t" - : "=r" (rv) - : "r" (add_value), "r" (dest) - : "memory", "o2", "o3"); -#else //_LP64 - __asm__ volatile( - "1: \n\t" - " ld [%2], %%o2\n\t" - " add %1, %%o2, %%o3\n\t" - " cas [%2], %%o2, %%o3\n\t" - " cmp %%o2, %%o3\n\t" - " bne 1b\n\t" - " nop\n\t" - " add %1, %%o2, %0\n\t" - : "=r" (rv) - : "r" (add_value), "r" (dest) - : "memory", "o2", "o3"); -#endif // _LP64 - return rv; -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest); -} - - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - intptr_t rv = exchange_value; - __asm__ volatile( - " swap [%2],%1\n\t" - : "=r" (rv) - : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) - : "memory"); - return rv; -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - intptr_t rv = exchange_value; -#ifdef _LP64 - __asm__ volatile( - "1:\n\t" - " mov %1, %%o3\n\t" - " ldx [%2], %%o2\n\t" - " casx [%2], %%o2, %%o3\n\t" - " cmp %%o2, %%o3\n\t" - " bne %%xcc, 1b\n\t" - " nop\n\t" - " mov %%o2, %0\n\t" - : "=r" (rv) - : "r" (exchange_value), "r" (dest) - : "memory", "o2", "o3"); -#else //_LP64 - __asm__ volatile( - "swap [%2],%1\n\t" - : "=r" (rv) - : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) - : "memory"); -#endif // _LP64 - return rv; -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); -} - - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - jint rv; - __asm__ volatile( - " cas [%2], %3, %0" - : "=r" (rv) - : "0" (exchange_value), "r" (dest), "r" (compare_value) - : "memory"); - return rv; -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { -#ifdef _LP64 - jlong rv; - __asm__ volatile( - " casx [%2], %3, %0" - : "=r" (rv) - : "0" (exchange_value), "r" (dest), "r" (compare_value) - : "memory"); - return rv; -#else //_LP64 - volatile jlong_accessor evl, cvl, rv; - evl.long_value = exchange_value; - cvl.long_value = compare_value; - - __asm__ volatile( - " sllx %2, 32, %2\n\t" - " srl %3, 0, %3\n\t" - " or %2, %3, %2\n\t" - " sllx %5, 32, %5\n\t" - " srl %6, 0, %6\n\t" - " or %5, %6, %5\n\t" - " casx [%4], %5, %2\n\t" - " srl %2, 0, %1\n\t" - " srlx %2, 32, %0\n\t" - : "=r" (rv.words[0]), "=r" (rv.words[1]) - : "r" (evl.words[0]), "r" (evl.words[1]), "r" (dest), "r" (cvl.words[0]), "r" (cvl.words[1]) - : "memory"); - - return rv.long_value; -#endif //_LP64 -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - intptr_t rv; -#ifdef _LP64 - __asm__ volatile( - " casx [%2], %3, %0" - : "=r" (rv) - : "0" (exchange_value), "r" (dest), "r" (compare_value) - : "memory"); -#else //_LP64 - __asm__ volatile( - " cas [%2], %3, %0" - : "=r" (rv) - : "0" (exchange_value), "r" (dest), "r" (compare_value) - : "memory"); -#endif // _LP64 - return rv; -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value, order); -} - -#else // _GNU_SOURCE - -#if defined(COMPILER2) || defined(_LP64) - -// This is the interface to the atomic instructions in solaris_sparc.il. -// It's very messy because we need to support v8 and these instructions -// are illegal there. When sparc v8 is dropped, we can drop out lots of -// this code. Also compiler2 does not support v8 so the conditional code -// omits the instruction set check. - -extern "C" jint _Atomic_swap32(jint exchange_value, volatile jint* dest); -extern "C" intptr_t _Atomic_swap64(intptr_t exchange_value, volatile intptr_t* dest); - -extern "C" jint _Atomic_cas32(jint exchange_value, volatile jint* dest, jint compare_value); -extern "C" intptr_t _Atomic_cas64(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value); -extern "C" jlong _Atomic_casl (jlong exchange_value, volatile jlong* dest, jlong compare_value); - -extern "C" jint _Atomic_add32(jint inc, volatile jint* dest); -extern "C" intptr_t _Atomic_add64(intptr_t add_value, volatile intptr_t* dest); - - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - return _Atomic_add32(add_value, dest); -} - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { -#ifdef _LP64 - return _Atomic_add64(add_value, dest); -#else //_LP64 - return _Atomic_add32(add_value, dest); -#endif // _LP64 -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest); -} - - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - return _Atomic_swap32(exchange_value, dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { -#ifdef _LP64 - return _Atomic_swap64(exchange_value, dest); -#else // _LP64 - return _Atomic_swap32(exchange_value, dest); -#endif // _LP64 -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); -} - - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - return _Atomic_cas32(exchange_value, dest, compare_value); -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { -#ifdef _LP64 - // Return 64 bit value in %o0 - return _Atomic_cas64((intptr_t)exchange_value, (intptr_t *)dest, (intptr_t)compare_value); -#else // _LP64 - // Return 64 bit value in %o0,%o1 by hand - return _Atomic_casl(exchange_value, dest, compare_value); -#endif // _LP64 -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { -#ifdef _LP64 - return _Atomic_cas64(exchange_value, dest, compare_value); -#else // _LP64 - return _Atomic_cas32(exchange_value, dest, compare_value); -#endif // _LP64 -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value, order); -} - - -#else // _LP64 || COMPILER2 - - -// 32-bit compiler1 only - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - return (*os::atomic_add_func)(add_value, dest); -} - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)add((jint)add_value, (volatile jint*)dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add((jint)add_value, (volatile jint*)dest); -} - - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - return (*os::atomic_xchg_func)(exchange_value, dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg((jint)exchange_value, (volatile jint*)dest); -} - - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value); -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -#endif // _LP64 || COMPILER2 - -#endif // _GNU_SOURCE - -#endif // OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp --- a/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP #define OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" // Compiler version last used for testing: solaris studio 12u3 diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,278 @@ +/* + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP +#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP + +#include "runtime/os.hpp" + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } + + +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + +inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); } +inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); } +inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); } + +inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); } +inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } +inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } + +// For Sun Studio - implementation is in solaris_x86_[32/64].il. +// For gcc - implementation is just below. + +// The lock prefix can be omitted for certain instructions on uniprocessors; to +// facilitate this, os::is_MP() is passed as an additional argument. 64-bit +// processors are assumed to be multi-threaded and/or multi-core, so the extra +// argument is unnecessary. +#ifndef _LP64 +#define IS_MP_DECL() , int is_mp +#define IS_MP_ARG() , (int) os::is_MP() +#else +#define IS_MP_DECL() +#define IS_MP_ARG() +#endif // _LP64 + +extern "C" { + jint _Atomic_add(jint add_value, volatile jint* dest IS_MP_DECL()); + jint _Atomic_xchg(jint exchange_value, volatile jint* dest); + jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, + jbyte compare_value IS_MP_DECL()); + jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, + jint compare_value IS_MP_DECL()); + jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, + jlong compare_value IS_MP_DECL()); +} + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + return _Atomic_add(add_value, dest IS_MP_ARG()); +} + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + return _Atomic_xchg(exchange_value, dest); +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value IS_MP_ARG()); +} + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + return _Atomic_cmpxchg(exchange_value, dest, compare_value IS_MP_ARG()); +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + return _Atomic_cmpxchg_long(exchange_value, dest, compare_value IS_MP_ARG()); +} + + +#ifdef AMD64 +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } +extern "C" jlong _Atomic_add_long(jlong add_value, volatile jlong* dest); +extern "C" jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest); + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest); +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); +} + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +#else // !AMD64 + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)add((jint)add_value, (volatile jint*)dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add((jint)add_value, (volatile jint*)dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg((jint)exchange_value, (volatile jint*)dest); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +extern "C" void _Atomic_move_long(volatile jlong* src, volatile jlong* dst); + +inline jlong Atomic::load(volatile jlong* src) { + volatile jlong dest; + _Atomic_move_long(src, &dest); + return dest; +} + +inline void Atomic::store(jlong store_value, jlong* dest) { + _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); +} + +inline void Atomic::store(jlong store_value, volatile jlong* dest) { + _Atomic_move_long((volatile jlong*)&store_value, dest); +} + +#endif // AMD64 + +#ifdef _GNU_SOURCE +// Add a lock prefix to an instruction on an MP machine +#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: " + +extern "C" { + inline jint _Atomic_add(jint add_value, volatile jint* dest, int mp) { + jint addend = add_value; + __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)" + : "=r" (addend) + : "0" (addend), "r" (dest), "r" (mp) + : "cc", "memory"); + return addend + add_value; + } + +#ifdef AMD64 + inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest, int mp) { + intptr_t addend = add_value; + __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" + : "=r" (addend) + : "0" (addend), "r" (dest), "r" (mp) + : "cc", "memory"); + return addend + add_value; + } + + inline jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest) { + __asm__ __volatile__ ("xchgq (%2),%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return exchange_value; + } + +#endif // AMD64 + + inline jint _Atomic_xchg(jint exchange_value, volatile jint* dest) { + __asm__ __volatile__ ("xchgl (%2),%0" + : "=r" (exchange_value) + : "0" (exchange_value), "r" (dest) + : "memory"); + return exchange_value; + } + + inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, int mp) { + __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" + : "=a" (exchange_value) + : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; + } + + + inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, int mp) { + __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" + : "=a" (exchange_value) + : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; + } + + // This is the interface to the atomic instruction in solaris_i486.s. + jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp); + + inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp) { +#ifdef AMD64 + __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" + : "=a" (exchange_value) + : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) + : "cc", "memory"); + return exchange_value; +#else + return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value, os::is_MP()); + + #if 0 + // The code below does not work presumably because of the bug in gcc + // The error message says: + // can't find a register in class BREG while reloading asm + // However I want to save this code and later replace _Atomic_cmpxchg_long_gcc + // with such inline asm code: + + volatile jlong_accessor evl, cvl, rv; + evl.long_value = exchange_value; + cvl.long_value = compare_value; + int mp = os::is_MP(); + + __asm__ volatile ("cmp $0, %%esi\n\t" + "je 1f \n\t" + "lock\n\t" + "1: cmpxchg8b (%%edi)\n\t" + : "=a"(cvl.words[0]), "=d"(cvl.words[1]) + : "a"(cvl.words[0]), "d"(cvl.words[1]), + "b"(evl.words[0]), "c"(evl.words[1]), + "D"(dest), "S"(mp) + : "cc", "memory"); + return cvl.long_value; + #endif // if 0 +#endif // AMD64 + } +} +#undef LOCK_IF_MP + +#endif // _GNU_SOURCE + +#endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp --- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,279 +0,0 @@ -/* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP -#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } - - -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - -inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); } -inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); } -inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); } - -inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); } -inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } -inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } - -// For Sun Studio - implementation is in solaris_x86_[32/64].il. -// For gcc - implementation is just below. - -// The lock prefix can be omitted for certain instructions on uniprocessors; to -// facilitate this, os::is_MP() is passed as an additional argument. 64-bit -// processors are assumed to be multi-threaded and/or multi-core, so the extra -// argument is unnecessary. -#ifndef _LP64 -#define IS_MP_DECL() , int is_mp -#define IS_MP_ARG() , (int) os::is_MP() -#else -#define IS_MP_DECL() -#define IS_MP_ARG() -#endif // _LP64 - -extern "C" { - jint _Atomic_add(jint add_value, volatile jint* dest IS_MP_DECL()); - jint _Atomic_xchg(jint exchange_value, volatile jint* dest); - jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, - jbyte compare_value IS_MP_DECL()); - jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, - jint compare_value IS_MP_DECL()); - jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, - jlong compare_value IS_MP_DECL()); -} - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - return _Atomic_add(add_value, dest IS_MP_ARG()); -} - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - return _Atomic_xchg(exchange_value, dest); -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value IS_MP_ARG()); -} - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - return _Atomic_cmpxchg(exchange_value, dest, compare_value IS_MP_ARG()); -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - return _Atomic_cmpxchg_long(exchange_value, dest, compare_value IS_MP_ARG()); -} - - -#ifdef AMD64 -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } -extern "C" jlong _Atomic_add_long(jlong add_value, volatile jlong* dest); -extern "C" jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest); - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest); -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); -} - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -#else // !AMD64 - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)add((jint)add_value, (volatile jint*)dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add((jint)add_value, (volatile jint*)dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg((jint)exchange_value, (volatile jint*)dest); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -extern "C" void _Atomic_move_long(volatile jlong* src, volatile jlong* dst); - -inline jlong Atomic::load(volatile jlong* src) { - volatile jlong dest; - _Atomic_move_long(src, &dest); - return dest; -} - -inline void Atomic::store(jlong store_value, jlong* dest) { - _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); -} - -inline void Atomic::store(jlong store_value, volatile jlong* dest) { - _Atomic_move_long((volatile jlong*)&store_value, dest); -} - -#endif // AMD64 - -#ifdef _GNU_SOURCE -// Add a lock prefix to an instruction on an MP machine -#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: " - -extern "C" { - inline jint _Atomic_add(jint add_value, volatile jint* dest, int mp) { - jint addend = add_value; - __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)" - : "=r" (addend) - : "0" (addend), "r" (dest), "r" (mp) - : "cc", "memory"); - return addend + add_value; - } - -#ifdef AMD64 - inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest, int mp) { - intptr_t addend = add_value; - __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)" - : "=r" (addend) - : "0" (addend), "r" (dest), "r" (mp) - : "cc", "memory"); - return addend + add_value; - } - - inline jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest) { - __asm__ __volatile__ ("xchgq (%2),%0" - : "=r" (exchange_value) - : "0" (exchange_value), "r" (dest) - : "memory"); - return exchange_value; - } - -#endif // AMD64 - - inline jint _Atomic_xchg(jint exchange_value, volatile jint* dest) { - __asm__ __volatile__ ("xchgl (%2),%0" - : "=r" (exchange_value) - : "0" (exchange_value), "r" (dest) - : "memory"); - return exchange_value; - } - - inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, int mp) { - __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" - : "=a" (exchange_value) - : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; - } - - - inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, int mp) { - __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" - : "=a" (exchange_value) - : "q" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; - } - - // This is the interface to the atomic instruction in solaris_i486.s. - jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp); - - inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp) { -#ifdef AMD64 - __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" - : "=a" (exchange_value) - : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) - : "cc", "memory"); - return exchange_value; -#else - return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value, os::is_MP()); - - #if 0 - // The code below does not work presumably because of the bug in gcc - // The error message says: - // can't find a register in class BREG while reloading asm - // However I want to save this code and later replace _Atomic_cmpxchg_long_gcc - // with such inline asm code: - - volatile jlong_accessor evl, cvl, rv; - evl.long_value = exchange_value; - cvl.long_value = compare_value; - int mp = os::is_MP(); - - __asm__ volatile ("cmp $0, %%esi\n\t" - "je 1f \n\t" - "lock\n\t" - "1: cmpxchg8b (%%edi)\n\t" - : "=a"(cvl.words[0]), "=d"(cvl.words[1]) - : "a"(cvl.words[0]), "d"(cvl.words[1]), - "b"(evl.words[0]), "c"(evl.words[1]), - "D"(dest), "S"(mp) - : "cc", "memory"); - return cvl.long_value; - #endif // if 0 -#endif // AMD64 - } -} -#undef LOCK_IF_MP - -#endif // _GNU_SOURCE - -#endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp --- a/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP #define OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -38,7 +38,7 @@ #include "prims/jvm.h" #include "prims/jvm_misc.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/extendedPC.hpp" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -0,0 +1,303 @@ +/* + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP +#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP + +#include "runtime/os.hpp" + +// The following alternative implementations are needed because +// Windows 95 doesn't support (some of) the corresponding Windows NT +// calls. Furthermore, these versions allow inlining in the caller. +// (More precisely: The documentation for InterlockedExchange says +// it is supported for Windows 95. However, when single-stepping +// through the assembly code we cannot step into the routine and +// when looking at the routine address we see only garbage code. +// Better safe then sorry!). Was bug 7/31/98 (gri). +// +// Performance note: On uniprocessors, the 'lock' prefixes are not +// necessary (and expensive). We should generate separate cases if +// this becomes a performance problem. + +#pragma warning(disable: 4035) // Disables warnings reporting missing return statement + +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } + +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } + +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } + + +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } + +// Adding a lock prefix to an instruction on MP machine +// VC++ doesn't like the lock prefix to be on a single line +// so we can't insert a label after the lock prefix. +// By emitting a lock prefix, we can define a label after it. +#define LOCK_IF_MP(mp) __asm cmp mp, 0 \ + __asm je L0 \ + __asm _emit 0xF0 \ + __asm L0: + +#ifdef AMD64 +inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } +inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + return (jint)(*os::atomic_add_func)(add_value, dest); +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)(*os::atomic_add_ptr_func)(add_value, dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)(*os::atomic_add_ptr_func)(add_value, (volatile intptr_t*)dest); +} + +inline void Atomic::inc (volatile jint* dest) { + (void)add (1, dest); +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + (void)add_ptr(1, dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + (void)add_ptr(1, dest); +} + +inline void Atomic::dec (volatile jint* dest) { + (void)add (-1, dest); +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + (void)add_ptr(-1, dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + (void)add_ptr(-1, dest); +} + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + return (jint)(*os::atomic_xchg_func)(exchange_value, dest); +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)(os::atomic_xchg_ptr_func)(exchange_value, dest); +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void *)(os::atomic_xchg_ptr_func)((intptr_t)exchange_value, (volatile intptr_t*)dest); +} + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value); +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + return (*os::atomic_cmpxchg_byte_func)(exchange_value, dest, compare_value); +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value); +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); +} + +inline jlong Atomic::load(volatile jlong* src) { return *src; } + +#else // !AMD64 + +inline jint Atomic::add (jint add_value, volatile jint* dest) { + int mp = os::is_MP(); + __asm { + mov edx, dest; + mov eax, add_value; + mov ecx, eax; + LOCK_IF_MP(mp) + xadd dword ptr [edx], eax; + add eax, ecx; + } +} + +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { + return (intptr_t)add((jint)add_value, (volatile jint*)dest); +} + +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { + return (void*)add((jint)add_value, (volatile jint*)dest); +} + +inline void Atomic::inc (volatile jint* dest) { + // alternative for InterlockedIncrement + int mp = os::is_MP(); + __asm { + mov edx, dest; + LOCK_IF_MP(mp) + add dword ptr [edx], 1; + } +} + +inline void Atomic::inc_ptr(volatile intptr_t* dest) { + inc((volatile jint*)dest); +} + +inline void Atomic::inc_ptr(volatile void* dest) { + inc((volatile jint*)dest); +} + +inline void Atomic::dec (volatile jint* dest) { + // alternative for InterlockedDecrement + int mp = os::is_MP(); + __asm { + mov edx, dest; + LOCK_IF_MP(mp) + sub dword ptr [edx], 1; + } +} + +inline void Atomic::dec_ptr(volatile intptr_t* dest) { + dec((volatile jint*)dest); +} + +inline void Atomic::dec_ptr(volatile void* dest) { + dec((volatile jint*)dest); +} + +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { + // alternative for InterlockedExchange + __asm { + mov eax, exchange_value; + mov ecx, dest; + xchg eax, dword ptr [ecx]; + } +} + +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { + return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); +} + +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { + return (void*)xchg((jint)exchange_value, (volatile jint*)dest); +} + +#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE +inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { + // alternative for InterlockedCompareExchange + int mp = os::is_MP(); + __asm { + mov edx, dest + mov cl, exchange_value + mov al, compare_value + LOCK_IF_MP(mp) + cmpxchg byte ptr [edx], cl + } +} + +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { + // alternative for InterlockedCompareExchange + int mp = os::is_MP(); + __asm { + mov edx, dest + mov ecx, exchange_value + mov eax, compare_value + LOCK_IF_MP(mp) + cmpxchg dword ptr [edx], ecx + } +} + +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { + int mp = os::is_MP(); + jint ex_lo = (jint)exchange_value; + jint ex_hi = *( ((jint*)&exchange_value) + 1 ); + jint cmp_lo = (jint)compare_value; + jint cmp_hi = *( ((jint*)&compare_value) + 1 ); + __asm { + push ebx + push edi + mov eax, cmp_lo + mov edx, cmp_hi + mov edi, dest + mov ebx, ex_lo + mov ecx, ex_hi + LOCK_IF_MP(mp) + cmpxchg8b qword ptr [edi] + pop edi + pop ebx + } +} + +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { + return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { + return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); +} + +inline jlong Atomic::load(volatile jlong* src) { + volatile jlong dest; + volatile jlong* pdest = &dest; + __asm { + mov eax, src + fild qword ptr [eax] + mov eax, pdest + fistp qword ptr [eax] + } + return dest; +} + +inline void Atomic::store(jlong store_value, volatile jlong* dest) { + volatile jlong* src = &store_value; + __asm { + mov eax, src + fild qword ptr [eax] + mov eax, dest + fistp qword ptr [eax] + } +} + +inline void Atomic::store(jlong store_value, jlong* dest) { + Atomic::store(store_value, (volatile jlong*)dest); +} + +#endif // AMD64 + +#pragma warning(default: 4035) // Enables warnings reporting missing return statement + +#endif // OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp --- a/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,304 +0,0 @@ -/* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP -#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "runtime/os.hpp" - -// The following alternative implementations are needed because -// Windows 95 doesn't support (some of) the corresponding Windows NT -// calls. Furthermore, these versions allow inlining in the caller. -// (More precisely: The documentation for InterlockedExchange says -// it is supported for Windows 95. However, when single-stepping -// through the assembly code we cannot step into the routine and -// when looking at the routine address we see only garbage code. -// Better safe then sorry!). Was bug 7/31/98 (gri). -// -// Performance note: On uniprocessors, the 'lock' prefixes are not -// necessary (and expensive). We should generate separate cases if -// this becomes a performance problem. - -#pragma warning(disable: 4035) // Disables warnings reporting missing return statement - -inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } - -inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } - -inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } -inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } -inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } - - -inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } -inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } - -// Adding a lock prefix to an instruction on MP machine -// VC++ doesn't like the lock prefix to be on a single line -// so we can't insert a label after the lock prefix. -// By emitting a lock prefix, we can define a label after it. -#define LOCK_IF_MP(mp) __asm cmp mp, 0 \ - __asm je L0 \ - __asm _emit 0xF0 \ - __asm L0: - -#ifdef AMD64 -inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; } -inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; } - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - return (jint)(*os::atomic_add_func)(add_value, dest); -} - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)(*os::atomic_add_ptr_func)(add_value, dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)(*os::atomic_add_ptr_func)(add_value, (volatile intptr_t*)dest); -} - -inline void Atomic::inc (volatile jint* dest) { - (void)add (1, dest); -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - (void)add_ptr(1, dest); -} - -inline void Atomic::inc_ptr(volatile void* dest) { - (void)add_ptr(1, dest); -} - -inline void Atomic::dec (volatile jint* dest) { - (void)add (-1, dest); -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - (void)add_ptr(-1, dest); -} - -inline void Atomic::dec_ptr(volatile void* dest) { - (void)add_ptr(-1, dest); -} - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - return (jint)(*os::atomic_xchg_func)(exchange_value, dest); -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)(os::atomic_xchg_ptr_func)(exchange_value, dest); -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void *)(os::atomic_xchg_ptr_func)((intptr_t)exchange_value, (volatile intptr_t*)dest); -} - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value); -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - return (*os::atomic_cmpxchg_byte_func)(exchange_value, dest, compare_value); -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value); -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, order); -} - -inline jlong Atomic::load(volatile jlong* src) { return *src; } - -#else // !AMD64 - -inline jint Atomic::add (jint add_value, volatile jint* dest) { - int mp = os::is_MP(); - __asm { - mov edx, dest; - mov eax, add_value; - mov ecx, eax; - LOCK_IF_MP(mp) - xadd dword ptr [edx], eax; - add eax, ecx; - } -} - -inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { - return (intptr_t)add((jint)add_value, (volatile jint*)dest); -} - -inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { - return (void*)add((jint)add_value, (volatile jint*)dest); -} - -inline void Atomic::inc (volatile jint* dest) { - // alternative for InterlockedIncrement - int mp = os::is_MP(); - __asm { - mov edx, dest; - LOCK_IF_MP(mp) - add dword ptr [edx], 1; - } -} - -inline void Atomic::inc_ptr(volatile intptr_t* dest) { - inc((volatile jint*)dest); -} - -inline void Atomic::inc_ptr(volatile void* dest) { - inc((volatile jint*)dest); -} - -inline void Atomic::dec (volatile jint* dest) { - // alternative for InterlockedDecrement - int mp = os::is_MP(); - __asm { - mov edx, dest; - LOCK_IF_MP(mp) - sub dword ptr [edx], 1; - } -} - -inline void Atomic::dec_ptr(volatile intptr_t* dest) { - dec((volatile jint*)dest); -} - -inline void Atomic::dec_ptr(volatile void* dest) { - dec((volatile jint*)dest); -} - -inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { - // alternative for InterlockedExchange - __asm { - mov eax, exchange_value; - mov ecx, dest; - xchg eax, dword ptr [ecx]; - } -} - -inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { - return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); -} - -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { - return (void*)xchg((jint)exchange_value, (volatile jint*)dest); -} - -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value, cmpxchg_memory_order order) { - // alternative for InterlockedCompareExchange - int mp = os::is_MP(); - __asm { - mov edx, dest - mov cl, exchange_value - mov al, compare_value - LOCK_IF_MP(mp) - cmpxchg byte ptr [edx], cl - } -} - -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value, cmpxchg_memory_order order) { - // alternative for InterlockedCompareExchange - int mp = os::is_MP(); - __asm { - mov edx, dest - mov ecx, exchange_value - mov eax, compare_value - LOCK_IF_MP(mp) - cmpxchg dword ptr [edx], ecx - } -} - -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value, cmpxchg_memory_order order) { - int mp = os::is_MP(); - jint ex_lo = (jint)exchange_value; - jint ex_hi = *( ((jint*)&exchange_value) + 1 ); - jint cmp_lo = (jint)compare_value; - jint cmp_hi = *( ((jint*)&compare_value) + 1 ); - __asm { - push ebx - push edi - mov eax, cmp_lo - mov edx, cmp_hi - mov edi, dest - mov ebx, ex_lo - mov ecx, ex_hi - LOCK_IF_MP(mp) - cmpxchg8b qword ptr [edi] - pop edi - pop ebx - } -} - -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value, cmpxchg_memory_order order) { - return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order) { - return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value, order); -} - -inline jlong Atomic::load(volatile jlong* src) { - volatile jlong dest; - volatile jlong* pdest = &dest; - __asm { - mov eax, src - fild qword ptr [eax] - mov eax, pdest - fistp qword ptr [eax] - } - return dest; -} - -inline void Atomic::store(jlong store_value, volatile jlong* dest) { - volatile jlong* src = &store_value; - __asm { - mov eax, src - fild qword ptr [eax] - mov eax, dest - fistp qword ptr [eax] - } -} - -inline void Atomic::store(jlong store_value, jlong* dest) { - Atomic::store(store_value, (volatile jlong*)dest); -} - -#endif // AMD64 - -#pragma warning(default: 4035) // Enables warnings reporting missing return statement - -#endif // OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp --- a/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP #include -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "runtime/os.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/asm/assembler.cpp --- a/hotspot/src/share/vm/asm/assembler.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/asm/assembler.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "asm/codeBuffer.hpp" #include "asm/macroAssembler.hpp" #include "asm/macroAssembler.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" #include "runtime/thread.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/c1/c1_Runtime1.cpp --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -49,7 +49,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayKlass.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -63,7 +63,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/javaCalls.hpp" #include "runtime/jniHandles.hpp" #include "runtime/mutex.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/classfile/stringTable.cpp --- a/hotspot/src/share/vm/classfile/stringTable.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/classfile/stringTable.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -34,7 +34,7 @@ #include "memory/filemap.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/classfile/symbolTable.cpp --- a/hotspot/src/share/vm/classfile/symbolTable.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -34,7 +34,7 @@ #include "memory/filemap.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/hashtable.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/code/nmethod.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -41,7 +41,7 @@ #include "oops/methodData.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiImpl.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/compiler/compileBroker.cpp --- a/hotspot/src/share/vm/compiler/compileBroker.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -42,7 +42,7 @@ #include "prims/nativeLookup.hpp" #include "prims/whitebox.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -61,7 +61,7 @@ #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/cms/parNewGeneration.cpp --- a/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/cms/parNewGeneration.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -50,7 +50,7 @@ #include "memory/resourceArea.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp --- a/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/collectionSetChooser.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -26,7 +26,7 @@ #include "gc/g1/collectionSetChooser.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/shared/space.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" // Even though we don't use the GC efficiency in our heuristics as // much as we used to, we still order according to GC efficiency. This diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp --- a/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -27,7 +27,7 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/shared/workgroup.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp --- a/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "gc/shared/workgroup.hpp" #include "logging/log.hpp" #include "memory/universe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/os.hpp" #include "utilities/bitMap.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -75,7 +75,7 @@ #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/init.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/vmThread.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp --- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -52,7 +52,7 @@ #include "memory/allocation.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/prefetch.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp --- a/hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #define SHARE_VM_GC_G1_G1EVACSTATS_INLINE_HPP #include "gc/g1/g1EvacStats.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" inline void G1EvacStats::add_direct_allocated(size_t value) { Atomic::add_ptr(value, &_direct_allocated); diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp --- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/g1/dirtyCardQueue.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1HotCardCache.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" G1HotCardCache::G1HotCardCache(G1CollectedHeap *g1h): _g1h(g1h), _hot_cache(NULL), _use_cache(false), _card_counts(g1h) {} diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp --- a/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1MarkSweep.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,7 @@ #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/fprofiler.hpp" #include "runtime/synchronizer.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp --- a/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1SATBCardTableModRefBS.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "gc/shared/memset_with_concurrent_readers.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/thread.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1StringDedup.cpp --- a/hotspot/src/share/vm/gc/g1/g1StringDedup.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1StringDedup.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -31,7 +31,7 @@ #include "gc/g1/g1StringDedupStat.hpp" #include "gc/g1/g1StringDedupTable.hpp" #include "gc/g1/g1StringDedupThread.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" bool G1StringDedup::_enabled = false; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1StringDedup.hpp --- a/hotspot/src/share/vm/gc/g1/g1StringDedup.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1StringDedup.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,6 @@ #include "memory/allocation.hpp" #include "oops/oop.hpp" -#include "runtime/atomic.hpp" class OopClosure; class BoolObjectClosure; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp --- a/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1StringDedupQueue.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "gc/shared/gcLocker.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" #include "utilities/stack.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp --- a/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/g1StringDedupThread.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -31,7 +31,7 @@ #include "gc/g1/suspendibleThreadSet.hpp" #include "logging/log.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" G1StringDedupThread* G1StringDedupThread::_thread = NULL; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -39,7 +39,7 @@ #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" int HeapRegion::LogOfHRGrainBytes = 0; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp --- a/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/heapRegion.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "gc/g1/heapRegion.hpp" #include "gc/shared/space.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" inline HeapWord* G1ContiguousSpace::allocate_impl(size_t min_word_size, size_t desired_word_size, diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -33,7 +33,7 @@ #include "memory/allocation.hpp" #include "memory/padded.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/bitMap.inline.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/g1/sparsePRT.cpp --- a/hotspot/src/share/vm/gc/g1/sparsePRT.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/g1/sparsePRT.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "gc/shared/cardTableModRefBS.hpp" #include "gc/shared/space.inline.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutexLocker.hpp" // Check that the size of the SparsePRTEntry is evenly divisible by the maximum diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp --- a/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/parallel/gcTaskThread.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/os.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp --- a/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/parallel/mutableNUMASpace.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,6 +1,5 @@ - /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +27,7 @@ #include "gc/shared/collectedHeap.hpp" #include "gc/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/thread.inline.hpp" MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) { diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/parallel/mutableSpace.cpp --- a/hotspot/src/share/vm/gc/parallel/mutableSpace.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/parallel/mutableSpace.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/parallel/mutableSpace.hpp" #include "gc/shared/spaceDecorator.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/safepoint.hpp" #include "runtime/thread.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp --- a/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/parallel/parMarkBitMap.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -27,7 +27,7 @@ #include "gc/parallel/psCompactionManager.inline.hpp" #include "gc/parallel/psParallelCompact.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" #include "utilities/bitMap.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp --- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -38,7 +38,7 @@ #include "oops/instanceMirrorKlass.inline.hpp" #include "oops/objArrayKlass.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" PSOldGen* ParCompactionManager::_old_gen = NULL; ParCompactionManager** ParCompactionManager::_manager_array = NULL; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp --- a/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/parallel/psParallelCompact.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -57,7 +57,7 @@ #include "oops/methodData.hpp" #include "oops/objArrayKlass.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/fprofiler.hpp" #include "runtime/safepoint.hpp" #include "runtime/vmThread.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/serial/defNewGeneration.cpp --- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -46,7 +46,7 @@ #include "memory/resourceArea.hpp" #include "oops/instanceRefKlass.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/java.hpp" #include "runtime/prefetch.inline.hpp" #include "runtime/thread.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/cardTableRS.cpp --- a/hotspot/src/share/vm/gc/shared/cardTableRS.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/cardTableRS.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -29,7 +29,7 @@ #include "gc/shared/space.inline.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/gcLocker.cpp --- a/hotspot/src/share/vm/gc/shared/gcLocker.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/gcLocker.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "gc/shared/gcLocker.inline.hpp" #include "memory/resourceArea.hpp" #include "logging/log.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/thread.inline.hpp" volatile jint GCLocker::_jni_lock_count = 0; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/plab.inline.hpp --- a/hotspot/src/share/vm/gc/shared/plab.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/plab.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/plab.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" inline HeapWord* PLAB::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) { HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes); diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/space.cpp --- a/hotspot/src/share/vm/gc/shared/space.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/space.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ #include "gc/shared/spaceDecorator.hpp" #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/java.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/prefetch.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/taskqueue.cpp --- a/hotspot/src/share/vm/gc/shared/taskqueue.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/taskqueue.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "gc/shared/taskqueue.hpp" #include "oops/oop.inline.hpp" #include "logging/log.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/thread.inline.hpp" #include "utilities/debug.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp --- a/hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/taskqueue.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc/shared/taskqueue.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/debug.hpp" #include "utilities/stack.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/gc/shared/workgroup.cpp --- a/hotspot/src/share/vm/gc/shared/workgroup.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/gc/shared/workgroup.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -28,7 +28,7 @@ #include "gc/shared/workerManager.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/semaphore.hpp" #include "runtime/thread.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp --- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -39,7 +39,7 @@ #include "oops/oop.inline.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/frame.inline.hpp" #include "runtime/handles.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -48,7 +48,7 @@ #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/nativeLookup.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/logging/logOutputList.cpp --- a/hotspot/src/share/vm/logging/logOutputList.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/logging/logOutputList.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #include "logging/logLevel.hpp" #include "logging/logOutputList.hpp" #include "memory/allocation.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/globalDefinitions.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/logging/logOutputList.hpp --- a/hotspot/src/share/vm/logging/logOutputList.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/logging/logOutputList.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ #include "logging/logLevel.hpp" #include "memory/allocation.hpp" -#include "runtime/atomic.hpp" #include "utilities/globalDefinitions.hpp" class LogOutput; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/memory/allocation.cpp --- a/hotspot/src/share/vm/memory/allocation.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/memory/allocation.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/task.hpp" #include "runtime/threadCritical.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/memory/allocation.inline.hpp --- a/hotspot/src/share/vm/memory/allocation.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/memory/allocation.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ #ifndef SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP #define SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp" #include "utilities/globalDefinitions.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -37,7 +37,7 @@ #include "memory/metaspaceTracer.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/init.hpp" #include "runtime/java.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/memory/universe.cpp --- a/hotspot/src/share/vm/memory/universe.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/memory/universe.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -56,7 +56,7 @@ #include "oops/oop.inline.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/commandLineFlagConstraintList.hpp" #include "runtime/deoptimization.hpp" #include "runtime/fprofiler.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/compiledICHolder.cpp --- a/hotspot/src/share/vm/oops/compiledICHolder.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/compiledICHolder.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,7 @@ #include "oops/compiledICHolder.hpp" #include "oops/klass.hpp" #include "oops/method.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" volatile int CompiledICHolder::_live_count; volatile int CompiledICHolder::_live_not_claimed_count; diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/cpCache.cpp --- a/hotspot/src/share/vm/oops/cpCache.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/cpCache.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -32,7 +32,7 @@ #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" #include "prims/methodHandles.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/orderAccess.inline.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -56,7 +56,7 @@ #include "prims/jvmtiRedefineClasses.hpp" #include "prims/jvmtiThreadState.hpp" #include "prims/methodComparator.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/klass.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -36,7 +36,7 @@ #include "oops/instanceKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "trace/traceMacros.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/oop.inline.hpp --- a/hotspot/src/share/vm/oops/oop.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/oop.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -36,7 +36,7 @@ #include "oops/klass.inline.hpp" #include "oops/markOop.inline.hpp" #include "oops/oop.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/symbol.cpp --- a/hotspot/src/share/vm/oops/symbol.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/symbol.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -29,7 +29,7 @@ #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "oops/symbol.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" Symbol::Symbol(const u1* name, int length, int refcount) { diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/oops/symbol.hpp --- a/hotspot/src/share/vm/oops/symbol.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/oops/symbol.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -26,8 +26,8 @@ #define SHARE_VM_OOPS_SYMBOL_HPP #include "memory/allocation.hpp" -#include "runtime/atomic.hpp" #include "utilities/exceptions.hpp" +#include "utilities/macros.hpp" #include "utilities/utf8.hpp" // A Symbol is a canonicalized string. diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/opto/runtime.cpp --- a/hotspot/src/share/vm/opto/runtime.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/opto/runtime.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -60,7 +60,7 @@ #include "opto/runtime.hpp" #include "opto/subnode.hpp" #include "prims/jvmtiThreadState.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/fprofiler.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/prims/jni.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -59,7 +59,7 @@ #include "prims/jvm_misc.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiThreadState.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/fprofiler.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/prims/jvm.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -54,7 +54,7 @@ #include "prims/privilegedStack.hpp" #include "prims/stackwalk.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/prims/jvmtiImpl.cpp --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ #include "prims/jvmtiEventController.inline.hpp" #include "prims/jvmtiImpl.hpp" #include "prims/jvmtiRedefineClasses.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/deoptimization.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp --- a/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "prims/jvmtiRawMonitor.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" #include "runtime/thread.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/prims/unsafe.cpp --- a/hotspot/src/share/vm/prims/unsafe.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/prims/unsafe.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -32,7 +32,7 @@ #include "prims/jni.h" #include "prims/jvm.h" #include "prims/unsafe.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/atomic.hpp --- a/hotspot/src/share/vm/runtime/atomic.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/atomic.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ #define SHARE_VM_RUNTIME_ATOMIC_HPP #include "memory/allocation.hpp" +#include "utilities/macros.hpp" enum cmpxchg_memory_order { memory_order_relaxed, @@ -119,24 +120,107 @@ inline static void* cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value, cmpxchg_memory_order order = memory_order_conservative); }; -// To use Atomic::inc(jshort* dest) and Atomic::dec(jshort* dest), the address must be specially -// aligned, such that (*dest) occupies the upper 16 bits of an aligned 32-bit word. The best way to -// achieve is to place your short value next to another short value, which doesn't need atomic ops. -// -// Example -// ATOMIC_SHORT_PAIR( -// volatile short _refcount, // needs atomic operation -// unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op) -// ); +// platform specific in-line definitions - must come before shared definitions + +#include OS_CPU_HEADER(atomic) -#ifdef VM_LITTLE_ENDIAN - #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ - non_atomic_decl; \ - atomic_decl -#else - #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ - atomic_decl; \ - non_atomic_decl +// shared in-line definitions + +// size_t casts... +#if (SIZE_MAX != UINTPTR_MAX) +#error size_t is not WORD_SIZE, interesting platform, but missing implementation here #endif +inline size_t Atomic::add(size_t add_value, volatile size_t* dest) { + return (size_t) add_ptr((intptr_t) add_value, (volatile intptr_t*) dest); +} + +inline void Atomic::inc(volatile size_t* dest) { + inc_ptr((volatile intptr_t*) dest); +} + +inline void Atomic::dec(volatile size_t* dest) { + dec_ptr((volatile intptr_t*) dest); +} + +#ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE +/* + * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg + * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition + * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific + * implementation to be used instead. + */ +inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte *dest, jbyte comparand, cmpxchg_memory_order order) +{ + assert(sizeof(jbyte) == 1, "assumption."); + uintptr_t dest_addr = (uintptr_t)dest; + uintptr_t offset = dest_addr % sizeof(jint); + volatile jint* dest_int = (volatile jint*)(dest_addr - offset); + jint cur = *dest_int; + jbyte* cur_as_bytes = (jbyte*)(&cur); + jint new_val = cur; + jbyte* new_val_as_bytes = (jbyte*)(&new_val); + new_val_as_bytes[offset] = exchange_value; + while (cur_as_bytes[offset] == comparand) { + jint res = cmpxchg(new_val, dest_int, cur, order); + if (res == cur) break; + cur = res; + new_val = cur; + new_val_as_bytes[offset] = exchange_value; + } + return cur_as_bytes[offset]; +} +#endif // VM_HAS_SPECIALIZED_CMPXCHG_BYTE + +inline unsigned Atomic::xchg(unsigned int exchange_value, volatile unsigned int* dest) { + assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); + return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest); +} + +inline unsigned Atomic::cmpxchg(unsigned int exchange_value, + volatile unsigned int* dest, unsigned int compare_value, + cmpxchg_memory_order order) { + assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); + return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest, + (jint)compare_value, order); +} + +inline jlong Atomic::add(jlong add_value, volatile jlong* dest) { + jlong old = load(dest); + jlong new_value = old + add_value; + while (old != cmpxchg(new_value, dest, old)) { + old = load(dest); + new_value = old + add_value; + } + return old; +} + +inline void Atomic::inc(volatile short* dest) { + // Most platforms do not support atomic increment on a 2-byte value. However, + // if the value occupies the most significant 16 bits of an aligned 32-bit + // word, then we can do this with an atomic add of 0x10000 to the 32-bit word. + // + // The least significant parts of this 32-bit word will never be affected, even + // in case of overflow/underflow. + // + // Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment. +#ifdef VM_LITTLE_ENDIAN + assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); + (void)Atomic::add(0x10000, (volatile int*)(dest-1)); +#else + assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); + (void)Atomic::add(0x10000, (volatile int*)(dest)); +#endif +} + +inline void Atomic::dec(volatile short* dest) { +#ifdef VM_LITTLE_ENDIAN + assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); + (void)Atomic::add(-0x10000, (volatile int*)(dest-1)); +#else + assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); + (void)Atomic::add(-0x10000, (volatile int*)(dest)); +#endif +} + #endif // SHARE_VM_RUNTIME_ATOMIC_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/atomic.inline.hpp --- a/hotspot/src/share/vm/runtime/atomic.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP -#define SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP - -#include "runtime/atomic.hpp" -#include "utilities/macros.hpp" - -#include OS_CPU_HEADER_INLINE(atomic) - -// size_t casts... -#if (SIZE_MAX != UINTPTR_MAX) -#error size_t is not WORD_SIZE, interesting platform, but missing implementation here -#endif - -inline size_t Atomic::add(size_t add_value, volatile size_t* dest) { - return (size_t) add_ptr((intptr_t) add_value, (volatile intptr_t*) dest); -} - -inline void Atomic::inc(volatile size_t* dest) { - inc_ptr((volatile intptr_t*) dest); -} - -inline void Atomic::dec(volatile size_t* dest) { - dec_ptr((volatile intptr_t*) dest); -} - -#ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE -/* - * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg - * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition - * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific - * implementation to be used instead. - */ -inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte *dest, jbyte comparand, cmpxchg_memory_order order) -{ - assert(sizeof(jbyte) == 1, "assumption."); - uintptr_t dest_addr = (uintptr_t)dest; - uintptr_t offset = dest_addr % sizeof(jint); - volatile jint* dest_int = (volatile jint*)(dest_addr - offset); - jint cur = *dest_int; - jbyte* cur_as_bytes = (jbyte*)(&cur); - jint new_val = cur; - jbyte* new_val_as_bytes = (jbyte*)(&new_val); - new_val_as_bytes[offset] = exchange_value; - while (cur_as_bytes[offset] == comparand) { - jint res = cmpxchg(new_val, dest_int, cur, order); - if (res == cur) break; - cur = res; - new_val = cur; - new_val_as_bytes[offset] = exchange_value; - } - return cur_as_bytes[offset]; -} -#endif // VM_HAS_SPECIALIZED_CMPXCHG_BYTE - -inline unsigned Atomic::xchg(unsigned int exchange_value, volatile unsigned int* dest) { - assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); - return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest); -} - -inline unsigned Atomic::cmpxchg(unsigned int exchange_value, - volatile unsigned int* dest, unsigned int compare_value, - cmpxchg_memory_order order) { - assert(sizeof(unsigned int) == sizeof(jint), "more work to do"); - return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest, - (jint)compare_value, order); -} - -inline jlong Atomic::add(jlong add_value, volatile jlong* dest) { - jlong old = load(dest); - jlong new_value = old + add_value; - while (old != cmpxchg(new_value, dest, old)) { - old = load(dest); - new_value = old + add_value; - } - return old; -} - -inline void Atomic::inc(volatile short* dest) { - // Most platforms do not support atomic increment on a 2-byte value. However, - // if the value occupies the most significant 16 bits of an aligned 32-bit - // word, then we can do this with an atomic add of 0x10000 to the 32-bit word. - // - // The least significant parts of this 32-bit word will never be affected, even - // in case of overflow/underflow. - // - // Use the ATOMIC_SHORT_PAIR macro to get the desired alignment. -#ifdef VM_LITTLE_ENDIAN - assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); - (void)Atomic::add(0x10000, (volatile int*)(dest-1)); -#else - assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); - (void)Atomic::add(0x10000, (volatile int*)(dest)); -#endif -} - -inline void Atomic::dec(volatile short* dest) { -#ifdef VM_LITTLE_ENDIAN - assert((intx(dest) & 0x03) == 0x02, "wrong alignment"); - (void)Atomic::add(-0x10000, (volatile int*)(dest-1)); -#else - assert((intx(dest) & 0x03) == 0x00, "wrong alignment"); - (void)Atomic::add(-0x10000, (volatile int*)(dest)); -#endif -} - -#endif // SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/biasedLocking.cpp --- a/hotspot/src/share/vm/runtime/biasedLocking.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -28,7 +28,7 @@ #include "oops/klass.inline.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/basicLock.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/task.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/handles.cpp --- a/hotspot/src/share/vm/runtime/handles.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/handles.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -26,7 +26,7 @@ #include "memory/allocation.inline.hpp" #include "oops/constantPool.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/thread.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/interfaceSupport.cpp --- a/hotspot/src/share/vm/runtime/interfaceSupport.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/interfaceSupport.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/genCollectedHeap.hpp" #include "memory/resourceArea.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/init.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/orderAccess.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/mutex.cpp --- a/hotspot/src/share/vm/runtime/mutex.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/mutex.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutex.hpp" #include "runtime/orderAccess.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/objectMonitor.cpp --- a/hotspot/src/share/vm/runtime/objectMonitor.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -27,7 +27,7 @@ #include "memory/resourceArea.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutexLocker.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/orderAccess.inline.hpp --- a/hotspot/src/share/vm/runtime/orderAccess.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/orderAccess.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -26,7 +26,7 @@ #ifndef SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP #define SHARE_VM_RUNTIME_ORDERACCESS_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "utilities/macros.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/os.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -44,7 +44,7 @@ #include "prims/jvm_misc.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/java.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/safepoint.cpp --- a/hotspot/src/share/vm/runtime/safepoint.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -39,7 +39,7 @@ #include "memory/universe.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/deoptimization.hpp" #include "runtime/frame.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -49,7 +49,7 @@ #include "prims/methodHandles.hpp" #include "prims/nativeLookup.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/handles.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/sweeper.cpp --- a/hotspot/src/share/vm/runtime/sweeper.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/sweeper.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "compiler/compileBroker.hpp" #include "memory/resourceArea.hpp" #include "oops/method.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/compilationPolicy.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/synchronizer.cpp --- a/hotspot/src/share/vm/runtime/synchronizer.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -30,7 +30,7 @@ #include "memory/resourceArea.hpp" #include "oops/markOop.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/thread.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -57,7 +57,7 @@ #include "prims/jvmtiThreadState.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/commandLineFlagConstraintList.hpp" #include "runtime/commandLineFlagWriteableList.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/runtime/thread.inline.hpp --- a/hotspot/src/share/vm/runtime/thread.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/runtime/thread.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ #define SHARE_VM_RUNTIME_THREAD_INLINE_HPP_SCOPE -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.inline.hpp" #include "runtime/thread.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/services/mallocTracker.cpp --- a/hotspot/src/share/vm/services/mallocTracker.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/services/mallocTracker.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,6 @@ #include "precompiled.hpp" #include "runtime/atomic.hpp" -#include "runtime/atomic.inline.hpp" #include "services/mallocSiteTable.hpp" #include "services/mallocTracker.hpp" #include "services/mallocTracker.inline.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/services/memTracker.hpp --- a/hotspot/src/share/vm/services/memTracker.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/services/memTracker.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -75,7 +75,6 @@ #else -#include "runtime/atomic.hpp" #include "runtime/threadCritical.hpp" #include "services/mallocTracker.hpp" #include "services/virtualMemoryTracker.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/services/threadService.cpp --- a/hotspot/src/share/vm/services/threadService.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/services/threadService.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -31,7 +31,7 @@ #include "oops/instanceKlass.hpp" #include "oops/objArrayOop.inline.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.inline.hpp" #include "runtime/init.hpp" #include "runtime/thread.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/services/virtualMemoryTracker.cpp --- a/hotspot/src/share/vm/services/virtualMemoryTracker.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/services/virtualMemoryTracker.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/os.hpp" #include "runtime/threadCritical.hpp" #include "services/memTracker.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/shark/sharkRuntime.cpp --- a/hotspot/src/share/vm/shark/sharkRuntime.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/shark/sharkRuntime.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -24,7 +24,7 @@ */ #include "precompiled.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/biasedLocking.hpp" #include "runtime/deoptimization.hpp" #include "runtime/thread.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/accessFlags.cpp --- a/hotspot/src/share/vm/utilities/accessFlags.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/accessFlags.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/accessFlags.hpp" void AccessFlags::atomic_set_bits(jint bits) { diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/bitMap.cpp --- a/hotspot/src/share/vm/utilities/bitMap.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/bitMap.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -25,7 +25,7 @@ #include "precompiled.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/bitMap.inline.hpp" #include "utilities/copy.hpp" #include "utilities/debug.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/bitMap.inline.hpp --- a/hotspot/src/share/vm/utilities/bitMap.inline.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/bitMap.inline.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -25,7 +25,7 @@ #ifndef SHARE_VM_UTILITIES_BITMAP_INLINE_HPP #define SHARE_VM_UTILITIES_BITMAP_INLINE_HPP -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/bitMap.hpp" inline void BitMap::set_bit(idx_t bit) { diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/debug.cpp --- a/hotspot/src/share/vm/utilities/debug.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/debug.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -38,7 +38,7 @@ #include "oops/oop.inline.hpp" #include "prims/privilegedStack.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.hpp" #include "runtime/java.hpp" #include "runtime/os.hpp" diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/histogram.cpp --- a/hotspot/src/share/vm/utilities/histogram.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/histogram.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "oops/oop.inline.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "utilities/histogram.hpp" #ifdef ASSERT diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/macros.hpp --- a/hotspot/src/share/vm/utilities/macros.hpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/macros.hpp Sun Aug 21 20:56:37 2016 -0400 @@ -486,4 +486,24 @@ #define OS_CPU_HEADER(basename) XSTR(OS_CPU_HEADER_STEM(basename).hpp) #define OS_CPU_HEADER_INLINE(basename) XSTR(OS_CPU_HEADER_STEM(basename).inline.hpp) +// To use Atomic::inc(jshort* dest) and Atomic::dec(jshort* dest), the address must be specially +// aligned, such that (*dest) occupies the upper 16 bits of an aligned 32-bit word. The best way to +// achieve is to place your short value next to another short value, which doesn't need atomic ops. +// +// Example +// ATOMIC_SHORT_PAIR( +// volatile short _refcount, // needs atomic operation +// unsigned short _length // number of UTF8 characters in the symbol (does not need atomic op) +// ); + +#ifdef VM_LITTLE_ENDIAN + #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ + non_atomic_decl; \ + atomic_decl +#else + #define ATOMIC_SHORT_PAIR(atomic_decl, non_atomic_decl) \ + atomic_decl; \ + non_atomic_decl +#endif + #endif // SHARE_VM_UTILITIES_MACROS_HPP diff -r d4f8e348420a -r 9f644073d3a0 hotspot/src/share/vm/utilities/vmError.cpp --- a/hotspot/src/share/vm/utilities/vmError.cpp Sun Aug 21 06:18:09 2016 +0200 +++ b/hotspot/src/share/vm/utilities/vmError.cpp Sun Aug 21 20:56:37 2016 -0400 @@ -31,7 +31,7 @@ #include "logging/logConfiguration.hpp" #include "prims/whitebox.hpp" #include "runtime/arguments.hpp" -#include "runtime/atomic.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/init.hpp" #include "runtime/os.hpp"