6822204: volatile fences should prefer lock:addl to actual mfence instructions

Thu, 26 Mar 2009 14:31:45 -0700

author
never
date
Thu, 26 Mar 2009 14:31:45 -0700
changeset 1106
d0994e5bebce
parent 1103
90a66aa50514
child 1107
afd8dfb5c2a6

6822204: volatile fences should prefer lock:addl to actual mfence instructions
Reviewed-by: kvn, phh

src/cpu/sparc/vm/stubGenerator_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/assembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/assembler_x86.hpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/stubGenerator_x86_64.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/x86_32.ad file | annotate | diff | comparison | revisions
src/cpu/x86/vm/x86_64.ad file | annotate | diff | comparison | revisions
src/os_cpu/linux_sparc/vm/os_linux_sparc.hpp file | annotate | diff | comparison | revisions
src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_sparc/vm/os_solaris_sparc.hpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp file | annotate | diff | comparison | revisions
src/os_cpu/solaris_x86/vm/os_solaris_x86.hpp file | annotate | diff | comparison | revisions
src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp file | annotate | diff | comparison | revisions
src/os_cpu/windows_x86/vm/os_windows_x86.cpp file | annotate | diff | comparison | revisions
src/os_cpu/windows_x86/vm/os_windows_x86.hpp file | annotate | diff | comparison | revisions
src/share/vm/includeDB_core file | annotate | diff | comparison | revisions
src/share/vm/runtime/orderAccess.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/orderAccess.hpp file | annotate | diff | comparison | revisions
     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  };

mercurial