Mercurial > hg > graal-jvmci-8
annotate src/os_cpu/solaris_x86/vm/threadLS_solaris_x86.cpp @ 1681:126ea7725993
6953477: Increase portability and flexibility of building Hotspot
Summary: A collection of portability improvements including shared code support for PPC, ARM platforms, software floating point, cross compilation support and improvements in error crash detail.
Reviewed-by: phh, never, coleenp, dholmes
author | bobv |
---|---|
date | Tue, 03 Aug 2010 08:13:38 -0400 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_threadLS_solaris_x86.cpp.incl" | |
27 | |
28 #ifdef AMD64 | |
29 extern "C" Thread* fs_load(ptrdiff_t tlsOffset); | |
30 extern "C" intptr_t fs_thread(); | |
31 #else | |
32 // From solaris_i486.s | |
33 extern "C" Thread* gs_load(ptrdiff_t tlsOffset); | |
34 extern "C" intptr_t gs_thread(); | |
35 #endif // AMD64 | |
36 | |
37 // tlsMode encoding: | |
38 // | |
39 // pd_tlsAccessUndefined : uninitialized | |
40 // pd_tlsAccessSlow : not available | |
41 // pd_tlsAccessIndirect : | |
42 // old-style indirect access - present in "T1" libthread. | |
43 // use thr_slot_sync_allocate() to attempt to allocate a slot. | |
44 // pd_tlsAccessDirect : | |
45 // new-style direct access - present in late-model "T2" libthread. | |
46 // Allocate the offset (slot) via _thr_slot_offset() or by | |
47 // defining an IE- or LE-mode TLS/TSD slot in the launcher and then passing | |
48 // that offset into libjvm.so. | |
49 // See http://sac.eng/Archives/CaseLog/arc/PSARC/2003/159/. | |
50 // | |
51 // Note that we have a capability gap - some early model T2 forms | |
52 // (e.g., unpatched S9) have neither _thr_slot_sync_allocate() nor | |
53 // _thr_slot_offset(). In that case we revert to the usual | |
54 // thr_getspecific accessor. | |
55 // | |
56 | |
57 static ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_tlsAccessUndefined ; | |
58 static ptrdiff_t tlsOffset = 0 ; | |
59 static thread_key_t tlsKey ; | |
60 | |
61 typedef int (*TSSA_Entry) (ptrdiff_t *, int, int) ; | |
62 typedef ptrdiff_t (*TSO_Entry) (int) ; | |
63 | |
64 ThreadLocalStorage::pd_tlsAccessMode ThreadLocalStorage::pd_getTlsAccessMode () | |
65 { | |
66 guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ; | |
67 return tlsMode ; | |
68 } | |
69 | |
70 ptrdiff_t ThreadLocalStorage::pd_getTlsOffset () { | |
71 guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ; | |
72 return tlsOffset ; | |
73 } | |
74 | |
75 // TODO: Consider the following improvements: | |
76 // | |
77 // 1. Convert from thr_*specific* to pthread_*specific*. | |
78 // The pthread_ forms are slightly faster. Also, the | |
79 // pthread_ forms have a pthread_key_delete() API which | |
80 // would aid in clean JVM shutdown and the eventual goal | |
81 // of permitting a JVM to reinstantiate itself withing a process. | |
82 // | |
83 // 2. See ThreadLocalStorage::init(). We end up allocating | |
84 // two TLS keys during VM startup. That's benign, but we could collapse | |
85 // down to one key without too much trouble. | |
86 // | |
87 // 3. MacroAssembler::get_thread() currently emits calls to thr_getspecific(). | |
88 // Modify get_thread() to call Thread::current() instead. | |
89 // | |
90 // 4. Thread::current() currently uses a cache keyed by %gs:[0]. | |
91 // (The JVM has PSARC permission to use %g7/%gs:[0] | |
92 // as an opaque temporally unique thread identifier). | |
93 // For C++ access to a thread's reflexive "self" pointer we | |
94 // should consider using one of the following: | |
95 // a. a radix tree keyed by %esp - as in EVM. | |
96 // This requires two loads (the 2nd dependent on the 1st), but | |
97 // is easily inlined and doesn't require a "miss" slow path. | |
98 // b. a fast TLS/TSD slot allocated by _thr_slot_offset | |
99 // or _thr_slot_sync_allocate. | |
100 // | |
101 // 5. 'generate_code_for_get_thread' is a misnomer. | |
102 // We should change it to something more general like | |
103 // pd_ThreadSelf_Init(), for instance. | |
104 // | |
105 | |
106 static void AllocateTLSOffset () | |
107 { | |
108 int rslt ; | |
109 TSSA_Entry tssa ; | |
110 TSO_Entry tso ; | |
111 ptrdiff_t off ; | |
112 | |
113 guarantee (tlsMode == ThreadLocalStorage::pd_tlsAccessUndefined, "tlsMode not set") ; | |
114 tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ; | |
115 tlsOffset = 0 ; | |
116 #ifndef AMD64 | |
117 | |
118 tssa = (TSSA_Entry) dlsym (RTLD_DEFAULT, "thr_slot_sync_allocate") ; | |
119 if (tssa != NULL) { | |
120 off = -1 ; | |
121 rslt = (*tssa)(&off, NULL, NULL) ; // (off,dtor,darg) | |
122 if (off != -1) { | |
123 tlsOffset = off ; | |
124 tlsMode = ThreadLocalStorage::pd_tlsAccessIndirect ; | |
125 return ; | |
126 } | |
127 } | |
128 | |
129 rslt = thr_keycreate (&tlsKey, NULL) ; | |
130 if (rslt != 0) { | |
131 tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ; // revert to slow mode | |
132 return ; | |
133 } | |
134 | |
135 tso = (TSO_Entry) dlsym (RTLD_DEFAULT, "_thr_slot_offset") ; | |
136 if (tso != NULL) { | |
137 off = (*tso)(tlsKey) ; | |
138 if (off >= 0) { | |
139 tlsOffset = off ; | |
140 tlsMode = ThreadLocalStorage::pd_tlsAccessDirect ; | |
141 return ; | |
142 } | |
143 } | |
144 | |
145 // Failure: Too bad ... we've allocated a TLS slot we don't need and there's | |
146 // no provision in the ABI for returning the slot. | |
147 // | |
148 // If we didn't find a slot then then: | |
149 // 1. We might be on liblwp. | |
150 // 2. We might be on T2 libthread, but all "fast" slots are already | |
151 // consumed | |
152 // 3. We might be on T1, and all TSD (thr_slot_sync_allocate) slots are | |
153 // consumed. | |
154 // 4. We might be on T2 libthread, but it's be re-architected | |
155 // so that fast slots are no longer g7-relative. | |
156 // | |
157 | |
158 tlsMode = ThreadLocalStorage::pd_tlsAccessSlow ; | |
159 return ; | |
160 #endif // AMD64 | |
161 } | |
162 | |
163 void ThreadLocalStorage::generate_code_for_get_thread() { | |
164 AllocateTLSOffset() ; | |
165 } | |
166 | |
167 void ThreadLocalStorage::set_thread_in_slot(Thread *thread) { | |
168 guarantee (tlsMode != pd_tlsAccessUndefined, "tlsMode not set") ; | |
169 if (tlsMode == pd_tlsAccessIndirect) { | |
170 #ifdef AMD64 | |
171 intptr_t tbase = fs_thread(); | |
172 #else | |
173 intptr_t tbase = gs_thread(); | |
174 #endif // AMD64 | |
175 *((Thread**) (tbase + tlsOffset)) = thread ; | |
176 } else | |
177 if (tlsMode == pd_tlsAccessDirect) { | |
178 thr_setspecific (tlsKey, (void *) thread) ; | |
179 // set with thr_setspecific and then readback with gs_load to validate. | |
180 #ifdef AMD64 | |
181 guarantee (thread == fs_load(tlsOffset), "tls readback failure") ; | |
182 #else | |
183 guarantee (thread == gs_load(tlsOffset), "tls readback failure") ; | |
184 #endif // AMD64 | |
185 } | |
186 } | |
187 | |
188 | |
189 extern "C" Thread* get_thread() { | |
190 return ThreadLocalStorage::thread(); | |
191 } |