Thu, 26 Mar 2009 14:31:45 -0700
6822204: volatile fences should prefer lock:addl to actual mfence instructions
Reviewed-by: kvn, phh
1.1 --- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Tue Mar 24 15:09:52 2009 -0700 1.2 +++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Thu Mar 26 14:31:45 2009 -0700 1.3 @@ -817,21 +817,6 @@ 1.4 Label _atomic_add_stub; // called from other stubs 1.5 1.6 1.7 - // Support for void OrderAccess::fence(). 1.8 - // 1.9 - address generate_fence() { 1.10 - StubCodeMark mark(this, "StubRoutines", "fence"); 1.11 - address start = __ pc(); 1.12 - 1.13 - __ membar(Assembler::Membar_mask_bits(Assembler::LoadLoad | Assembler::LoadStore | 1.14 - Assembler::StoreLoad | Assembler::StoreStore)); 1.15 - __ retl(false); 1.16 - __ delayed()->nop(); 1.17 - 1.18 - return start; 1.19 - } 1.20 - 1.21 - 1.22 //------------------------------------------------------------------------------------------------------------------------ 1.23 // The following routine generates a subroutine to throw an asynchronous 1.24 // UnknownError when an unsafe access gets a fault that could not be 1.25 @@ -2861,7 +2846,6 @@ 1.26 StubRoutines::_atomic_cmpxchg_ptr_entry = StubRoutines::_atomic_cmpxchg_entry; 1.27 StubRoutines::_atomic_cmpxchg_long_entry = generate_atomic_cmpxchg_long(); 1.28 StubRoutines::_atomic_add_ptr_entry = StubRoutines::_atomic_add_entry; 1.29 - StubRoutines::_fence_entry = generate_fence(); 1.30 #endif // COMPILER2 !=> _LP64 1.31 } 1.32
2.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Tue Mar 24 15:09:52 2009 -0700 2.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Thu Mar 26 14:31:45 2009 -0700 2.3 @@ -1438,26 +1438,12 @@ 2.4 } 2.5 } 2.6 2.7 -// Serializes memory. 2.8 +// Emit mfence instruction 2.9 void Assembler::mfence() { 2.10 - // Memory barriers are only needed on multiprocessors 2.11 - if (os::is_MP()) { 2.12 - if( LP64_ONLY(true ||) VM_Version::supports_sse2() ) { 2.13 - emit_byte( 0x0F ); // MFENCE; faster blows no regs 2.14 - emit_byte( 0xAE ); 2.15 - emit_byte( 0xF0 ); 2.16 - } else { 2.17 - // All usable chips support "locked" instructions which suffice 2.18 - // as barriers, and are much faster than the alternative of 2.19 - // using cpuid instruction. We use here a locked add [esp],0. 2.20 - // This is conveniently otherwise a no-op except for blowing 2.21 - // flags (which we save and restore.) 2.22 - pushf(); // Save eflags register 2.23 - lock(); 2.24 - addl(Address(rsp, 0), 0);// Assert the lock# signal here 2.25 - popf(); // Restore eflags register 2.26 - } 2.27 - } 2.28 + NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");) 2.29 + emit_byte( 0x0F ); 2.30 + emit_byte( 0xAE ); 2.31 + emit_byte( 0xF0 ); 2.32 } 2.33 2.34 void Assembler::mov(Register dst, Register src) {
3.1 --- a/src/cpu/x86/vm/assembler_x86.hpp Tue Mar 24 15:09:52 2009 -0700 3.2 +++ b/src/cpu/x86/vm/assembler_x86.hpp Thu Mar 26 14:31:45 2009 -0700 3.3 @@ -1068,15 +1068,23 @@ 3.4 LoadLoad = 1 << 0 3.5 }; 3.6 3.7 - // Serializes memory. 3.8 + // Serializes memory and blows flags 3.9 void membar(Membar_mask_bits order_constraint) { 3.10 - // We only have to handle StoreLoad and LoadLoad 3.11 - if (order_constraint & StoreLoad) { 3.12 - // MFENCE subsumes LFENCE 3.13 - mfence(); 3.14 - } /* [jk] not needed currently: else if (order_constraint & LoadLoad) { 3.15 - lfence(); 3.16 - } */ 3.17 + if (os::is_MP()) { 3.18 + // We only have to handle StoreLoad 3.19 + if (order_constraint & StoreLoad) { 3.20 + // All usable chips support "locked" instructions which suffice 3.21 + // as barriers, and are much faster than the alternative of 3.22 + // using cpuid instruction. We use here a locked add [esp],0. 3.23 + // This is conveniently otherwise a no-op except for blowing 3.24 + // flags. 3.25 + // Any change to this code may need to revisit other places in 3.26 + // the code where this idiom is used, in particular the 3.27 + // orderAccess code. 3.28 + lock(); 3.29 + addl(Address(rsp, 0), 0);// Assert the lock# signal here 3.30 + } 3.31 + } 3.32 } 3.33 3.34 void mfence();
4.1 --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Tue Mar 24 15:09:52 2009 -0700 4.2 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Thu Mar 26 14:31:45 2009 -0700 4.3 @@ -637,7 +637,7 @@ 4.4 address generate_orderaccess_fence() { 4.5 StubCodeMark mark(this, "StubRoutines", "orderaccess_fence"); 4.6 address start = __ pc(); 4.7 - __ mfence(); 4.8 + __ membar(Assembler::StoreLoad); 4.9 __ ret(0); 4.10 4.11 return start;
5.1 --- a/src/cpu/x86/vm/x86_32.ad Tue Mar 24 15:09:52 2009 -0700 5.2 +++ b/src/cpu/x86/vm/x86_32.ad Thu Mar 26 14:31:45 2009 -0700 5.3 @@ -4288,24 +4288,6 @@ 5.4 emit_opcode(cbuf, 0xC8 + $src2$$reg); 5.5 %} 5.6 5.7 - enc_class enc_membar_acquire %{ 5.8 - // Doug Lea believes this is not needed with current Sparcs and TSO. 5.9 - // MacroAssembler masm(&cbuf); 5.10 - // masm.membar(); 5.11 - %} 5.12 - 5.13 - enc_class enc_membar_release %{ 5.14 - // Doug Lea believes this is not needed with current Sparcs and TSO. 5.15 - // MacroAssembler masm(&cbuf); 5.16 - // masm.membar(); 5.17 - %} 5.18 - 5.19 - enc_class enc_membar_volatile %{ 5.20 - MacroAssembler masm(&cbuf); 5.21 - masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad | 5.22 - Assembler::StoreStore)); 5.23 - %} 5.24 - 5.25 // Atomically load the volatile long 5.26 enc_class enc_loadL_volatile( memory mem, stackSlotL dst ) %{ 5.27 emit_opcode(cbuf,0xDF); 5.28 @@ -7498,9 +7480,9 @@ 5.29 ins_cost(400); 5.30 5.31 size(0); 5.32 - format %{ "MEMBAR-acquire" %} 5.33 - ins_encode( enc_membar_acquire ); 5.34 - ins_pipe(pipe_slow); 5.35 + format %{ "MEMBAR-acquire ! (empty encoding)" %} 5.36 + ins_encode(); 5.37 + ins_pipe(empty); 5.38 %} 5.39 5.40 instruct membar_acquire_lock() %{ 5.41 @@ -7519,9 +7501,9 @@ 5.42 ins_cost(400); 5.43 5.44 size(0); 5.45 - format %{ "MEMBAR-release" %} 5.46 - ins_encode( enc_membar_release ); 5.47 - ins_pipe(pipe_slow); 5.48 + format %{ "MEMBAR-release ! (empty encoding)" %} 5.49 + ins_encode( ); 5.50 + ins_pipe(empty); 5.51 %} 5.52 5.53 instruct membar_release_lock() %{ 5.54 @@ -7535,12 +7517,22 @@ 5.55 ins_pipe(empty); 5.56 %} 5.57 5.58 -instruct membar_volatile() %{ 5.59 +instruct membar_volatile(eFlagsReg cr) %{ 5.60 match(MemBarVolatile); 5.61 + effect(KILL cr); 5.62 ins_cost(400); 5.63 5.64 - format %{ "MEMBAR-volatile" %} 5.65 - ins_encode( enc_membar_volatile ); 5.66 + format %{ 5.67 + $$template 5.68 + if (os::is_MP()) { 5.69 + $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile" 5.70 + } else { 5.71 + $$emit$$"MEMBAR-volatile ! (empty encoding)" 5.72 + } 5.73 + %} 5.74 + ins_encode %{ 5.75 + __ membar(Assembler::StoreLoad); 5.76 + %} 5.77 ins_pipe(pipe_slow); 5.78 %} 5.79
6.1 --- a/src/cpu/x86/vm/x86_64.ad Tue Mar 24 15:09:52 2009 -0700 6.2 +++ b/src/cpu/x86/vm/x86_64.ad Thu Mar 26 14:31:45 2009 -0700 6.3 @@ -4162,33 +4162,6 @@ 6.4 // done: 6.5 %} 6.6 6.7 - enc_class enc_membar_acquire 6.8 - %{ 6.9 - // [jk] not needed currently, if you enable this and it really 6.10 - // emits code don't forget to the remove the "size(0)" line in 6.11 - // membar_acquire() 6.12 - // MacroAssembler masm(&cbuf); 6.13 - // masm.membar(Assembler::Membar_mask_bits(Assembler::LoadStore | 6.14 - // Assembler::LoadLoad)); 6.15 - %} 6.16 - 6.17 - enc_class enc_membar_release 6.18 - %{ 6.19 - // [jk] not needed currently, if you enable this and it really 6.20 - // emits code don't forget to the remove the "size(0)" line in 6.21 - // membar_release() 6.22 - // MacroAssembler masm(&cbuf); 6.23 - // masm.membar(Assembler::Membar_mask_bits(Assembler::LoadStore | 6.24 - // Assembler::StoreStore)); 6.25 - %} 6.26 - 6.27 - enc_class enc_membar_volatile 6.28 - %{ 6.29 - MacroAssembler masm(&cbuf); 6.30 - masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad | 6.31 - Assembler::StoreStore)); 6.32 - %} 6.33 - 6.34 // Safepoint Poll. This polls the safepoint page, and causes an 6.35 // exception if it is not readable. Unfortunately, it kills 6.36 // RFLAGS in the process. 6.37 @@ -7458,7 +7431,7 @@ 6.38 ins_cost(0); 6.39 6.40 size(0); 6.41 - format %{ "MEMBAR-acquire" %} 6.42 + format %{ "MEMBAR-acquire ! (empty encoding)" %} 6.43 ins_encode(); 6.44 ins_pipe(empty); 6.45 %} 6.46 @@ -7481,7 +7454,7 @@ 6.47 ins_cost(0); 6.48 6.49 size(0); 6.50 - format %{ "MEMBAR-release" %} 6.51 + format %{ "MEMBAR-release ! (empty encoding)" %} 6.52 ins_encode(); 6.53 ins_pipe(empty); 6.54 %} 6.55 @@ -7498,13 +7471,22 @@ 6.56 ins_pipe(empty); 6.57 %} 6.58 6.59 -instruct membar_volatile() 6.60 -%{ 6.61 +instruct membar_volatile(rFlagsReg cr) %{ 6.62 match(MemBarVolatile); 6.63 + effect(KILL cr); 6.64 ins_cost(400); 6.65 6.66 - format %{ "MEMBAR-volatile" %} 6.67 - ins_encode(enc_membar_volatile); 6.68 + format %{ 6.69 + $$template 6.70 + if (os::is_MP()) { 6.71 + $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6.72 + } else { 6.73 + $$emit$$"MEMBAR-volatile ! (empty encoding)" 6.74 + } 6.75 + %} 6.76 + ins_encode %{ 6.77 + __ membar(Assembler::StoreLoad); 6.78 + %} 6.79 ins_pipe(pipe_slow); 6.80 %} 6.81
7.1 --- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.hpp Tue Mar 24 15:09:52 2009 -0700 7.2 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.hpp Thu Mar 26 14:31:45 2009 -0700 7.3 @@ -29,13 +29,11 @@ 7.4 static jint (*atomic_cmpxchg_func) (jint, volatile jint*, jint); 7.5 static jlong (*atomic_cmpxchg_long_func)(jlong, volatile jlong*, jlong); 7.6 static jint (*atomic_add_func) (jint, volatile jint*); 7.7 - static void (*fence_func) (); 7.8 7.9 static jint atomic_xchg_bootstrap (jint, volatile jint*); 7.10 static jint atomic_cmpxchg_bootstrap (jint, volatile jint*, jint); 7.11 static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong); 7.12 static jint atomic_add_bootstrap (jint, volatile jint*); 7.13 - static void fence_bootstrap (); 7.14 7.15 static void setup_fpu() {} 7.16
8.1 --- a/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Tue Mar 24 15:09:52 2009 -0700 8.2 +++ b/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Thu Mar 26 14:31:45 2009 -0700 8.3 @@ -44,11 +44,12 @@ 8.4 8.5 inline void OrderAccess::fence() { 8.6 if (os::is_MP()) { 8.7 + // always use locked addl since mfence is sometimes expensive 8.8 #ifdef AMD64 8.9 - __asm__ __volatile__ ("mfence":::"memory"); 8.10 + __asm__ volatile ("lock; addl $0,0(%%rsp)" : : : "cc", "memory"); 8.11 #else 8.12 __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory"); 8.13 -#endif // AMD64 8.14 +#endif 8.15 } 8.16 } 8.17
9.1 --- a/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Tue Mar 24 15:09:52 2009 -0700 9.2 +++ b/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Thu Mar 26 14:31:45 2009 -0700 9.3 @@ -60,22 +60,10 @@ 9.4 dummy = 0; 9.5 } 9.6 9.7 -#if defined(COMPILER2) || defined(_LP64) 9.8 - 9.9 inline void OrderAccess::fence() { 9.10 _OrderAccess_fence(); 9.11 } 9.12 9.13 -#else // defined(COMPILER2) || defined(_LP64) 9.14 - 9.15 -inline void OrderAccess::fence() { 9.16 - if (os::is_MP()) { 9.17 - (*os::fence_func)(); 9.18 - } 9.19 -} 9.20 - 9.21 -#endif // defined(COMPILER2) || defined(_LP64) 9.22 - 9.23 #endif // _GNU_SOURCE 9.24 9.25 inline jbyte OrderAccess::load_acquire(volatile jbyte* p) { return *p; }
10.1 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Tue Mar 24 15:09:52 2009 -0700 10.2 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp Thu Mar 26 14:31:45 2009 -0700 10.3 @@ -619,7 +619,6 @@ 10.4 typedef jint cmpxchg_func_t (jint, volatile jint*, jint); 10.5 typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong); 10.6 typedef jint add_func_t (jint, volatile jint*); 10.7 -typedef void fence_func_t (); 10.8 10.9 jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) { 10.10 // try to use the stub: 10.11 @@ -681,25 +680,10 @@ 10.12 return (*dest) += add_value; 10.13 } 10.14 10.15 -void os::fence_bootstrap() { 10.16 - // try to use the stub: 10.17 - fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry()); 10.18 - 10.19 - if (func != NULL) { 10.20 - os::fence_func = func; 10.21 - (*func)(); 10.22 - return; 10.23 - } 10.24 - assert(Threads::number_of_threads() == 0, "for bootstrap only"); 10.25 - 10.26 - // don't have to do anything for a single thread 10.27 -} 10.28 - 10.29 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap; 10.30 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap; 10.31 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; 10.32 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; 10.33 -fence_func_t* os::fence_func = os::fence_bootstrap; 10.34 10.35 #endif // !_LP64 && !COMPILER2 10.36
11.1 --- a/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.hpp Tue Mar 24 15:09:52 2009 -0700 11.2 +++ b/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.hpp Thu Mar 26 14:31:45 2009 -0700 11.3 @@ -29,13 +29,11 @@ 11.4 static jint (*atomic_cmpxchg_func) (jint, volatile jint*, jint); 11.5 static jlong (*atomic_cmpxchg_long_func)(jlong, volatile jlong*, jlong); 11.6 static jint (*atomic_add_func) (jint, volatile jint*); 11.7 - static void (*fence_func) (); 11.8 11.9 static jint atomic_xchg_bootstrap (jint, volatile jint*); 11.10 static jint atomic_cmpxchg_bootstrap (jint, volatile jint*, jint); 11.11 static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong); 11.12 static jint atomic_add_bootstrap (jint, volatile jint*); 11.13 - static void fence_bootstrap (); 11.14 11.15 static void setup_fpu() {} 11.16
12.1 --- a/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Tue Mar 24 15:09:52 2009 -0700 12.2 +++ b/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Thu Mar 26 14:31:45 2009 -0700 12.3 @@ -61,11 +61,8 @@ 12.4 #endif // AMD64 12.5 } 12.6 inline void _OrderAccess_fence() { 12.7 -#ifdef AMD64 12.8 - __asm__ __volatile__ ("mfence":::"memory"); 12.9 -#else 12.10 + // Always use locked addl since mfence is sometimes expensive 12.11 __asm__ volatile ("lock; addl $0,0(%%esp)" : : : "cc", "memory"); 12.12 -#endif // AMD64 12.13 } 12.14 12.15 }
13.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Tue Mar 24 15:09:52 2009 -0700 13.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Thu Mar 26 14:31:45 2009 -0700 13.3 @@ -794,7 +794,6 @@ 13.4 typedef jint cmpxchg_func_t (jint, volatile jint*, jint); 13.5 typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong); 13.6 typedef jint add_func_t (jint, volatile jint*); 13.7 -typedef void fence_func_t (); 13.8 13.9 jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) { 13.10 // try to use the stub: 13.11 @@ -856,25 +855,10 @@ 13.12 return (*dest) += add_value; 13.13 } 13.14 13.15 -void os::fence_bootstrap() { 13.16 - // try to use the stub: 13.17 - fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry()); 13.18 - 13.19 - if (func != NULL) { 13.20 - os::fence_func = func; 13.21 - (*func)(); 13.22 - return; 13.23 - } 13.24 - assert(Threads::number_of_threads() == 0, "for bootstrap only"); 13.25 - 13.26 - // don't have to do anything for a single thread 13.27 -} 13.28 - 13.29 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap; 13.30 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap; 13.31 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap; 13.32 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; 13.33 -fence_func_t* os::fence_func = os::fence_bootstrap; 13.34 13.35 extern "C" _solaris_raw_setup_fpu(address ptr); 13.36 void os::setup_fpu() {
14.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp Tue Mar 24 15:09:52 2009 -0700 14.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp Thu Mar 26 14:31:45 2009 -0700 14.3 @@ -32,13 +32,11 @@ 14.4 static jint (*atomic_cmpxchg_func) (jint, volatile jint*, jint); 14.5 static jlong (*atomic_cmpxchg_long_func)(jlong, volatile jlong*, jlong); 14.6 static jint (*atomic_add_func) (jint, volatile jint*); 14.7 - static void (*fence_func) (); 14.8 14.9 static jint atomic_xchg_bootstrap (jint, volatile jint*); 14.10 static jint atomic_cmpxchg_bootstrap (jint, volatile jint*, jint); 14.11 static jlong atomic_cmpxchg_long_bootstrap(jlong, volatile jlong*, jlong); 14.12 static jint atomic_add_bootstrap (jint, volatile jint*); 14.13 - static void fence_bootstrap (); 14.14 14.15 static void setup_fpu(); 14.16 #endif // AMD64
15.1 --- a/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Tue Mar 24 15:09:52 2009 -0700 15.2 +++ b/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Thu Mar 26 14:31:45 2009 -0700 15.3 @@ -46,7 +46,7 @@ 15.4 15.5 inline void OrderAccess::fence() { 15.6 #ifdef AMD64 15.7 - (*os::fence_func)(); 15.8 + StubRoutines_fence(); 15.9 #else 15.10 if (os::is_MP()) { 15.11 __asm {
16.1 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Tue Mar 24 15:09:52 2009 -0700 16.2 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Mar 26 14:31:45 2009 -0700 16.3 @@ -196,7 +196,6 @@ 16.4 typedef jlong cmpxchg_long_func_t (jlong, volatile jlong*, jlong); 16.5 typedef jint add_func_t (jint, volatile jint*); 16.6 typedef intptr_t add_ptr_func_t (intptr_t, volatile intptr_t*); 16.7 -typedef void fence_func_t (); 16.8 16.9 #ifdef AMD64 16.10 16.11 @@ -292,27 +291,11 @@ 16.12 return (*dest) += add_value; 16.13 } 16.14 16.15 -void os::fence_bootstrap() { 16.16 - // try to use the stub: 16.17 - fence_func_t* func = CAST_TO_FN_PTR(fence_func_t*, StubRoutines::fence_entry()); 16.18 - 16.19 - if (func != NULL) { 16.20 - os::fence_func = func; 16.21 - (*func)(); 16.22 - return; 16.23 - } 16.24 - assert(Threads::number_of_threads() == 0, "for bootstrap only"); 16.25 - 16.26 - // don't have to do anything for a single thread 16.27 -} 16.28 - 16.29 - 16.30 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap; 16.31 xchg_ptr_func_t* os::atomic_xchg_ptr_func = os::atomic_xchg_ptr_bootstrap; 16.32 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap; 16.33 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap; 16.34 add_ptr_func_t* os::atomic_add_ptr_func = os::atomic_add_ptr_bootstrap; 16.35 -fence_func_t* os::fence_func = os::fence_bootstrap; 16.36 16.37 #endif // AMD64 16.38
17.1 --- a/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Tue Mar 24 15:09:52 2009 -0700 17.2 +++ b/src/os_cpu/windows_x86/vm/os_windows_x86.hpp Thu Mar 26 14:31:45 2009 -0700 17.3 @@ -35,9 +35,6 @@ 17.4 static jint (*atomic_add_func) (jint, volatile jint*); 17.5 static intptr_t (*atomic_add_ptr_func) (intptr_t, volatile intptr_t*); 17.6 17.7 - static void (*fence_func) (); 17.8 - 17.9 - 17.10 static jint atomic_xchg_bootstrap (jint, volatile jint*); 17.11 static intptr_t atomic_xchg_ptr_bootstrap (intptr_t, volatile intptr_t*); 17.12 17.13 @@ -53,8 +50,6 @@ 17.14 #ifdef AMD64 17.15 static jint atomic_add_bootstrap (jint, volatile jint*); 17.16 static intptr_t atomic_add_ptr_bootstrap (intptr_t, volatile intptr_t*); 17.17 - 17.18 - static void fence_bootstrap (); 17.19 #endif // AMD64 17.20 17.21 static void setup_fpu();
18.1 --- a/src/share/vm/includeDB_core Tue Mar 24 15:09:52 2009 -0700 18.2 +++ b/src/share/vm/includeDB_core Thu Mar 26 14:31:45 2009 -0700 18.3 @@ -3154,6 +3154,8 @@ 18.4 oopsHierarchy.cpp thread_<os_family>.inline.hpp 18.5 18.6 orderAccess.cpp orderAccess.hpp 18.7 +orderAccess.cpp stubRoutines.hpp 18.8 +orderAccess.cpp thread.hpp 18.9 18.10 orderAccess.hpp allocation.hpp 18.11 orderAccess.hpp os.hpp
19.1 --- a/src/share/vm/runtime/orderAccess.cpp Tue Mar 24 15:09:52 2009 -0700 19.2 +++ b/src/share/vm/runtime/orderAccess.cpp Thu Mar 26 14:31:45 2009 -0700 19.3 @@ -26,3 +26,15 @@ 19.4 # include "incls/_orderAccess.cpp.incl" 19.5 19.6 volatile intptr_t OrderAccess::dummy = 0; 19.7 + 19.8 +void OrderAccess::StubRoutines_fence() { 19.9 + // Use a stub if it exists. It may not exist during bootstrap so do 19.10 + // nothing in that case but assert if no fence code exists after threads have been created 19.11 + void (*func)() = CAST_TO_FN_PTR(void (*)(), StubRoutines::fence_entry()); 19.12 + 19.13 + if (func != NULL) { 19.14 + (*func)(); 19.15 + return; 19.16 + } 19.17 + assert(Threads::number_of_threads() == 0, "for bootstrap only"); 19.18 +}
20.1 --- a/src/share/vm/runtime/orderAccess.hpp Tue Mar 24 15:09:52 2009 -0700 20.2 +++ b/src/share/vm/runtime/orderAccess.hpp Thu Mar 26 14:31:45 2009 -0700 20.3 @@ -300,4 +300,10 @@ 20.4 // In order to force a memory access, implementations may 20.5 // need a volatile externally visible dummy variable. 20.6 static volatile intptr_t dummy; 20.7 + 20.8 + private: 20.9 + // This is a helper that invokes the StubRoutines::fence_entry() 20.10 + // routine if it exists, It should only be used by platforms that 20.11 + // don't another way to do the inline eassembly. 20.12 + static void StubRoutines_fence(); 20.13 };