Tue, 15 Dec 2015 12:21:38 -0800
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