0
|
1 /*
|
196
|
2 * Copyright 1999-2008 Sun Microsystems, Inc. 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 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 #include "incls/_precompiled.incl"
|
304
|
26 #include "incls/_assembler_solaris_x86.cpp.incl"
|
0
|
27
|
|
28
|
|
29 void MacroAssembler::int3() {
|
304
|
30 push(rax);
|
|
31 push(rdx);
|
|
32 push(rcx);
|
0
|
33 call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint)));
|
304
|
34 pop(rcx);
|
|
35 pop(rdx);
|
|
36 pop(rax);
|
0
|
37 }
|
|
38
|
304
|
39 #define __ _masm->
|
|
40 #ifndef _LP64
|
|
41 static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) {
|
0
|
42
|
|
43 // slow call to of thr_getspecific
|
|
44 // int thr_getspecific(thread_key_t key, void **value);
|
|
45 // Consider using pthread_getspecific instead.
|
|
46
|
304
|
47 __ push(0); // allocate space for return value
|
|
48 if (thread != rax) __ push(rax); // save rax, if caller still wants it
|
|
49 __ push(rcx); // save caller save
|
|
50 __ push(rdx); // save caller save
|
0
|
51 if (thread != rax) {
|
304
|
52 __ lea(thread, Address(rsp, 3 * sizeof(int))); // address of return value
|
0
|
53 } else {
|
304
|
54 __ lea(thread, Address(rsp, 2 * sizeof(int))); // address of return value
|
|
55 }
|
|
56 __ push(thread); // and pass the address
|
|
57 __ push(ThreadLocalStorage::thread_index()); // the key
|
|
58 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific)));
|
|
59 __ increment(rsp, 2 * wordSize);
|
|
60 __ pop(rdx);
|
|
61 __ pop(rcx);
|
|
62 if (thread != rax) __ pop(rax);
|
|
63 __ pop(thread);
|
|
64
|
|
65 }
|
|
66 #else
|
|
67 static void slow_call_thr_specific(MacroAssembler* _masm, Register thread) {
|
|
68 // slow call to of thr_getspecific
|
|
69 // int thr_getspecific(thread_key_t key, void **value);
|
|
70 // Consider using pthread_getspecific instead.
|
|
71
|
|
72 if (thread != rax) {
|
|
73 __ push(rax);
|
0
|
74 }
|
304
|
75 __ push(0); // space for return value
|
|
76 __ push(rdi);
|
|
77 __ push(rsi);
|
|
78 __ lea(rsi, Address(rsp, 16)); // pass return value address
|
|
79 __ push(rdx);
|
|
80 __ push(rcx);
|
|
81 __ push(r8);
|
|
82 __ push(r9);
|
|
83 __ push(r10);
|
|
84 // XXX
|
|
85 __ mov(r10, rsp);
|
|
86 __ andptr(rsp, -16);
|
|
87 __ push(r10);
|
|
88 __ push(r11);
|
|
89
|
|
90 __ movl(rdi, ThreadLocalStorage::thread_index());
|
|
91 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, thr_getspecific)));
|
|
92
|
|
93 __ pop(r11);
|
|
94 __ pop(rsp);
|
|
95 __ pop(r10);
|
|
96 __ pop(r9);
|
|
97 __ pop(r8);
|
|
98 __ pop(rcx);
|
|
99 __ pop(rdx);
|
|
100 __ pop(rsi);
|
|
101 __ pop(rdi);
|
|
102 __ pop(thread); // load return value
|
|
103 if (thread != rax) {
|
|
104 __ pop(rax);
|
|
105 }
|
0
|
106 }
|
304
|
107 #endif //LP64
|
|
108
|
|
109 void MacroAssembler::get_thread(Register thread) {
|
|
110
|
|
111 int segment = NOT_LP64(Assembler::GS_segment) LP64_ONLY(Assembler::FS_segment);
|
|
112 // Try to emit a Solaris-specific fast TSD/TLS accessor.
|
|
113 ThreadLocalStorage::pd_tlsAccessMode tlsMode = ThreadLocalStorage::pd_getTlsAccessMode ();
|
|
114 if (tlsMode == ThreadLocalStorage::pd_tlsAccessIndirect) { // T1
|
|
115 // Use thread as a temporary: mov r, gs:[0]; mov r, [r+tlsOffset]
|
|
116 emit_byte (segment);
|
|
117 // ExternalAddress doesn't work because it can't take NULL
|
|
118 AddressLiteral null(0, relocInfo::none);
|
|
119 movptr (thread, null);
|
|
120 movptr(thread, Address(thread, ThreadLocalStorage::pd_getTlsOffset())) ;
|
|
121 return ;
|
|
122 } else
|
|
123 if (tlsMode == ThreadLocalStorage::pd_tlsAccessDirect) { // T2
|
|
124 // mov r, gs:[tlsOffset]
|
|
125 emit_byte (segment);
|
|
126 AddressLiteral tls_off((address)ThreadLocalStorage::pd_getTlsOffset(), relocInfo::none);
|
|
127 movptr (thread, tls_off);
|
|
128 return ;
|
|
129 }
|
|
130
|
|
131 slow_call_thr_specific(this, thread);
|
|
132
|
|
133 }
|