annotate src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @ 14304:a2866d45e99e

8027454: Do not traverse string table during G1 remark when treating them as strong roots during initial mark Summary: Do not try to unlink string table entries unconditionally during remark. This is without side effects as the preceding initial mark always uses the string table as strong roots. Needs to be fixed with class unloading during concurrent mark. Reviewed-by: brutisso, mgerdin
author tschatzl
date Mon, 20 Jan 2014 11:47:29 +0100
parents af21010d1062
children 2c2a99f6cf83
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1250
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1250
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: 1250
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
25 // no precompiled headers
7199
cd3d6a6b95d9 8003240: x86: move MacroAssembler into separate file
twisti
parents: 6842
diff changeset
26 #include "asm/macroAssembler.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
27 #include "classfile/classLoader.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
28 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
29 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
30 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
31 #include "code/vtableStubs.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
32 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
33 #include "jvm_solaris.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
34 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
35 #include "mutex_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
36 #include "os_share_solaris.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
37 #include "prims/jniFastGetField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
38 #include "prims/jvm.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
39 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
40 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
41 #include "runtime/extendedPC.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
42 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
43 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
44 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
45 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
46 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
47 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
48 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
49 #include "runtime/stubRoutines.hpp"
7180
f34d701e952e 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 6842
diff changeset
50 #include "runtime/thread.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
51 #include "runtime/timer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
52 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
53 #include "utilities/vmError.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
56 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
57 # include <sys/mman.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
58 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
59 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
60 # include <setjmp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
61 # include <errno.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
62 # include <dlfcn.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
63 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
64 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
65 # include <sys/resource.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
66 # include <thread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
67 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
68 # include <sys/time.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
69 # include <sys/filio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
70 # include <sys/utsname.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
71 # include <sys/systeminfo.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
72 # include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
73 # include <sys/trap.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
74 # include <sys/lwp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
75 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
76 # include <poll.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
77 # include <sys/lwp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
78 # include <procfs.h> // see comment in <sys/procfs.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // QQQ seems useless at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
82 # define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later
a61af66fc99e Initial load
duke
parents:
diff changeset
83 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
84 # include <sys/procfs.h> // see comment in <sys/procfs.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 #define MAX_PATH (2 * K)
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // Minimum stack size for the VM. It's easier to document a constant value
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // but it's different for x86 and sparc because the page sizes are different.
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
92 size_t os::Solaris::min_stack_allowed = 224*K;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #define REG_SP REG_RSP
a61af66fc99e Initial load
duke
parents:
diff changeset
94 #define REG_PC REG_RIP
a61af66fc99e Initial load
duke
parents:
diff changeset
95 #define REG_FP REG_RBP
a61af66fc99e Initial load
duke
parents:
diff changeset
96 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
97 size_t os::Solaris::min_stack_allowed = 64*K;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 #define REG_SP UESP
a61af66fc99e Initial load
duke
parents:
diff changeset
99 #define REG_PC EIP
a61af66fc99e Initial load
duke
parents:
diff changeset
100 #define REG_FP EBP
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // 4900493 counter to prevent runaway LDTR refresh attempt
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static volatile int ldtr_refresh = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // the libthread instruction that faults because of the stale LDTR
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 static const unsigned char movlfs[] = { 0x8e, 0xe0 // movl %eax,%fs
a61af66fc99e Initial load
duke
parents:
diff changeset
107 };
a61af66fc99e Initial load
duke
parents:
diff changeset
108 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 char* os::non_memory_address_word() {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // Must never look like an address returned by reserve_memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // even in its subfields (as defined by the CPU immediate fields,
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // if the CPU splits constants across multiple instructions).
a61af66fc99e Initial load
duke
parents:
diff changeset
114 return (char*) -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
116
a61af66fc99e Initial load
duke
parents:
diff changeset
117 //
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Validate a ucontext retrieved from walking a uc_link of a ucontext.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // There are issues with libthread giving out uc_links for different threads
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // on the same uc_link chain and bad or circular links.
a61af66fc99e Initial load
duke
parents:
diff changeset
121 //
a61af66fc99e Initial load
duke
parents:
diff changeset
122 bool os::Solaris::valid_ucontext(Thread* thread, ucontext_t* valid, ucontext_t* suspect) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (valid >= suspect ||
a61af66fc99e Initial load
duke
parents:
diff changeset
124 valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags ||
a61af66fc99e Initial load
duke
parents:
diff changeset
125 valid->uc_stack.ss_sp != suspect->uc_stack.ss_sp ||
a61af66fc99e Initial load
duke
parents:
diff changeset
126 valid->uc_stack.ss_size != suspect->uc_stack.ss_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
127 DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");)
a61af66fc99e Initial load
duke
parents:
diff changeset
128 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 if (!valid_stack_address(thread, (address)suspect)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");)
a61af66fc99e Initial load
duke
parents:
diff changeset
134 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136 if (!valid_stack_address(thread, (address) suspect->uc_mcontext.gregs[REG_SP])) {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");)
a61af66fc99e Initial load
duke
parents:
diff changeset
138 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // We will only follow one level of uc_link since there are libthread
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // issues with ucontext linking and it is better to be safe and just
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // let caller retry later.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
148 ucontext_t *uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 ucontext_t *retuc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if (uc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (uc->uc_link == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // cannot validate without uc_link so accept current ucontext
a61af66fc99e Initial load
duke
parents:
diff changeset
155 retuc = uc;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // first ucontext is valid so try the next one
a61af66fc99e Initial load
duke
parents:
diff changeset
158 uc = uc->uc_link;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 if (uc->uc_link == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // cannot validate without uc_link so accept current ucontext
a61af66fc99e Initial load
duke
parents:
diff changeset
161 retuc = uc;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // the ucontext one level down is also valid so return it
a61af66fc99e Initial load
duke
parents:
diff changeset
164 retuc = uc;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 return retuc;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Assumes ucontext is valid
a61af66fc99e Initial load
duke
parents:
diff changeset
172 ExtendedPC os::Solaris::ucontext_get_ExtendedPC(ucontext_t *uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return ExtendedPC((address)uc->uc_mcontext.gregs[REG_PC]);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // Assumes ucontext is valid
a61af66fc99e Initial load
duke
parents:
diff changeset
177 intptr_t* os::Solaris::ucontext_get_sp(ucontext_t *uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Assumes ucontext is valid
a61af66fc99e Initial load
duke
parents:
diff changeset
182 intptr_t* os::Solaris::ucontext_get_fp(ucontext_t *uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
186 address os::Solaris::ucontext_get_pc(ucontext_t *uc) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
187 return (address) uc->uc_mcontext.gregs[REG_PC];
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
188 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
189
0
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // is currently interrupted by SIGPROF.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 //
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // The difference between this and os::fetch_frame_from_context() is that
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // here we try to skip nested signal frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
195 ExtendedPC os::Solaris::fetch_frame_from_ucontext(Thread* thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
196 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 assert(thread != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
199 assert(ret_sp != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
200 assert(ret_fp != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 ucontext_t *luc = os::Solaris::get_valid_uc_in_signal_handler(thread, uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 return os::fetch_frame_from_context(luc, ret_sp, ret_fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
a61af66fc99e Initial load
duke
parents:
diff changeset
207 intptr_t** ret_sp, intptr_t** ret_fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 ExtendedPC epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 ucontext_t *uc = (ucontext_t*)ucVoid;
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 if (uc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 epc = os::Solaris::ucontext_get_ExtendedPC(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // construct empty ExtendedPC for return value checking
a61af66fc99e Initial load
duke
parents:
diff changeset
218 epc = ExtendedPC(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (ret_sp) *ret_sp = (intptr_t *)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 if (ret_fp) *ret_fp = (intptr_t *)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 frame os::fetch_frame_from_context(void* ucVoid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 intptr_t* sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 intptr_t* fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 return frame(sp, fp, epc.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 frame os::get_sender_for_C_frame(frame* fr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
5903
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
237 extern "C" intptr_t *_get_current_sp(); // in .il file
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
238
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
239 address os::current_stack_pointer() {
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
240 return (address)_get_current_sp();
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
241 }
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
242
472
7b920868b475 6773838: There is no calling stack for Compiler thread in hs_err file on x86
coleenp
parents: 196
diff changeset
243 extern "C" intptr_t *_get_current_fp(); // in .il file
0
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 frame os::current_frame() {
472
7b920868b475 6773838: There is no calling stack for Compiler thread in hs_err file on x86
coleenp
parents: 196
diff changeset
246 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
0
a61af66fc99e Initial load
duke
parents:
diff changeset
247 frame myframe((intptr_t*)os::current_stack_pointer(),
a61af66fc99e Initial load
duke
parents:
diff changeset
248 (intptr_t*)fp,
a61af66fc99e Initial load
duke
parents:
diff changeset
249 CAST_FROM_FN_PTR(address, os::current_frame));
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if (os::is_first_C_frame(&myframe)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // stack is not walkable
107
93b6525e3b82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 0
diff changeset
252 frame ret; // This will be a null useless frame
93b6525e3b82 6603919: Stackwalking crash on x86 -server with Sun Studio's collect -j on
sgoldman
parents: 0
diff changeset
253 return ret;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 return os::get_sender_for_C_frame(&myframe);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 static int threadgetstate(thread_t tid, int *flags, lwpid_t *lwp, stack_t *ss, gregset_t rs, lwpstatus_t *lwpstatus) {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 char lwpstatusfile[PROCFILE_LENGTH];
a61af66fc99e Initial load
duke
parents:
diff changeset
261 int lwpfd, err;
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 if (err = os::Solaris::thr_getstate(tid, flags, lwp, ss, rs))
a61af66fc99e Initial load
duke
parents:
diff changeset
264 return (err);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (*flags == TRS_LWPID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 sprintf(lwpstatusfile, "/proc/%d/lwp/%d/lwpstatus", getpid(),
a61af66fc99e Initial load
duke
parents:
diff changeset
267 *lwp);
a61af66fc99e Initial load
duke
parents:
diff changeset
268 if ((lwpfd = open(lwpstatusfile, O_RDONLY)) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 perror("thr_mutator_status: open lwpstatus");
a61af66fc99e Initial load
duke
parents:
diff changeset
270 return (EINVAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
272 if (pread(lwpfd, lwpstatus, sizeof (lwpstatus_t), (off_t)0) !=
a61af66fc99e Initial load
duke
parents:
diff changeset
273 sizeof (lwpstatus_t)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 perror("thr_mutator_status: read lwpstatus");
a61af66fc99e Initial load
duke
parents:
diff changeset
275 (void) close(lwpfd);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 return (EINVAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278 (void) close(lwpfd);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280 return (0);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Detecting SSE support by OS
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // From solaris_i486.s
a61af66fc99e Initial load
duke
parents:
diff changeset
287 extern "C" bool sse_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 extern "C" bool sse_unavailable();
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 enum { SSE_UNKNOWN, SSE_NOT_SUPPORTED, SSE_SUPPORTED};
a61af66fc99e Initial load
duke
parents:
diff changeset
291 static int sse_status = SSE_UNKNOWN;
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 static void check_for_sse_support() {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 if (!VM_Version::supports_sse()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 sse_status = SSE_NOT_SUPPORTED;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // looking for _sse_hw in libc.so, if it does not exist or
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // the value (int) is 0, OS has no support for SSE
a61af66fc99e Initial load
duke
parents:
diff changeset
301 int *sse_hwp;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 void *h;
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if ((h=dlopen("/usr/lib/libc.so", RTLD_LAZY)) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 //open failed, presume no support for SSE
a61af66fc99e Initial load
duke
parents:
diff changeset
306 sse_status = SSE_NOT_SUPPORTED;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309 if ((sse_hwp = (int *)dlsym(h, "_sse_hw")) == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 sse_status = SSE_NOT_SUPPORTED;
a61af66fc99e Initial load
duke
parents:
diff changeset
311 } else if (*sse_hwp == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 sse_status = SSE_NOT_SUPPORTED;
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314 dlclose(h);
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 if (sse_status == SSE_UNKNOWN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 bool (*try_sse)() = (bool (*)())sse_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
318 sse_status = (*try_sse)() ? SSE_SUPPORTED : SSE_NOT_SUPPORTED;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322
585
22e09c0f4b47 6808589: Merge vm_version_x86_{32,64}.{cpp,hpp}
twisti
parents: 477
diff changeset
323 #endif // AMD64
22e09c0f4b47 6808589: Merge vm_version_x86_{32,64}.{cpp,hpp}
twisti
parents: 477
diff changeset
324
0
a61af66fc99e Initial load
duke
parents:
diff changeset
325 bool os::supports_sse() {
585
22e09c0f4b47 6808589: Merge vm_version_x86_{32,64}.{cpp,hpp}
twisti
parents: 477
diff changeset
326 #ifdef AMD64
22e09c0f4b47 6808589: Merge vm_version_x86_{32,64}.{cpp,hpp}
twisti
parents: 477
diff changeset
327 return true;
22e09c0f4b47 6808589: Merge vm_version_x86_{32,64}.{cpp,hpp}
twisti
parents: 477
diff changeset
328 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
329 if (sse_status == SSE_UNKNOWN)
a61af66fc99e Initial load
duke
parents:
diff changeset
330 check_for_sse_support();
a61af66fc99e Initial load
duke
parents:
diff changeset
331 return sse_status == SSE_SUPPORTED;
585
22e09c0f4b47 6808589: Merge vm_version_x86_{32,64}.{cpp,hpp}
twisti
parents: 477
diff changeset
332 #endif // AMD64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 bool os::is_allocatable(size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
337 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
338 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 if (bytes < 2 * G) {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 char* addr = reserve_memory(bytes, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 release_memory(addr, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 return addr != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
351 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
352
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2095
diff changeset
355 extern "C" JNIEXPORT int
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2095
diff changeset
356 JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2095
diff changeset
357 int abort_if_unrecognized) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
358 ucontext_t* uc = (ucontext_t*) ucVoid;
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
361 if (sig == SIGILL && info->si_addr == (caddr_t)sse_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // the SSE instruction faulted. supports_sse() need return false.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 uc->uc_mcontext.gregs[EIP] = (greg_t)sse_unavailable;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
367
a61af66fc99e Initial load
duke
parents:
diff changeset
368 Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady
a61af66fc99e Initial load
duke
parents:
diff changeset
369
11151
5e3b6f79d280 8020701: Avoid crashes in WatcherThread
rbackman
parents: 10405
diff changeset
370 // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
5e3b6f79d280 8020701: Avoid crashes in WatcherThread
rbackman
parents: 10405
diff changeset
371 // (no destructors can be run)
5e3b6f79d280 8020701: Avoid crashes in WatcherThread
rbackman
parents: 10405
diff changeset
372 os::WatcherThreadCrashProtection::check_crash_protection(sig, t);
5e3b6f79d280 8020701: Avoid crashes in WatcherThread
rbackman
parents: 10405
diff changeset
373
0
a61af66fc99e Initial load
duke
parents:
diff changeset
374 SignalHandlerMark shm(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 if(sig == SIGPIPE || sig == SIGXFSZ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
377 if (os::Solaris::chained_handler(sig, info, ucVoid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
378 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
379 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 if (PrintMiscellaneous && (WizardMode || Verbose)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 char buf[64];
a61af66fc99e Initial load
duke
parents:
diff changeset
382 warning("Ignoring %s - see 4229104 or 6499219",
a61af66fc99e Initial load
duke
parents:
diff changeset
383 os::exception_name(sig, buf, sizeof(buf)));
a61af66fc99e Initial load
duke
parents:
diff changeset
384
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 JavaThread* thread = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
391 VMThread* vmthread = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (os::Solaris::signal_handlers_are_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 if (t != NULL ){
a61af66fc99e Initial load
duke
parents:
diff changeset
395 if(t->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
396 thread = (JavaThread*)t;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 else if(t->is_VM_thread()){
a61af66fc99e Initial load
duke
parents:
diff changeset
399 vmthread = (VMThread *)t;
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 guarantee(sig != os::Solaris::SIGinterrupt(), "Can not chain VM interrupt signal, try -XX:+UseAltSigs");
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 if (sig == os::Solaris::SIGasync()) {
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
407 if(thread || vmthread){
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10161
diff changeset
408 OSThread::SR_handler(t, uc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
409 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 } else if (os::Solaris::chained_handler(sig, info, ucVoid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // If os::Solaris::SIGasync not chained, and this is a non-vm and
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // non-java thread
a61af66fc99e Initial load
duke
parents:
diff changeset
415 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418
a61af66fc99e Initial load
duke
parents:
diff changeset
419 if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // can't decode this kind of signal
a61af66fc99e Initial load
duke
parents:
diff changeset
421 info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 assert(sig == info->si_signo, "bad siginfo");
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // decide if this trap can be handled by a stub
a61af66fc99e Initial load
duke
parents:
diff changeset
427 address stub = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
428
a61af66fc99e Initial load
duke
parents:
diff changeset
429 address pc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 //%note os_trap_1
a61af66fc99e Initial load
duke
parents:
diff changeset
432 if (info != NULL && uc != NULL && thread != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // factor me: getPCfromContext
a61af66fc99e Initial load
duke
parents:
diff changeset
434 pc = (address) uc->uc_mcontext.gregs[REG_PC];
a61af66fc99e Initial load
duke
parents:
diff changeset
435
11127
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 10405
diff changeset
436 if (StubRoutines::is_safefetch_fault(pc)) {
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 10405
diff changeset
437 uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
980532a806a5 8016697: Use stubs to implement safefetch
goetz
parents: 10405
diff changeset
438 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Handle ALL stack overflow variations here
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 address addr = (address) info->si_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 if (thread->in_stack_yellow_zone(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 thread->disable_stack_yellow_zone();
a61af66fc99e Initial load
duke
parents:
diff changeset
446 if (thread->thread_state() == _thread_in_Java) {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // Throw a stack overflow exception. Guard pages will be reenabled
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // while unwinding the stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
449 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
a61af66fc99e Initial load
duke
parents:
diff changeset
450 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Thread was in the vm or native code. Return and try to finish.
a61af66fc99e Initial load
duke
parents:
diff changeset
452 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454 } else if (thread->in_stack_red_zone(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Fatal red zone violation. Disable the guard pages and fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // to handle_unexpected_exception way down below.
a61af66fc99e Initial load
duke
parents:
diff changeset
457 thread->disable_stack_red_zone();
a61af66fc99e Initial load
duke
parents:
diff changeset
458 tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 if (thread->thread_state() == _thread_in_vm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 stub = StubRoutines::handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 if (thread->thread_state() == _thread_in_Java) {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // Support Safepoint Polling
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if ( sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 stub = SharedRuntime::get_poll_stub(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473 else if (sig == SIGBUS && info->si_code == BUS_OBJERR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // BugId 4454115: A read from a MappedByteBuffer can fault
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // here if the underlying file has been truncated.
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // Do not crash the VM in such a case.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (nm != NULL && nm->has_unsafe_access()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 stub = StubRoutines::handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483 else
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (sig == SIGFPE && info->si_code == FPE_INTDIV) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // integer divide by zero
a61af66fc99e Initial load
duke
parents:
diff changeset
486 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
489 else if (sig == SIGFPE && info->si_code == FPE_FLTDIV) {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // floating-point divide by zero
a61af66fc99e Initial load
duke
parents:
diff changeset
491 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493 else if (sig == SIGFPE && info->si_code == FPE_FLTINV) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // The encoding of D2I in i486.ad can cause an exception prior
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // to the fist instruction if there was an invalid operation
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // pending. We want to dismiss that exception. From the win_32
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // side it also seems that if it really was the fist causing
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // the exception that we do the d2i by hand with different
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // rounding. Seems kind of weird. QQQ TODO
a61af66fc99e Initial load
duke
parents:
diff changeset
500 // Note that we take the exception at the NEXT floating point instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
501 if (pc[0] == 0xDB) {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 assert(pc[0] == 0xDB, "not a FIST opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
503 assert(pc[1] == 0x14, "not a FIST opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
504 assert(pc[2] == 0x24, "not a FIST opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
505 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
506 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
507 assert(pc[-3] == 0xDB, "not an flt invalid opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
508 assert(pc[-2] == 0x14, "not an flt invalid opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
509 assert(pc[-1] == 0x24, "not an flt invalid opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512 else if (sig == SIGFPE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 tty->print_cr("caught SIGFPE, info 0x%x.", info->si_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // QQQ It doesn't seem that we need to do this on x86 because we should be able
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // to return properly from the handler without this extra stuff on the back side.
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 else if (sig == SIGSEGV && info->si_code > 0 && !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // Determination of interpreter/vtable stub/compiled code null exception
a61af66fc99e Initial load
duke
parents:
diff changeset
522 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // and the heap gets shrunk before the field access.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 if ((sig == SIGSEGV) || (sig == SIGBUS)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 address addr = JNI_FastGetField::find_slowcase_pc(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (addr != (address)-1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 stub = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // Check to see if we caught the safepoint code in the
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // process of write protecting the memory serialization page.
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // It write enables the page immediately after protecting it
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // so we can just return to retry the write.
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if ((sig == SIGSEGV) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
540 os::is_memory_serialize_page(thread, (address)info->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // Block current thread until the memory serialize page permission restored.
a61af66fc99e Initial load
duke
parents:
diff changeset
542 os::block_on_serialize_page_trap();
a61af66fc99e Initial load
duke
parents:
diff changeset
543 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // Execution protection violation
a61af66fc99e Initial load
duke
parents:
diff changeset
548 //
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // Preventative code for future versions of Solaris which may
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // enable execution protection when running the 32-bit VM on AMD64.
a61af66fc99e Initial load
duke
parents:
diff changeset
551 //
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // This should be kept as the last step in the triage. We don't
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // have a dedicated trap number for a no-execute fault, so be
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // conservative and allow other handlers the first shot.
a61af66fc99e Initial load
duke
parents:
diff changeset
555 //
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // Note: We don't test that info->si_code == SEGV_ACCERR here.
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // this si_code is so generic that it is almost meaningless; and
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // the si_code for this condition may change in the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Furthermore, a false-positive should be harmless.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 if (UnguardOnExecutionViolation > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
561 (sig == SIGSEGV || sig == SIGBUS) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
562 uc->uc_mcontext.gregs[TRAPNO] == T_PGFLT) { // page fault
a61af66fc99e Initial load
duke
parents:
diff changeset
563 int page_size = os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
564 address addr = (address) info->si_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 address pc = (address) uc->uc_mcontext.gregs[REG_PC];
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // Make sure the pc and the faulting address are sane.
a61af66fc99e Initial load
duke
parents:
diff changeset
567 //
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // If an instruction spans a page boundary, and the page containing
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // the beginning of the instruction is executable but the following
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // page is not, the pc and the faulting address might be slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // different - we still want to unguard the 2nd page in this case.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 //
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // 15 bytes seems to be a (very) safe value for max instruction size.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 bool pc_is_near_addr =
a61af66fc99e Initial load
duke
parents:
diff changeset
575 (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
a61af66fc99e Initial load
duke
parents:
diff changeset
576 bool instr_spans_page_boundary =
a61af66fc99e Initial load
duke
parents:
diff changeset
577 (align_size_down((intptr_t) pc ^ (intptr_t) addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
578 (intptr_t) page_size) > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 static volatile address last_addr =
a61af66fc99e Initial load
duke
parents:
diff changeset
582 (address) os::non_memory_address_word();
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // In conservative mode, don't unguard unless the address is in the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
585 if (addr != last_addr &&
a61af66fc99e Initial load
duke
parents:
diff changeset
586 (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 472
diff changeset
588 // Make memory rwx and retry
0
a61af66fc99e Initial load
duke
parents:
diff changeset
589 address page_start =
a61af66fc99e Initial load
duke
parents:
diff changeset
590 (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 472
diff changeset
591 bool res = os::protect_memory((char*) page_start, page_size,
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 472
diff changeset
592 os::MEM_PROT_RWX);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 char buf[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
596 jio_snprintf(buf, sizeof(buf), "Execution protection violation "
a61af66fc99e Initial load
duke
parents:
diff changeset
597 "at " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
598 ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
599 page_start, (res ? "success" : "failed"), errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 tty->print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602 stub = pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // Set last_addr so if we fault again at the same address, we don't end
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // up in an endless loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
606 //
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // There are two potential complications here. Two threads trapping at
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // the same address at the same time could cause one of the threads to
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // think it already unguarded, and abort the VM. Likely very rare.
a61af66fc99e Initial load
duke
parents:
diff changeset
610 //
a61af66fc99e Initial load
duke
parents:
diff changeset
611 // The other race involves two threads alternately trapping at
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // different addresses and failing to unguard the page, resulting in
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // an endless loop. This condition is probably even more unlikely than
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // the first.
a61af66fc99e Initial load
duke
parents:
diff changeset
615 //
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // Although both cases could be avoided by using locks or thread local
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // last_addr, these solutions are unnecessary complication: this
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // handler is a best-effort safety net, not a complete solution. It is
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // disabled by default and should only be used as a workaround in case
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // we missed any no-execute-unsafe VM code.
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 last_addr = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if (stub != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 // save all thread context in case we need to restore it
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 if (thread != NULL) thread->set_saved_exception_pc(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 // 12/02/99: On Sparc it appears that the full context is also saved
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // but as yet, no one looks at or restores that saved context
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // factor me: setPC
a61af66fc99e Initial load
duke
parents:
diff changeset
634 uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
635 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
639 if (os::Solaris::chained_handler(sig, info, ucVoid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 }
a61af66fc99e Initial load
duke
parents:
diff changeset
642
a61af66fc99e Initial load
duke
parents:
diff changeset
643 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // Workaround (bug 4900493) for Solaris kernel bug 4966651.
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // Handle an undefined selector caused by an attempt to assign
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // fs in libthread getipriptr(). With the current libthread design every 512
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // thread creations the LDT for a private thread data structure is extended
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // and thre is a hazard that and another thread attempting a thread creation
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // will use a stale LDTR that doesn't reflect the structure's growth,
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // causing a GP fault.
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Enforce the probable limit of passes through here to guard against an
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // infinite loop if some other move to fs caused the GP fault. Note that
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // this loop counter is ultimately a heuristic as it is possible for
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // more than one thread to generate this fault at a time in an MP system.
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // In the case of the loop count being exceeded or if the poll fails
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // just fall through to a fatal error.
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // If there is some other source of T_GPFLT traps and the text at EIP is
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // unreadable this code will loop infinitely until the stack is exausted.
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // The key to diagnosis in this case is to look for the bottom signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 if(! IgnoreLibthreadGPFault) {
a61af66fc99e Initial load
duke
parents:
diff changeset
663 if (sig == SIGSEGV && uc->uc_mcontext.gregs[TRAPNO] == T_GPFLT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 const unsigned char *p =
a61af66fc99e Initial load
duke
parents:
diff changeset
665 (unsigned const char *) uc->uc_mcontext.gregs[EIP];
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Expected instruction?
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 if(p[0] == movlfs[0] && p[1] == movlfs[1]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670
a61af66fc99e Initial load
duke
parents:
diff changeset
671 Atomic::inc(&ldtr_refresh);
a61af66fc99e Initial load
duke
parents:
diff changeset
672
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // Infinite loop?
a61af66fc99e Initial load
duke
parents:
diff changeset
674
a61af66fc99e Initial load
duke
parents:
diff changeset
675 if(ldtr_refresh < ((2 << 16) / PAGESIZE)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // No, force scheduling to get a fresh view of the LDTR
a61af66fc99e Initial load
duke
parents:
diff changeset
678
a61af66fc99e Initial load
duke
parents:
diff changeset
679 if(poll(NULL, 0, 10) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // Retry the move
a61af66fc99e Initial load
duke
parents:
diff changeset
682
a61af66fc99e Initial load
duke
parents:
diff changeset
683 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
689 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if (!abort_if_unrecognized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // caller wants another chance, so give it to him
a61af66fc99e Initial load
duke
parents:
diff changeset
693 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 if (!os::Solaris::libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 struct sigaction oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 sigaction(sig, (struct sigaction *)0, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 if (oldAct.sa_sigaction != signalHandler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 void* sighand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
701 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
605
98cb887364d3 6810672: Comment typos
twisti
parents: 585
diff changeset
702 warning("Unexpected Signal %d occurred under user-defined signal handler %#lx", sig, (long)sighand);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 if (pc == NULL && uc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 pc = (address) uc->uc_mcontext.gregs[REG_PC];
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // unmask current signal
a61af66fc99e Initial load
duke
parents:
diff changeset
711 sigset_t newset;
a61af66fc99e Initial load
duke
parents:
diff changeset
712 sigemptyset(&newset);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 sigaddset(&newset, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 sigprocmask(SIG_UNBLOCK, &newset, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
715
2095
36c186bcc085 6302804: Hotspot VM dies ungraceful death when C heap is exhausted in various places.
coleenp
parents: 1980
diff changeset
716 // Determine which sort of error to throw. Out of swap may signal
36c186bcc085 6302804: Hotspot VM dies ungraceful death when C heap is exhausted in various places.
coleenp
parents: 1980
diff changeset
717 // on the thread stack, which could get a mapping error when touched.
36c186bcc085 6302804: Hotspot VM dies ungraceful death when C heap is exhausted in various places.
coleenp
parents: 1980
diff changeset
718 address addr = (address) info->si_addr;
36c186bcc085 6302804: Hotspot VM dies ungraceful death when C heap is exhausted in various places.
coleenp
parents: 1980
diff changeset
719 if (sig == SIGBUS && info->si_code == BUS_OBJERR && info->si_errno == ENOMEM) {
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 7206
diff changeset
720 vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "Out of swap space to map in thread stack.");
2095
36c186bcc085 6302804: Hotspot VM dies ungraceful death when C heap is exhausted in various places.
coleenp
parents: 1980
diff changeset
721 }
36c186bcc085 6302804: Hotspot VM dies ungraceful death when C heap is exhausted in various places.
coleenp
parents: 1980
diff changeset
722
0
a61af66fc99e Initial load
duke
parents:
diff changeset
723 VMError err(t, sig, pc, info, ucVoid);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 err.report_and_die();
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 void os::print_context(outputStream *st, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 if (context == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 ucontext_t *uc = (ucontext_t*)context;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 st->print_cr("Registers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
734 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
735 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
736 st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
737 st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
738 st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
739 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
740 st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
742 st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
743 st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 st->cr();
1907
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
745 st->print( "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
746 st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
747 st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
a61af66fc99e Initial load
duke
parents:
diff changeset
748 st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
1250
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 671
diff changeset
749 st->cr();
3f5b7efb9642 6920293: OptimizeStringConcat causing core dumps
never
parents: 671
diff changeset
750 st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
751 st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
a61af66fc99e Initial load
duke
parents:
diff changeset
752 st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
a61af66fc99e Initial load
duke
parents:
diff changeset
753 st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
a61af66fc99e Initial load
duke
parents:
diff changeset
754 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
755 st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
756 st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]);
a61af66fc99e Initial load
duke
parents:
diff changeset
757 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
758 st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
760 st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
762 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
763 st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
766 st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
767 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
768 st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
769 st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]);
a61af66fc99e Initial load
duke
parents:
diff changeset
770 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
771 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
772 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
773
a61af66fc99e Initial load
duke
parents:
diff changeset
774 intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
775 st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
776 print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
777 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // Note: it may be unsafe to inspect memory near pc. For example, pc may
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // point to garbage if entry point in an nmethod is corrupted. Leave
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // this at the end, and hope for the best.
a61af66fc99e Initial load
duke
parents:
diff changeset
782 ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 address pc = epc.pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
784 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
1907
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
785 print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
786 }
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
787
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
788 void os::print_register_info(outputStream *st, void *context) {
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
789 if (context == NULL) return;
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
790
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
791 ucontext_t *uc = (ucontext_t*)context;
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
792
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
793 st->print_cr("Register to memory mapping:");
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
794 st->cr();
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
795
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
796 // this is horrendously verbose but the layout of the registers in the
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
797 // context does not match how we defined our abstract Register set, so
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
798 // we can't just iterate through the gregs area
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
799
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
800 // this is only for the "general purpose" registers
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
801
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
802 #ifdef AMD64
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
803 st->print("RAX="); print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
804 st->print("RBX="); print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
805 st->print("RCX="); print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
806 st->print("RDX="); print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
807 st->print("RSP="); print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
808 st->print("RBP="); print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
809 st->print("RSI="); print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
810 st->print("RDI="); print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
811 st->print("R8 ="); print_location(st, uc->uc_mcontext.gregs[REG_R8]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
812 st->print("R9 ="); print_location(st, uc->uc_mcontext.gregs[REG_R9]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
813 st->print("R10="); print_location(st, uc->uc_mcontext.gregs[REG_R10]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
814 st->print("R11="); print_location(st, uc->uc_mcontext.gregs[REG_R11]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
815 st->print("R12="); print_location(st, uc->uc_mcontext.gregs[REG_R12]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
816 st->print("R13="); print_location(st, uc->uc_mcontext.gregs[REG_R13]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
817 st->print("R14="); print_location(st, uc->uc_mcontext.gregs[REG_R14]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
818 st->print("R15="); print_location(st, uc->uc_mcontext.gregs[REG_R15]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
819 #else
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
820 st->print("EAX="); print_location(st, uc->uc_mcontext.gregs[EAX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
821 st->print("EBX="); print_location(st, uc->uc_mcontext.gregs[EBX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
822 st->print("ECX="); print_location(st, uc->uc_mcontext.gregs[ECX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
823 st->print("EDX="); print_location(st, uc->uc_mcontext.gregs[EDX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
824 st->print("ESP="); print_location(st, uc->uc_mcontext.gregs[UESP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
825 st->print("EBP="); print_location(st, uc->uc_mcontext.gregs[EBP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
826 st->print("ESI="); print_location(st, uc->uc_mcontext.gregs[ESI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
827 st->print("EDI="); print_location(st, uc->uc_mcontext.gregs[EDI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
828 #endif
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
829
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
830 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
832
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1624
diff changeset
833
0
a61af66fc99e Initial load
duke
parents:
diff changeset
834 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
835 void os::Solaris::init_thread_fpu_state(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // Nothing to do
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // From solaris_i486.s
a61af66fc99e Initial load
duke
parents:
diff changeset
840 extern "C" void fixcw();
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 void os::Solaris::init_thread_fpu_state(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // Set fpu to 53 bit precision. This happens too early to use a stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
844 fixcw();
a61af66fc99e Initial load
duke
parents:
diff changeset
845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
846
a61af66fc99e Initial load
duke
parents:
diff changeset
847 // These routines are the initial value of atomic_xchg_entry(),
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // atomic_cmpxchg_entry(), atomic_inc_entry() and fence_entry()
a61af66fc99e Initial load
duke
parents:
diff changeset
849 // until initialization is complete.
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // TODO - replace with .il implementation when compiler supports it.
a61af66fc99e Initial load
duke
parents:
diff changeset
851
a61af66fc99e Initial load
duke
parents:
diff changeset
852 typedef jint xchg_func_t (jint, volatile jint*);
a61af66fc99e Initial load
duke
parents:
diff changeset
853 typedef jint cmpxchg_func_t (jint, volatile jint*, jint);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 typedef jlong cmpxchg_long_func_t(jlong, volatile jlong*, jlong);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 typedef jint add_func_t (jint, volatile jint*);
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 jint os::atomic_xchg_bootstrap(jint exchange_value, volatile jint* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // try to use the stub:
a61af66fc99e Initial load
duke
parents:
diff changeset
859 xchg_func_t* func = CAST_TO_FN_PTR(xchg_func_t*, StubRoutines::atomic_xchg_entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 if (func != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 os::atomic_xchg_func = func;
a61af66fc99e Initial load
duke
parents:
diff changeset
863 return (*func)(exchange_value, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865 assert(Threads::number_of_threads() == 0, "for bootstrap only");
a61af66fc99e Initial load
duke
parents:
diff changeset
866
a61af66fc99e Initial load
duke
parents:
diff changeset
867 jint old_value = *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 *dest = exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
869 return old_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 jint os::atomic_cmpxchg_bootstrap(jint exchange_value, volatile jint* dest, jint compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // try to use the stub:
a61af66fc99e Initial load
duke
parents:
diff changeset
874 cmpxchg_func_t* func = CAST_TO_FN_PTR(cmpxchg_func_t*, StubRoutines::atomic_cmpxchg_entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 if (func != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
877 os::atomic_cmpxchg_func = func;
a61af66fc99e Initial load
duke
parents:
diff changeset
878 return (*func)(exchange_value, dest, compare_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880 assert(Threads::number_of_threads() == 0, "for bootstrap only");
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 jint old_value = *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 if (old_value == compare_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
884 *dest = exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
885 return old_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 jlong os::atomic_cmpxchg_long_bootstrap(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // try to use the stub:
a61af66fc99e Initial load
duke
parents:
diff changeset
890 cmpxchg_long_func_t* func = CAST_TO_FN_PTR(cmpxchg_long_func_t*, StubRoutines::atomic_cmpxchg_long_entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 if (func != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 os::atomic_cmpxchg_long_func = func;
a61af66fc99e Initial load
duke
parents:
diff changeset
894 return (*func)(exchange_value, dest, compare_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
896 assert(Threads::number_of_threads() == 0, "for bootstrap only");
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 jlong old_value = *dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
899 if (old_value == compare_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
900 *dest = exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 return old_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 jint os::atomic_add_bootstrap(jint add_value, volatile jint* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // try to use the stub:
a61af66fc99e Initial load
duke
parents:
diff changeset
906 add_func_t* func = CAST_TO_FN_PTR(add_func_t*, StubRoutines::atomic_add_entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 if (func != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 os::atomic_add_func = func;
a61af66fc99e Initial load
duke
parents:
diff changeset
910 return (*func)(add_value, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 }
a61af66fc99e Initial load
duke
parents:
diff changeset
912 assert(Threads::number_of_threads() == 0, "for bootstrap only");
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 return (*dest) += add_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap;
a61af66fc99e Initial load
duke
parents:
diff changeset
918 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap;
a61af66fc99e Initial load
duke
parents:
diff changeset
919 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
a61af66fc99e Initial load
duke
parents:
diff changeset
920 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap;
a61af66fc99e Initial load
duke
parents:
diff changeset
921
1624
726b40449bd2 6939019: Source code adjustments for parfait compilation of hotspot
zgu
parents: 1552
diff changeset
922 extern "C" void _solaris_raw_setup_fpu(address ptr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
923 void os::setup_fpu() {
a61af66fc99e Initial load
duke
parents:
diff changeset
924 address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std();
a61af66fc99e Initial load
duke
parents:
diff changeset
925 _solaris_raw_setup_fpu(fpu_cntrl);
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927 #endif // AMD64
5903
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
928
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
929 #ifndef PRODUCT
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
930 void os::verify_stack_alignment() {
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
931 #ifdef AMD64
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
932 assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
933 #endif
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
934 }
da4be62fb889 7147740: add assertions to check stack alignment on VM entry from generated code (x64)
roland
parents: 2426
diff changeset
935 #endif