Merge

Tue, 15 Dec 2015 12:21:38 -0800

author
asaha
date
Tue, 15 Dec 2015 12:21:38 -0800
changeset 8358
6dfa00ef5698
parent 8355
0ec76670e407
parent 8357
a8cdb5c0646c
child 8359
e128ae63439e
child 8360
324d912186ce

Merge

.hgtags file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Tue Dec 15 10:36:22 2015 -0800
     1.2 +++ b/.hgtags	Tue Dec 15 12:21:38 2015 -0800
     1.3 @@ -768,6 +768,7 @@
     1.4  6a0b19c56d797c2975f0cf505190e8f5d69b0b7a jdk8u66-b33
     1.5  3d55b1055c782375e39ebbddba2887379bc3531c jdk8u66-b34
     1.6  95b0e04287fb443a4eee64504e0f18bc324c7abd jdk8u66-b35
     1.7 +dce99debdba26def128cd8b2d3eae93d7d789ee2 jdk8u66-b36
     1.8  9a158a0c243beb610dbaabd63d6218d3ce5825f1 jdk8u71-b00
     1.9  67df26e363fb7e722032fd286673642fc999957c jdk8u71-b01
    1.10  1a799d49de23d84f658ade1d3805a1924e7e1e84 jdk8u71-b02
     2.1 --- a/src/os/solaris/vm/os_solaris.cpp	Tue Dec 15 10:36:22 2015 -0800
     2.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Tue Dec 15 12:21:38 2015 -0800
     2.3 @@ -178,75 +178,6 @@
     2.4  
     2.5  static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
     2.6  
     2.7 -// Thread Local Storage
     2.8 -// This is common to all Solaris platforms so it is defined here,
     2.9 -// in this common file.
    2.10 -// The declarations are in the os_cpu threadLS*.hpp files.
    2.11 -//
    2.12 -// Static member initialization for TLS
    2.13 -Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
    2.14 -
    2.15 -#ifndef PRODUCT
    2.16 -#define _PCT(n,d)       ((100.0*(double)(n))/(double)(d))
    2.17 -
    2.18 -int ThreadLocalStorage::_tcacheHit = 0;
    2.19 -int ThreadLocalStorage::_tcacheMiss = 0;
    2.20 -
    2.21 -void ThreadLocalStorage::print_statistics() {
    2.22 -  int total = _tcacheMiss+_tcacheHit;
    2.23 -  tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
    2.24 -                _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
    2.25 -}
    2.26 -#undef _PCT
    2.27 -#endif // PRODUCT
    2.28 -
    2.29 -Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
    2.30 -                                                        int index) {
    2.31 -  Thread *thread = get_thread_slow();
    2.32 -  if (thread != NULL) {
    2.33 -    address sp = os::current_stack_pointer();
    2.34 -    guarantee(thread->_stack_base == NULL ||
    2.35 -              (sp <= thread->_stack_base &&
    2.36 -                 sp >= thread->_stack_base - thread->_stack_size) ||
    2.37 -               is_error_reported(),
    2.38 -              "sp must be inside of selected thread stack");
    2.39 -
    2.40 -    thread->set_self_raw_id(raw_id);  // mark for quick retrieval
    2.41 -    _get_thread_cache[ index ] = thread;
    2.42 -  }
    2.43 -  return thread;
    2.44 -}
    2.45 -
    2.46 -
    2.47 -static const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0};
    2.48 -#define NO_CACHED_THREAD ((Thread*)all_zero)
    2.49 -
    2.50 -void ThreadLocalStorage::pd_set_thread(Thread* thread) {
    2.51 -
    2.52 -  // Store the new value before updating the cache to prevent a race
    2.53 -  // between get_thread_via_cache_slowly() and this store operation.
    2.54 -  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
    2.55 -
    2.56 -  // Update thread cache with new thread if setting on thread create,
    2.57 -  // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
    2.58 -  uintptr_t raw = pd_raw_thread_id();
    2.59 -  int ix = pd_cache_index(raw);
    2.60 -  _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
    2.61 -}
    2.62 -
    2.63 -void ThreadLocalStorage::pd_init() {
    2.64 -  for (int i = 0; i < _pd_cache_size; i++) {
    2.65 -    _get_thread_cache[i] = NO_CACHED_THREAD;
    2.66 -  }
    2.67 -}
    2.68 -
    2.69 -// Invalidate all the caches (happens to be the same as pd_init).
    2.70 -void ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
    2.71 -
    2.72 -#undef NO_CACHED_THREAD
    2.73 -
    2.74 -// END Thread Local Storage
    2.75 -
    2.76  static inline size_t adjust_stack_size(address base, size_t size) {
    2.77    if ((ssize_t)size < 0) {
    2.78      // 4759953: Compensate for ridiculous stack size.
    2.79 @@ -1473,64 +1404,6 @@
    2.80    return (int)(_initial_pid ? _initial_pid : getpid());
    2.81  }
    2.82  
    2.83 -int os::allocate_thread_local_storage() {
    2.84 -  // %%%       in Win32 this allocates a memory segment pointed to by a
    2.85 -  //           register.  Dan Stein can implement a similar feature in
    2.86 -  //           Solaris.  Alternatively, the VM can do the same thing
    2.87 -  //           explicitly: malloc some storage and keep the pointer in a
    2.88 -  //           register (which is part of the thread's context) (or keep it
    2.89 -  //           in TLS).
    2.90 -  // %%%       In current versions of Solaris, thr_self and TSD can
    2.91 -  //           be accessed via short sequences of displaced indirections.
    2.92 -  //           The value of thr_self is available as %g7(36).
    2.93 -  //           The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
    2.94 -  //           assuming that the current thread already has a value bound to k.
    2.95 -  //           It may be worth experimenting with such access patterns,
    2.96 -  //           and later having the parameters formally exported from a Solaris
    2.97 -  //           interface.  I think, however, that it will be faster to
    2.98 -  //           maintain the invariant that %g2 always contains the
    2.99 -  //           JavaThread in Java code, and have stubs simply
   2.100 -  //           treat %g2 as a caller-save register, preserving it in a %lN.
   2.101 -  thread_key_t tk;
   2.102 -  if (thr_keycreate( &tk, NULL ) )
   2.103 -    fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed "
   2.104 -                  "(%s)", strerror(errno)));
   2.105 -  return int(tk);
   2.106 -}
   2.107 -
   2.108 -void os::free_thread_local_storage(int index) {
   2.109 -  // %%% don't think we need anything here
   2.110 -  // if ( pthread_key_delete((pthread_key_t) tk) )
   2.111 -  //   fatal("os::free_thread_local_storage: pthread_key_delete failed");
   2.112 -}
   2.113 -
   2.114 -#define SMALLINT 32   // libthread allocate for tsd_common is a version specific
   2.115 -                      // small number - point is NO swap space available
   2.116 -void os::thread_local_storage_at_put(int index, void* value) {
   2.117 -  // %%% this is used only in threadLocalStorage.cpp
   2.118 -  if (thr_setspecific((thread_key_t)index, value)) {
   2.119 -    if (errno == ENOMEM) {
   2.120 -       vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR,
   2.121 -                             "thr_setspecific: out of swap space");
   2.122 -    } else {
   2.123 -      fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed "
   2.124 -                    "(%s)", strerror(errno)));
   2.125 -    }
   2.126 -  } else {
   2.127 -      ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ;
   2.128 -  }
   2.129 -}
   2.130 -
   2.131 -// This function could be called before TLS is initialized, for example, when
   2.132 -// VM receives an async signal or when VM causes a fatal error during
   2.133 -// initialization. Return NULL if thr_getspecific() fails.
   2.134 -void* os::thread_local_storage_at(int index) {
   2.135 -  // %%% this is used only in threadLocalStorage.cpp
   2.136 -  void* r = NULL;
   2.137 -  return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
   2.138 -}
   2.139 -
   2.140 -
   2.141  // gethrtime() should be monotonic according to the documentation,
   2.142  // but some virtualized platforms are known to break this guarantee.
   2.143  // getTimeNanos() must be guaranteed not to move backwards, so we
     3.1 --- a/src/os/solaris/vm/thread_solaris.inline.hpp	Tue Dec 15 10:36:22 2015 -0800
     3.2 +++ b/src/os/solaris/vm/thread_solaris.inline.hpp	Tue Dec 15 12:21:38 2015 -0800
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -40,19 +40,12 @@
    3.11  // For SPARC, to avoid excessive register window spill-fill faults,
    3.12  // we aggressively inline these routines.
    3.13  
    3.14 +inline void ThreadLocalStorage::set_thread(Thread* thread) {
    3.15 +  _thr_current = thread;
    3.16 +}
    3.17 +
    3.18  inline Thread* ThreadLocalStorage::thread()  {
    3.19 -  // don't use specialized code if +UseMallocOnly -- may confuse Purify et al.
    3.20 -  debug_only(if (UseMallocOnly) return get_thread_slow(););
    3.21 -
    3.22 -  uintptr_t raw = pd_raw_thread_id();
    3.23 -  int ix = pd_cache_index(raw);
    3.24 -  Thread* candidate = ThreadLocalStorage::_get_thread_cache[ix];
    3.25 -  if (candidate->self_raw_id() == raw) {
    3.26 -    // hit
    3.27 -    return candidate;
    3.28 -  } else {
    3.29 -    return ThreadLocalStorage::get_thread_via_cache_slowly(raw, ix);
    3.30 -  }
    3.31 +  return _thr_current;
    3.32  }
    3.33  
    3.34  #endif // OS_SOLARIS_VM_THREAD_SOLARIS_INLINE_HPP
     4.1 --- a/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp	Tue Dec 15 10:36:22 2015 -0800
     4.2 +++ b/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.cpp	Tue Dec 15 12:21:38 2015 -0800
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -26,19 +26,26 @@
    4.11  #include "runtime/thread.inline.hpp"
    4.12  #include "runtime/threadLocalStorage.hpp"
    4.13  
    4.14 -// Provides an entry point we can link against and
    4.15 -// a buffer we can emit code into. The buffer is
    4.16 -// filled by ThreadLocalStorage::generate_code_for_get_thread
    4.17 -// and called from ThreadLocalStorage::thread()
    4.18 +// True thread-local variable
    4.19 +__thread Thread * ThreadLocalStorage::_thr_current = NULL;
    4.20  
    4.21 -#include <sys/systeminfo.h>
    4.22 +// Implementations needed to support the shared API
    4.23  
    4.24 -// The portable TLS mechanism (get_thread_via_cache) is enough on SPARC.
    4.25 -// There is no need for hand-assembling a special function.
    4.26 -void ThreadLocalStorage::generate_code_for_get_thread() {
    4.27 +void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
    4.28 +
    4.29 +bool ThreadLocalStorage::_initialized = false;
    4.30 +
    4.31 +void ThreadLocalStorage::init() {
    4.32 +  _initialized = true;
    4.33  }
    4.34  
    4.35 -void ThreadLocalStorage::set_thread_in_slot (Thread * self) {}
    4.36 +bool ThreadLocalStorage::is_initialized() {
    4.37 +  return _initialized;
    4.38 +}
    4.39 +
    4.40 +Thread* ThreadLocalStorage::get_thread_slow() {
    4.41 +    return thread();
    4.42 +}
    4.43  
    4.44  extern "C" Thread* get_thread() {
    4.45    return ThreadLocalStorage::thread();
     5.1 --- a/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp	Tue Dec 15 10:36:22 2015 -0800
     5.2 +++ b/src/os_cpu/solaris_sparc/vm/threadLS_solaris_sparc.hpp	Tue Dec 15 12:21:38 2015 -0800
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -25,47 +25,15 @@
    5.11  #ifndef OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
    5.12  #define OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
    5.13  
    5.14 -public:
    5.15 -  // Java Thread  - force inlining
    5.16 -  static inline Thread* thread() ;
    5.17 +// Solaris specific implementation involves simple, direct use
    5.18 +// of a compiler-based thread-local variable
    5.19  
    5.20  private:
    5.21 -  static Thread* _get_thread_cache[];  // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size]
    5.22 -  static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index);
    5.23 +  static __thread Thread * _thr_current;
    5.24  
    5.25 -  NOT_PRODUCT(static int _tcacheHit;)
    5.26 -  NOT_PRODUCT(static int _tcacheMiss;)
    5.27 +  static bool _initialized;  // needed for shared API
    5.28  
    5.29  public:
    5.30 -
    5.31 -  // Print cache hit/miss statistics
    5.32 -  static void print_statistics() PRODUCT_RETURN;
    5.33 -
    5.34 -  enum Constants {
    5.35 -    _pd_cache_size         =  256*2  // projected typical # of threads * 2
    5.36 -  };
    5.37 -
    5.38 -  static void set_thread_in_slot (Thread *) ;
    5.39 -
    5.40 -  static uintptr_t pd_raw_thread_id() {
    5.41 -    return _raw_thread_id();
    5.42 -  }
    5.43 -
    5.44 -  static int pd_cache_index(uintptr_t raw_id) {
    5.45 -    // Hash function: From email from Dave:
    5.46 -    // The hash function deserves an explanation.  %g7 points to libthread's
    5.47 -    // "thread" structure.  On T1 the thread structure is allocated on the
    5.48 -    // user's stack (yes, really!) so the ">>20" handles T1 where the JVM's
    5.49 -    // stack size is usually >= 1Mb.  The ">>9" is for T2 where Roger allocates
    5.50 -    // globs of thread blocks contiguously.  The "9" has to do with the
    5.51 -    // expected size of the T2 thread structure.  If these constants are wrong
    5.52 -    // the worst thing that'll happen is that the hit rate for heavily threaded
    5.53 -    // apps won't be as good as it could be.  If you want to burn another
    5.54 -    // shift+xor you could mix together _all of the %g7 bits to form the hash,
    5.55 -    // but I think that's excessive.  Making the change above changed the
    5.56 -    // T$ miss rate on SpecJBB (on a 16X system) from about 3% to imperceptible.
    5.57 -    uintptr_t ix = (int) (((raw_id >> 9) ^ (raw_id >> 20)) % _pd_cache_size);
    5.58 -    return ix;
    5.59 -  }
    5.60 +  static inline Thread* thread();
    5.61  
    5.62  #endif // OS_CPU_SOLARIS_SPARC_VM_THREADLS_SOLARIS_SPARC_HPP
     6.1 --- a/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp	Tue Dec 15 10:36:22 2015 -0800
     6.2 +++ b/src/os_cpu/solaris_x86/vm/assembler_solaris_x86.cpp	Tue Dec 15 12:21:38 2015 -0800
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -23,11 +23,10 @@
    6.11   */
    6.12  
    6.13  #include "precompiled.hpp"
    6.14 -#include "asm/macroAssembler.hpp"
    6.15  #include "asm/macroAssembler.inline.hpp"
    6.16  #include "runtime/os.hpp"
    6.17  #include "runtime/threadLocalStorage.hpp"
    6.18 -
    6.19 +#include "runtime/thread.inline.hpp"
    6.20  
    6.21  void MacroAssembler::int3() {
    6.22    push(rax);
    6.23 @@ -39,98 +38,32 @@
    6.24    pop(rax);
    6.25  }
    6.26  
    6.27 -#define __  _masm->
    6.28 -#ifndef _LP64
    6.29 -static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) {
    6.30 +// This is simply a call to ThreadLocalStorage::thread()
    6.31 +void MacroAssembler::get_thread(Register thread) {
    6.32 +  if (thread != rax) {
    6.33 +    push(rax);
    6.34 +  }
    6.35 +  push(rdi);
    6.36 +  push(rsi);
    6.37 +  push(rdx);
    6.38 +  push(rcx);
    6.39 +  push(r8);
    6.40 +  push(r9);
    6.41 +  push(r10);
    6.42 +  push(r11);
    6.43  
    6.44 -  // slow call to of thr_getspecific
    6.45 -  // int thr_getspecific(thread_key_t key, void **value);
    6.46 -  // Consider using pthread_getspecific instead.
    6.47 +  call(RuntimeAddress(CAST_FROM_FN_PTR(address, ThreadLocalStorage::thread)));
    6.48  
    6.49 -__  push(0);                                                            // allocate space for return value
    6.50 -  if (thread != rax) __ push(rax);                                      // save rax, if caller still wants it
    6.51 -__  push(rcx);                                                          // save caller save
    6.52 -__  push(rdx);                                                          // save caller save
    6.53 +  pop(r11);
    6.54 +  pop(r10);
    6.55 +  pop(r9);
    6.56 +  pop(r8);
    6.57 +  pop(rcx);
    6.58 +  pop(rdx);
    6.59 +  pop(rsi);
    6.60 +  pop(rdi);
    6.61    if (thread != rax) {
    6.62 -__    lea(thread, Address(rsp, 3 * sizeof(int)));                       // address of return value
    6.63 -  } else {
    6.64 -__    lea(thread, Address(rsp, 2 * sizeof(int)));                       // address of return value
    6.65 -  }
    6.66 -__  push(thread);                                                       // and pass the address
    6.67 -__  push(ThreadLocalStorage::thread_index());                           // the key
    6.68 -__  call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific)));
    6.69 -__  increment(rsp, 2 * wordSize);
    6.70 -__  pop(rdx);
    6.71 -__  pop(rcx);
    6.72 -  if (thread != rax) __ pop(rax);
    6.73 -__  pop(thread);
    6.74 -
    6.75 -}
    6.76 -#else
    6.77 -static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) {
    6.78 -  // slow call to of thr_getspecific
    6.79 -  // int thr_getspecific(thread_key_t key, void **value);
    6.80 -  // Consider using pthread_getspecific instead.
    6.81 -
    6.82 -  if (thread != rax) {
    6.83 -__    push(rax);
    6.84 -  }
    6.85 -__  push(0); // space for return value
    6.86 -__  push(rdi);
    6.87 -__  push(rsi);
    6.88 -__  lea(rsi, Address(rsp, 16)); // pass return value address
    6.89 -__  push(rdx);
    6.90 -__  push(rcx);
    6.91 -__  push(r8);
    6.92 -__  push(r9);
    6.93 -__  push(r10);
    6.94 -  // XXX
    6.95 -__  mov(r10, rsp);
    6.96 -__  andptr(rsp, -16);
    6.97 -__  push(r10);
    6.98 -__  push(r11);
    6.99 -
   6.100 -__  movl(rdi, ThreadLocalStorage::thread_index());
   6.101 -__  call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific)));
   6.102 -
   6.103 -__  pop(r11);
   6.104 -__  pop(rsp);
   6.105 -__  pop(r10);
   6.106 -__  pop(r9);
   6.107 -__  pop(r8);
   6.108 -__  pop(rcx);
   6.109 -__  pop(rdx);
   6.110 -__  pop(rsi);
   6.111 -__  pop(rdi);
   6.112 -__  pop(thread); // load return value
   6.113 -  if (thread != rax) {
   6.114 -__    pop(rax);
   6.115 +    movl(thread, rax);
   6.116 +    pop(rax);
   6.117    }
   6.118  }
   6.119 -#endif //LP64
   6.120 -
   6.121 -void MacroAssembler::get_thread(Register thread) {
   6.122 -
   6.123 -  int segment = NOT_LP64(Assembler::GS_segment) LP64_ONLY(Assembler::FS_segment);
   6.124 -  // Try to emit a Solaris-specific fast TSD/TLS accessor.
   6.125 -  ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode ();
   6.126 -  if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) {            // T1
   6.127 -     // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset]
   6.128 -     emit_int8 (segment);
   6.129 -     // ExternalAddress doesn't work because it can't take NULL
   6.130 -     AddressLiteral null(0, relocInfo::none);
   6.131 -     movptr (thread, null);
   6.132 -     movptr(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ;
   6.133 -     return ;
   6.134 -  } else
   6.135 -  if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) {              // T2
   6.136 -     // mov r, gs:[tlsOffset]
   6.137 -     emit_int8 (segment);
   6.138 -     AddressLiteral tls_off((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none);
   6.139 -     movptr (thread, tls_off);
   6.140 -     return ;
   6.141 -  }
   6.142 -
   6.143 -  slow_call_thr_specific(this, thread);
   6.144 -
   6.145 -}
     7.1 --- a/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp	Tue Dec 15 10:36:22 2015 -0800
     7.2 +++ b/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp	Tue Dec 15 12:21:38 2015 -0800
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -26,167 +26,27 @@
    7.11  #include "runtime/thread.inline.hpp"
    7.12  #include "runtime/threadLocalStorage.hpp"
    7.13  
    7.14 -#ifdef AMD64
    7.15 -extern "C" Thread*  fs_load(ptrdiff_t tlsOffset);
    7.16 -extern "C" intptr_t fs_thread();
    7.17 -#else
    7.18 -// From solaris_i486.s
    7.19 -extern "C" Thread*  gs_load(ptrdiff_t tlsOffset);
    7.20 -extern "C" intptr_t gs_thread();
    7.21 -#endif // AMD64
    7.22 +// True thread-local variable
    7.23 +__thread Thread * ThreadLocalStorage::_thr_current = NULL;
    7.24  
    7.25 -// tlsMode encoding:
    7.26 -//
    7.27 -// pd_tlsAccessUndefined : uninitialized
    7.28 -// pd_tlsAccessSlow      : not available
    7.29 -// pd_tlsAccessIndirect  :
    7.30 -//   old-style indirect access - present in "T1" libthread.
    7.31 -//   use thr_slot_sync_allocate() to attempt to allocate a slot.
    7.32 -// pd_tlsAccessDirect    :
    7.33 -//   new-style direct access - present in late-model "T2" libthread.
    7.34 -//   Allocate the offset (slot) via _thr_slot_offset() or by
    7.35 -//   defining an IE- or LE-mode TLS/TSD slot in the launcher and then passing
    7.36 -//   that offset into libjvm.so.
    7.37 -//   See http://sac.eng/Archives/CaseLog/arc/PSARC/2003/159/.
    7.38 -//
    7.39 -// Note that we have a capability gap - some early model T2 forms
    7.40 -// (e.g., unpatched S9) have neither _thr_slot_sync_allocate() nor
    7.41 -// _thr_slot_offset().  In that case we revert to the usual
    7.42 -// thr_getspecific accessor.
    7.43 -//
    7.44 +// Implementations needed to support the shared API
    7.45  
    7.46 -static ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_tlsAccessUndefined ;
    7.47 -static ptrdiff_t tlsOffset = 0 ;
    7.48 -static thread_key_t tlsKey ;
    7.49 +void ThreadLocalStorage::pd_invalidate_all() {} // nothing to do
    7.50  
    7.51 -typedef int (*TSSA_Entry) (ptrdiff_t *, int, int) ;
    7.52 -typedef ptrdiff_t (*TSO_Entry) (int) ;
    7.53 +bool ThreadLocalStorage::_initialized = false;
    7.54  
    7.55 -ThreadLocalStorage::pd_tlsAccessMode ThreadLocalStorage::pd_getTlsAccessMode ()
    7.56 -{
    7.57 -   guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ;
    7.58 -   return tlsMode ;
    7.59 +void ThreadLocalStorage::init() {
    7.60 +  _initialized = true;
    7.61  }
    7.62  
    7.63 -ptrdiff_t ThreadLocalStorage::pd_getTlsOffset () {
    7.64 -   guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ;
    7.65 -   return tlsOffset ;
    7.66 +bool ThreadLocalStorage::is_initialized() {
    7.67 +  return _initialized;
    7.68  }
    7.69  
    7.70 -// TODO: Consider the following improvements:
    7.71 -//
    7.72 -// 1.   Convert from thr_*specific* to pthread_*specific*.
    7.73 -//      The pthread_ forms are slightly faster.  Also, the
    7.74 -//      pthread_ forms have a pthread_key_delete() API which
    7.75 -//      would aid in clean JVM shutdown and the eventual goal
    7.76 -//      of permitting a JVM to reinstantiate itself withing a process.
    7.77 -//
    7.78 -// 2.   See ThreadLocalStorage::init().  We end up allocating
    7.79 -//      two TLS keys during VM startup.  That's benign, but we could collapse
    7.80 -//      down to one key without too much trouble.
    7.81 -//
    7.82 -// 3.   MacroAssembler::get_thread() currently emits calls to thr_getspecific().
    7.83 -//      Modify get_thread() to call Thread::current() instead.
    7.84 -//
    7.85 -// 4.   Thread::current() currently uses a cache keyed by %gs:[0].
    7.86 -//      (The JVM has PSARC permission to use %g7/%gs:[0]
    7.87 -//      as an opaque temporally unique thread identifier).
    7.88 -//      For C++ access to a thread's reflexive "self" pointer we
    7.89 -//      should consider using one of the following:
    7.90 -//      a. a radix tree keyed by %esp - as in EVM.
    7.91 -//         This requires two loads (the 2nd dependent on the 1st), but
    7.92 -//         is easily inlined and doesn't require a "miss" slow path.
    7.93 -//      b. a fast TLS/TSD slot allocated by _thr_slot_offset
    7.94 -//         or _thr_slot_sync_allocate.
    7.95 -//
    7.96 -// 5.   'generate_code_for_get_thread' is a misnomer.
    7.97 -//      We should change it to something more general like
    7.98 -//      pd_ThreadSelf_Init(), for instance.
    7.99 -//
   7.100 -
   7.101 -static void AllocateTLSOffset ()
   7.102 -{
   7.103 -   int rslt ;
   7.104 -   TSSA_Entry tssa ;
   7.105 -   TSO_Entry  tso ;
   7.106 -   ptrdiff_t off ;
   7.107 -
   7.108 -   guarantee (tlsMode == ThreadLocalStorage::pd_tlsAccessUndefined, "tlsMode not set") ;
   7.109 -   tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ;
   7.110 -   tlsOffset = 0 ;
   7.111 -#ifndef AMD64
   7.112 -
   7.113 -   tssa = (TSSA_Entry) dlsym (RTLD_DEFAULT, "thr_slot_sync_allocate") ;
   7.114 -   if (tssa != NULL) {
   7.115 -        off = -1 ;
   7.116 -        rslt = (*tssa)(&off, NULL, NULL) ;                // (off,dtor,darg)
   7.117 -        if (off != -1) {
   7.118 -           tlsOffset = off ;
   7.119 -           tlsMode = ThreadLocalStorage::pd_tlsAccessIndirect ;
   7.120 -           return ;
   7.121 -        }
   7.122 -    }
   7.123 -
   7.124 -    rslt = thr_keycreate (&tlsKey, NULL) ;
   7.125 -    if (rslt != 0) {
   7.126 -        tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ;   // revert to slow mode
   7.127 -        return ;
   7.128 -    }
   7.129 -
   7.130 -    tso = (TSO_Entry) dlsym (RTLD_DEFAULT, "_thr_slot_offset") ;
   7.131 -    if (tso != NULL) {
   7.132 -        off = (*tso)(tlsKey) ;
   7.133 -        if (off >= 0) {
   7.134 -           tlsOffset = off ;
   7.135 -           tlsMode = ThreadLocalStorage::pd_tlsAccessDirect ;
   7.136 -           return ;
   7.137 -        }
   7.138 -    }
   7.139 -
   7.140 -    // Failure: Too bad ... we've allocated a TLS slot we don't need and there's
   7.141 -    // no provision in the ABI for returning the slot.
   7.142 -    //
   7.143 -    // If we didn't find a slot then then:
   7.144 -    // 1. We might be on liblwp.
   7.145 -    // 2. We might be on T2 libthread, but all "fast" slots are already
   7.146 -    //    consumed
   7.147 -    // 3. We might be on T1, and all TSD (thr_slot_sync_allocate) slots are
   7.148 -    //    consumed.
   7.149 -    // 4. We might be on T2 libthread, but it's be re-architected
   7.150 -    //    so that fast slots are no longer g7-relative.
   7.151 -    //
   7.152 -
   7.153 -    tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ;
   7.154 -    return ;
   7.155 -#endif // AMD64
   7.156 +Thread* ThreadLocalStorage::get_thread_slow() {
   7.157 +    return thread();
   7.158  }
   7.159  
   7.160 -void ThreadLocalStorage::generate_code_for_get_thread() {
   7.161 -    AllocateTLSOffset() ;
   7.162 -}
   7.163 -
   7.164 -void ThreadLocalStorage::set_thread_in_slot(Thread *thread) {
   7.165 -  guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ;
   7.166 -  if (tlsMode == pd_tlsAccessIndirect) {
   7.167 -#ifdef AMD64
   7.168 -        intptr_t tbase = fs_thread();
   7.169 -#else
   7.170 -        intptr_t tbase = gs_thread();
   7.171 -#endif // AMD64
   7.172 -        *((Thread**) (tbase + tlsOffset)) = thread ;
   7.173 -  } else
   7.174 -  if (tlsMode == pd_tlsAccessDirect) {
   7.175 -        thr_setspecific (tlsKey, (void *) thread) ;
   7.176 -        // set with thr_setspecific and then readback with gs_load to validate.
   7.177 -#ifdef AMD64
   7.178 -        guarantee (thread == fs_load(tlsOffset), "tls readback failure") ;
   7.179 -#else
   7.180 -        guarantee (thread == gs_load(tlsOffset), "tls readback failure") ;
   7.181 -#endif // AMD64
   7.182 -  }
   7.183 -}
   7.184 -
   7.185 -
   7.186  extern "C" Thread* get_thread() {
   7.187    return ThreadLocalStorage::thread();
   7.188  }
     8.1 --- a/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp	Tue Dec 15 10:36:22 2015 -0800
     8.2 +++ b/src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.hpp	Tue Dec 15 12:21:38 2015 -0800
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -25,61 +25,15 @@
    8.11  #ifndef OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
    8.12  #define OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
    8.13  
    8.14 -// Processor dependent parts of ThreadLocalStorage
    8.15 +// Solaris specific implementation involves simple, direct use
    8.16 +// of a compiler-based thread-local variable
    8.17  
    8.18  private:
    8.19 -  static Thread* _get_thread_cache[];  // index by [(raw_id>>9)^(raw_id>>20) % _pd_cache_size]
    8.20 -  static Thread* get_thread_via_cache_slowly(uintptr_t raw_id, int index);
    8.21 +  static __thread Thread * _thr_current;
    8.22  
    8.23 -  NOT_PRODUCT(static int _tcacheHit;)
    8.24 -  NOT_PRODUCT(static int _tcacheMiss;)
    8.25 +  static bool _initialized;  // needed for shared API
    8.26  
    8.27  public:
    8.28 -  // Cache hit/miss statistics
    8.29 -  static void print_statistics() PRODUCT_RETURN;
    8.30 -
    8.31 -  enum Constants {
    8.32 -#ifdef AMD64
    8.33 -    _pd_cache_size         =  256*2   // projected typical # of threads * 2
    8.34 -#else
    8.35 -    _pd_cache_size         =  128*2   // projected typical # of threads * 2
    8.36 -#endif // AMD64
    8.37 -  };
    8.38 -
    8.39 -  enum pd_tlsAccessMode {
    8.40 -     pd_tlsAccessUndefined      = -1,
    8.41 -     pd_tlsAccessSlow           = 0,
    8.42 -     pd_tlsAccessIndirect       = 1,
    8.43 -     pd_tlsAccessDirect         = 2
    8.44 -  } ;
    8.45 -
    8.46 -  static void set_thread_in_slot (Thread *) ;
    8.47 -
    8.48 -  static pd_tlsAccessMode pd_getTlsAccessMode () ;
    8.49 -  static ptrdiff_t pd_getTlsOffset () ;
    8.50 -
    8.51 -  static uintptr_t pd_raw_thread_id() {
    8.52 -#ifdef _GNU_SOURCE
    8.53 -#ifdef AMD64
    8.54 -    uintptr_t rv;
    8.55 -    __asm__ __volatile__ ("movq %%fs:0, %0" : "=r"(rv));
    8.56 -    return rv;
    8.57 -#else
    8.58 -    return gs_thread();
    8.59 -#endif // AMD64
    8.60 -#else  //_GNU_SOURCE
    8.61 -    return _raw_thread_id();
    8.62 -#endif //_GNU_SOURCE
    8.63 -  }
    8.64 -
    8.65 -  static int pd_cache_index(uintptr_t raw_id) {
    8.66 -    // Copied from the sparc version. Dave said it should also work fine
    8.67 -    // for solx86.
    8.68 -    int ix = (int) (((raw_id >> 9) ^ (raw_id >> 20)) % _pd_cache_size);
    8.69 -    return ix;
    8.70 -  }
    8.71 -
    8.72 -  // Java Thread
    8.73    static inline Thread* thread();
    8.74  
    8.75  #endif // OS_CPU_SOLARIS_X86_VM_THREADLS_SOLARIS_X86_HPP
     9.1 --- a/src/share/vm/runtime/threadLocalStorage.cpp	Tue Dec 15 10:36:22 2015 -0800
     9.2 +++ b/src/share/vm/runtime/threadLocalStorage.cpp	Tue Dec 15 12:21:38 2015 -0800
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -38,6 +38,11 @@
    9.11  # include "os_bsd.inline.hpp"
    9.12  #endif
    9.13  
    9.14 +// Solaris no longer has this kind of ThreadLocalStorage implementation.
    9.15 +// This will be removed from all platforms in the near future.
    9.16 +
    9.17 +#ifndef SOLARIS
    9.18 +
    9.19  // static member initialization
    9.20  int ThreadLocalStorage::_thread_index = -1;
    9.21  
    9.22 @@ -65,3 +70,5 @@
    9.23  bool ThreadLocalStorage::is_initialized() {
    9.24      return (thread_index() != -1);
    9.25  }
    9.26 +
    9.27 +#endif // SOLARIS
    10.1 --- a/src/share/vm/runtime/threadLocalStorage.hpp	Tue Dec 15 10:36:22 2015 -0800
    10.2 +++ b/src/share/vm/runtime/threadLocalStorage.hpp	Tue Dec 15 12:21:38 2015 -0800
    10.3 @@ -38,10 +38,14 @@
    10.4  extern "C" uintptr_t _raw_thread_id();
    10.5  
    10.6  class ThreadLocalStorage : AllStatic {
    10.7 +
    10.8 + // Exported API
    10.9   public:
   10.10    static void    set_thread(Thread* thread);
   10.11    static Thread* get_thread_slow();
   10.12    static void    invalidate_all() { pd_invalidate_all(); }
   10.13 +  static void    init();
   10.14 +  static bool    is_initialized();
   10.15  
   10.16    // Machine dependent stuff
   10.17  #ifdef TARGET_OS_ARCH_linux_x86
   10.18 @@ -78,17 +82,12 @@
   10.19  # include "threadLS_bsd_zero.hpp"
   10.20  #endif
   10.21  
   10.22 -
   10.23 +#ifndef SOLARIS
   10.24   public:
   10.25    // Accessor
   10.26    static inline int  thread_index()              { return _thread_index; }
   10.27    static inline void set_thread_index(int index) { _thread_index = index; }
   10.28  
   10.29 -  // Initialization
   10.30 -  // Called explicitly from VMThread::activate_system instead of init_globals.
   10.31 -  static void init();
   10.32 -  static bool is_initialized();
   10.33 -
   10.34   private:
   10.35    static int     _thread_index;
   10.36  
   10.37 @@ -97,6 +96,9 @@
   10.38    // Processor dependent parts of set_thread and initialization
   10.39    static void pd_set_thread(Thread* thread);
   10.40    static void pd_init();
   10.41 +
   10.42 +#endif // SOLARIS
   10.43 +
   10.44    // Invalidate any thread cacheing or optimization schemes.
   10.45    static void pd_invalidate_all();
   10.46  

mercurial