annotate src/os_cpu/linux_x86/vm/os_linux_x86.cpp @ 5318:b5cd7bc05695

Method entry counters: Enable the flag to collect an execution profile of compiled methods and their callers. This allows to, e.g., detect methods that should be inlined because they are called frequently.
author Christian Wimmer <Christian.Wimmer@Oracle.com>
date Fri, 27 Apr 2012 12:56:39 -0700
parents 70aaaa83b93a
children 957c266d8bc5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2426
1d1603768966 7010070: Update all 2010 Oracle-changed OpenJDK files to have the proper copyright dates - second pass
trims
parents: 2191
diff changeset
2 * Copyright (c) 1999, 2011, 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: 1490
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
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: 1490
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
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
26 #include "assembler_x86.inline.hpp"
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_linux.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_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
36 #include "nativeInst_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
37 #include "os_share_linux.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
38 #include "prims/jniFastGetField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
39 #include "prims/jvm.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
40 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
41 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
42 #include "runtime/extendedPC.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
43 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
44 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
45 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
46 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
47 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
48 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
49 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
50 #include "runtime/stubRoutines.hpp"
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 "thread_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
53 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
54 #include "utilities/vmError.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
55 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
56 #include "c1/c1_Runtime1.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
57 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
58 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
59 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
60 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
63 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
64 # include <sys/mman.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
65 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
66 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
67 # include <errno.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
68 # include <dlfcn.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
69 # include <stdlib.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
70 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
71 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
72 # include <sys/resource.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
73 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
74 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
75 # include <sys/time.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
76 # include <sys/utsname.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
77 # include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
78 # include <sys/wait.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
79 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
80 # include <poll.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
81 # include <ucontext.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
82 # include <fpu_control.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
85 #define REG_SP REG_RSP
a61af66fc99e Initial load
duke
parents:
diff changeset
86 #define REG_PC REG_RIP
a61af66fc99e Initial load
duke
parents:
diff changeset
87 #define REG_FP REG_RBP
a61af66fc99e Initial load
duke
parents:
diff changeset
88 #define SPELL_REG_SP "rsp"
a61af66fc99e Initial load
duke
parents:
diff changeset
89 #define SPELL_REG_FP "rbp"
a61af66fc99e Initial load
duke
parents:
diff changeset
90 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
91 #define REG_SP REG_UESP
a61af66fc99e Initial load
duke
parents:
diff changeset
92 #define REG_PC REG_EIP
a61af66fc99e Initial load
duke
parents:
diff changeset
93 #define REG_FP REG_EBP
a61af66fc99e Initial load
duke
parents:
diff changeset
94 #define SPELL_REG_SP "esp"
a61af66fc99e Initial load
duke
parents:
diff changeset
95 #define SPELL_REG_FP "ebp"
a61af66fc99e Initial load
duke
parents:
diff changeset
96 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 address os::current_stack_pointer() {
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
99 #ifdef SPARC_WORKS
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
100 register void *esp;
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
101 __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
102 return (address) ((char*)esp + sizeof(long)*2);
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
103 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104 register void *esp __asm__ (SPELL_REG_SP);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 return (address) esp;
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
106 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 char* os::non_memory_address_word() {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // Must never look like an address returned by reserve_memory,
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // even in its subfields (as defined by the CPU immediate fields,
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // if the CPU splits constants across multiple instructions).
a61af66fc99e Initial load
duke
parents:
diff changeset
113
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 void os::initialize_thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Nothing to do.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
120
a61af66fc99e Initial load
duke
parents:
diff changeset
121 address os::Linux::ucontext_get_pc(ucontext_t * uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 return (address)uc->uc_mcontext.gregs[REG_PC];
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 return (intptr_t*)uc->uc_mcontext.gregs[REG_SP];
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return (intptr_t*)uc->uc_mcontext.gregs[REG_FP];
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
a61af66fc99e Initial load
duke
parents:
diff changeset
134 // is currently interrupted by SIGPROF.
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // frames. Currently we don't do that on Linux, so it's the same as
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // os::fetch_frame_from_context().
a61af66fc99e Initial load
duke
parents:
diff changeset
138 ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
139 ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 assert(thread != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 assert(ret_sp != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
143 assert(ret_fp != NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 ExtendedPC os::fetch_frame_from_context(void* ucVoid,
a61af66fc99e Initial load
duke
parents:
diff changeset
149 intptr_t** ret_sp, intptr_t** ret_fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 ExtendedPC epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 ucontext_t* uc = (ucontext_t*)ucVoid;
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 if (uc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
155 epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
a61af66fc99e Initial load
duke
parents:
diff changeset
156 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // construct empty ExtendedPC for return value checking
a61af66fc99e Initial load
duke
parents:
diff changeset
160 epc = ExtendedPC(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 if (ret_sp) *ret_sp = (intptr_t *)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 if (ret_fp) *ret_fp = (intptr_t *)NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 frame os::fetch_frame_from_context(void* ucVoid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 intptr_t* sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 intptr_t* fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return frame(sp, fp, epc.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // By default, gcc always save frame pointer (%ebp/%rbp) on stack. It may get
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // turned off by -fomit-frame-pointer,
a61af66fc99e Initial load
duke
parents:
diff changeset
177 frame os::get_sender_for_C_frame(frame* fr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 intptr_t* _get_previous_fp() {
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
182 #ifdef SPARC_WORKS
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
183 register intptr_t **ebp;
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
184 __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
185 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
186 register intptr_t **ebp __asm__ (SPELL_REG_FP);
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
187 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return (intptr_t*) *ebp; // we want what it points to.
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 frame os::current_frame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 intptr_t* fp = _get_previous_fp();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 frame myframe((intptr_t*)os::current_stack_pointer(),
a61af66fc99e Initial load
duke
parents:
diff changeset
195 (intptr_t*)fp,
a61af66fc99e Initial load
duke
parents:
diff changeset
196 CAST_FROM_FN_PTR(address, os::current_frame));
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if (os::is_first_C_frame(&myframe)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // stack is not walkable
a61af66fc99e Initial load
duke
parents:
diff changeset
199 return frame(NULL, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
200 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return os::get_sender_for_C_frame(&myframe);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Utility functions
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // From IA32 System Programming Guide
a61af66fc99e Initial load
duke
parents:
diff changeset
208 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 trap_page_fault = 0xE
a61af66fc99e Initial load
duke
parents:
diff changeset
210 };
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 extern "C" void Fetch32PFI () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 extern "C" void Fetch32Resume () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
215 extern "C" void FetchNPFI () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 extern "C" void FetchNResume () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
218
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 1980
diff changeset
219 extern "C" JNIEXPORT int
0
a61af66fc99e Initial load
duke
parents:
diff changeset
220 JVM_handle_linux_signal(int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
221 siginfo_t* info,
a61af66fc99e Initial load
duke
parents:
diff changeset
222 void* ucVoid,
a61af66fc99e Initial load
duke
parents:
diff changeset
223 int abort_if_unrecognized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 ucontext_t* uc = (ucontext_t*) ucVoid;
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 Thread* t = ThreadLocalStorage::get_thread_slow();
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 SignalHandlerMark shm(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // Note: it's not uncommon that JNI code uses signal/sigset to install
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
a61af66fc99e Initial load
duke
parents:
diff changeset
232 // or have a SIGILL handler when detecting CPU type). When that happens,
a61af66fc99e Initial load
duke
parents:
diff changeset
233 // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // avoid unnecessary crash when libjsig is not preloaded, try handle signals
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // that do not require siginfo/ucontext first.
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if (sig == SIGPIPE || sig == SIGXFSZ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // allow chained handler to go first
a61af66fc99e Initial load
duke
parents:
diff changeset
239 if (os::Linux::chained_handler(sig, info, ucVoid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
241 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (PrintMiscellaneous && (WizardMode || Verbose)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 char buf[64];
a61af66fc99e Initial load
duke
parents:
diff changeset
244 warning("Ignoring %s - see bugs 4229104 or 646499219",
a61af66fc99e Initial load
duke
parents:
diff changeset
245 os::exception_name(sig, buf, sizeof(buf)));
a61af66fc99e Initial load
duke
parents:
diff changeset
246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
247 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 JavaThread* thread = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 VMThread* vmthread = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 if (os::Linux::signal_handlers_are_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if (t != NULL ){
a61af66fc99e Initial load
duke
parents:
diff changeset
255 if(t->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 thread = (JavaThread*)t;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 else if(t->is_VM_thread()){
a61af66fc99e Initial load
duke
parents:
diff changeset
259 vmthread = (VMThread *)t;
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
264 NOTE: does not seem to work on linux.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // can't decode this kind of signal
a61af66fc99e Initial load
duke
parents:
diff changeset
267 info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
269 assert(sig == info->si_signo, "bad siginfo");
a61af66fc99e Initial load
duke
parents:
diff changeset
270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
271 */
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // decide if this trap can be handled by a stub
a61af66fc99e Initial load
duke
parents:
diff changeset
273 address stub = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 address pc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 //%note os_trap_1
a61af66fc99e Initial load
duke
parents:
diff changeset
278 if (info != NULL && uc != NULL && thread != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
279 pc = (address) os::Linux::ucontext_get_pc(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 if (pc == (address) Fetch32PFI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 return 1 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
286 if (pc == (address) FetchNPFI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return 1 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
291
1936
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
292 if (TraceSignals) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
293 CodeBlob* cb = CodeCache::find_blob(pc);
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
294 if (cb != NULL && cb->is_nmethod()) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
295 nmethod* nm = (nmethod*)cb;
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
296 int rel = pc - nm->code_begin();
1942
00bc9eaf0e24 Support for -XX:+UseFastLocking flag. Fixed monitor enter XIR template for correct debug info at the runtime call.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1936
diff changeset
297 tty->print_cr(err_msg("Implicit exception at %d of method %s", rel, nm->method()->name()->as_C_string()));
1936
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
298 } else {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
299 tty->print_cr("No code blob found for %x", pc);
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
300 }
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
301 }
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
302
0
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // Handle ALL stack overflow variations here
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (sig == SIGSEGV) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 address addr = (address) info->si_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 // check if fault address is within thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (addr < thread->stack_base() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
309 addr >= thread->stack_base() - thread->stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // stack overflow
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (thread->in_stack_yellow_zone(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 thread->disable_stack_yellow_zone();
a61af66fc99e Initial load
duke
parents:
diff changeset
313 if (thread->thread_state() == _thread_in_Java) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Throw a stack overflow exception. Guard pages will be reenabled
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // while unwinding the stack.
5182
70aaaa83b93a fixed gcc warning; added note to README_GRAAL about disabling the bootstrap step
Doug Simon <doug.simon@oracle.com>
parents: 2491
diff changeset
316 if (WizardMode) tty->print("implicit: %08x%08x\n", ((long long)pc) >> 32, pc);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
317 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Thread was in the vm or native code. Return and try to finish.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 } else if (thread->in_stack_red_zone(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Fatal red zone violation. Disable the guard pages and fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // to handle_unexpected_exception way down below.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 thread->disable_stack_red_zone();
a61af66fc99e Initial load
duke
parents:
diff changeset
326 tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
a61af66fc99e Initial load
duke
parents:
diff changeset
327 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Accessing stack address below sp may cause SEGV if current
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // thread has MAP_GROWSDOWN stack. This should only happen when
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // current thread was created by user code with MAP_GROWSDOWN flag
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // and then attached to VM. See notes in os_linux.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
332 if (thread->osthread()->expanding_stack() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
333 thread->osthread()->set_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
334 if (os::Linux::manually_expand_stack(thread, addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 thread->osthread()->clear_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338 thread->osthread()->clear_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
339 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 fatal("recursive segv. expanding stack.");
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 if (thread->thread_state() == _thread_in_Java) {
a61af66fc99e Initial load
duke
parents:
diff changeset
347 // Java thread running in Java code => find exception handler if any
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // a fault inside compiled code, the interpreter, or a stub
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 stub = SharedRuntime::get_poll_stub(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // BugId 4454115: A read from a MappedByteBuffer can fault
a61af66fc99e Initial load
duke
parents:
diff changeset
354 // here if the underlying file has been truncated.
a61af66fc99e Initial load
duke
parents:
diff changeset
355 // Do not crash the VM in such a case.
a61af66fc99e Initial load
duke
parents:
diff changeset
356 CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
357 nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
358 if (nm != NULL && nm->has_unsafe_access()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 stub = StubRoutines::handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 else
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
365 if (sig == SIGFPE &&
a61af66fc99e Initial load
duke
parents:
diff changeset
366 (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 stub =
a61af66fc99e Initial load
duke
parents:
diff changeset
368 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
369 continuation_for_implicit_exception(thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
370 pc,
a61af66fc99e Initial load
duke
parents:
diff changeset
371 SharedRuntime::
a61af66fc99e Initial load
duke
parents:
diff changeset
372 IMPLICIT_DIVIDE_BY_ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
373 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
374 if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // HACK: si_code does not work on linux 2.2.12-20!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
376 int op = pc[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
377 if (op == 0xDB) {
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // FIST
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // TODO: The encoding of D2I in i486.ad can cause an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // prior to the fist instruction if there was an invalid operation
a61af66fc99e Initial load
duke
parents:
diff changeset
381 // pending. We want to dismiss that exception. From the win_32
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // side it also seems that if it really was the fist causing
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // the exception that we do the d2i by hand with different
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // rounding. Seems kind of weird.
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // NOTE: that we take the exception at the NEXT floating point instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
386 assert(pc[0] == 0xDB, "not a FIST opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
387 assert(pc[1] == 0x14, "not a FIST opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
388 assert(pc[2] == 0x24, "not a FIST opcode");
a61af66fc99e Initial load
duke
parents:
diff changeset
389 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
390 } else if (op == 0xF7) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // IDIV
a61af66fc99e Initial load
duke
parents:
diff changeset
392 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO);
a61af66fc99e Initial load
duke
parents:
diff changeset
393 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 // TODO: handle more cases if we are using other x86 instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
395 // that can generate SIGFPE signal on linux.
a61af66fc99e Initial load
duke
parents:
diff changeset
396 tty->print_cr("unknown opcode 0x%X with SIGFPE.", op);
a61af66fc99e Initial load
duke
parents:
diff changeset
397 fatal("please update this code.");
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
400 } else if (sig == SIGSEGV &&
a61af66fc99e Initial load
duke
parents:
diff changeset
401 !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
1936
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
402 if (TraceSignals) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
403 tty->print_cr("Implicit exception continuation");
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
404 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Determination of interpreter/vtable stub/compiled code null exception
a61af66fc99e Initial load
duke
parents:
diff changeset
406 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
1936
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
407 } else if (sig == SIGSEGV) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
408 if (TraceSignals) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
409 tty->print_cr("would have needed explicit null check %d", (intptr_t)info->si_addr);
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1930
diff changeset
410 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412 } else if (thread->thread_state() == _thread_in_vm &&
a61af66fc99e Initial load
duke
parents:
diff changeset
413 sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
a61af66fc99e Initial load
duke
parents:
diff changeset
414 thread->doing_unsafe_access()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 stub = StubRoutines::handler_for_unsafe_access();
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // and the heap gets shrunk before the field access.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if ((sig == SIGSEGV) || (sig == SIGBUS)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 address addr = JNI_FastGetField::find_slowcase_pc(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 if (addr != (address)-1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 stub = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // Check to see if we caught the safepoint code in the
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // process of write protecting the memory serialization page.
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // It write enables the page immediately after protecting it
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // so we can just return to retry the write.
a61af66fc99e Initial load
duke
parents:
diff changeset
431 if ((sig == SIGSEGV) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
432 os::is_memory_serialize_page(thread, (address) info->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 // Block current thread until the memory serialize page permission restored.
a61af66fc99e Initial load
duke
parents:
diff changeset
434 os::block_on_serialize_page_trap();
a61af66fc99e Initial load
duke
parents:
diff changeset
435 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // Execution protection violation
a61af66fc99e Initial load
duke
parents:
diff changeset
441 //
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // This should be kept as the last step in the triage. We don't
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // have a dedicated trap number for a no-execute fault, so be
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // conservative and allow other handlers the first shot.
a61af66fc99e Initial load
duke
parents:
diff changeset
445 //
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // Note: We don't test that info->si_code == SEGV_ACCERR here.
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // this si_code is so generic that it is almost meaningless; and
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // the si_code for this condition may change in the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // Furthermore, a false-positive should be harmless.
a61af66fc99e Initial load
duke
parents:
diff changeset
450 if (UnguardOnExecutionViolation > 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
451 (sig == SIGSEGV || sig == SIGBUS) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
452 uc->uc_mcontext.gregs[REG_TRAPNO] == trap_page_fault) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 int page_size = os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
454 address addr = (address) info->si_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
455 address pc = os::Linux::ucontext_get_pc(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // Make sure the pc and the faulting address are sane.
a61af66fc99e Initial load
duke
parents:
diff changeset
457 //
a61af66fc99e Initial load
duke
parents:
diff changeset
458 // If an instruction spans a page boundary, and the page containing
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // the beginning of the instruction is executable but the following
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // page is not, the pc and the faulting address might be slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // different - we still want to unguard the 2nd page in this case.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 //
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // 15 bytes seems to be a (very) safe value for max instruction size.
a61af66fc99e Initial load
duke
parents:
diff changeset
464 bool pc_is_near_addr =
a61af66fc99e Initial load
duke
parents:
diff changeset
465 (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
a61af66fc99e Initial load
duke
parents:
diff changeset
466 bool instr_spans_page_boundary =
a61af66fc99e Initial load
duke
parents:
diff changeset
467 (align_size_down((intptr_t) pc ^ (intptr_t) addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
468 (intptr_t) page_size) > 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
469
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 static volatile address last_addr =
a61af66fc99e Initial load
duke
parents:
diff changeset
472 (address) os::non_memory_address_word();
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // In conservative mode, don't unguard unless the address is in the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
475 if (addr != last_addr &&
a61af66fc99e Initial load
duke
parents:
diff changeset
476 (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
477
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 196
diff changeset
478 // Set memory to RWX and retry
0
a61af66fc99e Initial load
duke
parents:
diff changeset
479 address page_start =
a61af66fc99e Initial load
duke
parents:
diff changeset
480 (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: 196
diff changeset
481 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: 196
diff changeset
482 os::MEM_PROT_RWX);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 char buf[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
486 jio_snprintf(buf, sizeof(buf), "Execution protection violation "
a61af66fc99e Initial load
duke
parents:
diff changeset
487 "at " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
488 ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
489 page_start, (res ? "success" : "failed"), errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
490 tty->print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492 stub = pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // Set last_addr so if we fault again at the same address, we don't end
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // up in an endless loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
496 //
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // There are two potential complications here. Two threads trapping at
a61af66fc99e Initial load
duke
parents:
diff changeset
498 // the same address at the same time could cause one of the threads to
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // think it already unguarded, and abort the VM. Likely very rare.
a61af66fc99e Initial load
duke
parents:
diff changeset
500 //
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // The other race involves two threads alternately trapping at
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // different addresses and failing to unguard the page, resulting in
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // an endless loop. This condition is probably even more unlikely than
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // the first.
a61af66fc99e Initial load
duke
parents:
diff changeset
505 //
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // Although both cases could be avoided by using locks or thread local
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // last_addr, these solutions are unnecessary complication: this
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // handler is a best-effort safety net, not a complete solution. It is
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // disabled by default and should only be used as a workaround in case
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // we missed any no-execute-unsafe VM code.
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 last_addr = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (stub != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // save all thread context in case we need to restore it
a61af66fc99e Initial load
duke
parents:
diff changeset
520 if (thread != NULL) thread->set_saved_exception_pc(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
521
a61af66fc99e Initial load
duke
parents:
diff changeset
522 uc->uc_mcontext.gregs[REG_PC] = (greg_t)stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
523 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (os::Linux::chained_handler(sig, info, ucVoid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 if (!abort_if_unrecognized) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // caller wants another chance, so give it to him
a61af66fc99e Initial load
duke
parents:
diff changeset
533 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 if (pc == NULL && uc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 pc = os::Linux::ucontext_get_pc(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // unmask current signal
a61af66fc99e Initial load
duke
parents:
diff changeset
541 sigset_t newset;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 sigemptyset(&newset);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 sigaddset(&newset, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
544 sigprocmask(SIG_UNBLOCK, &newset, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 VMError err(t, sig, pc, info, ucVoid);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 err.report_and_die();
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 void os::Linux::init_thread_fpu_state(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // set fpu to 53 bit precision
a61af66fc99e Initial load
duke
parents:
diff changeset
555 set_fpu_control_word(0x27f);
a61af66fc99e Initial load
duke
parents:
diff changeset
556 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 int os::Linux::get_fpu_control_word(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
561 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
562 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
563 int fpu_control;
a61af66fc99e Initial load
duke
parents:
diff changeset
564 _FPU_GETCW(fpu_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 return fpu_control & 0xffff;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 void os::Linux::set_fpu_control_word(int fpu_control) {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
571 _FPU_SETCW(fpu_control);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // Check that the linux kernel version is 2.4 or higher since earlier
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // versions do not support SSE without patches.
a61af66fc99e Initial load
duke
parents:
diff changeset
577 bool os::supports_sse() {
a61af66fc99e Initial load
duke
parents:
diff changeset
578 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
579 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
580 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
581 struct utsname uts;
a61af66fc99e Initial load
duke
parents:
diff changeset
582 if( uname(&uts) != 0 ) return false; // uname fails?
a61af66fc99e Initial load
duke
parents:
diff changeset
583 char *minor_string;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 int major = strtol(uts.release,&minor_string,10);
a61af66fc99e Initial load
duke
parents:
diff changeset
585 int minor = strtol(minor_string+1,NULL,10);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 bool result = (major > 2 || (major==2 && minor >= 4));
a61af66fc99e Initial load
duke
parents:
diff changeset
587 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
588 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 tty->print("OS version is %d.%d, which %s support SSE/SSE2\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
590 major,minor, result ? "DOES" : "does NOT");
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
593 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
596
a61af66fc99e Initial load
duke
parents:
diff changeset
597 bool os::is_allocatable(size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // unused on amd64?
a61af66fc99e Initial load
duke
parents:
diff changeset
600 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
601 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 if (bytes < 2 * G) {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 char* addr = reserve_memory(bytes, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
610 release_memory(addr, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 return addr != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
614 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
621 size_t os::Linux::min_stack_allowed = 64 * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // amd64: pthread on amd64 is always in floating stack mode
a61af66fc99e Initial load
duke
parents:
diff changeset
624 bool os::Linux::supports_variable_stack_size() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
625 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
626 size_t os::Linux::min_stack_allowed = (48 DEBUG_ONLY(+4))*K;
a61af66fc99e Initial load
duke
parents:
diff changeset
627
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
628 #ifdef __GNUC__
0
a61af66fc99e Initial load
duke
parents:
diff changeset
629 #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
630 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
631
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Test if pthread library can support variable thread stack size. LinuxThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // in fixed stack mode allocates 2M fixed slot for each thread. LinuxThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // in floating stack mode and NPTL support variable stack size.
a61af66fc99e Initial load
duke
parents:
diff changeset
635 bool os::Linux::supports_variable_stack_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
636 if (os::Linux::is_NPTL()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // NPTL, yes
a61af66fc99e Initial load
duke
parents:
diff changeset
638 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // Note: We can't control default stack size when creating a thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // If we use non-default stack size (pthread_attr_setstacksize), both
a61af66fc99e Initial load
duke
parents:
diff changeset
643 // floating stack and non-floating stack LinuxThreads will return the
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // same value. This makes it impossible to implement this function by
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // detecting thread stack size directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
646 //
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // An alternative approach is to check %gs. Fixed-stack LinuxThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // do not use %gs, so its value is 0. Floating-stack LinuxThreads use
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // %gs (either as LDT selector or GDT selector, depending on kernel)
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // to access thread specific data.
a61af66fc99e Initial load
duke
parents:
diff changeset
651 //
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // Note that %gs is a reserved glibc register since early 2001, so
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // applications are not allowed to change its value (Ulrich Drepper from
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Redhat confirmed that all known offenders have been modified to use
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // either %fs or TSD). In the worst case scenario, when VM is embedded in
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // a native application that plays with %gs, we might see non-zero %gs
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // even LinuxThreads is running in fixed stack mode. As the result, we'll
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // return true and skip _thread_safety_check(), so we may not be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // detect stack-heap collisions. But otherwise it's harmless.
a61af66fc99e Initial load
duke
parents:
diff changeset
660 //
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
661 #ifdef __GNUC__
0
a61af66fc99e Initial load
duke
parents:
diff changeset
662 return (GET_GS() != 0);
50
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
663 #else
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
664 return false;
485d403e94e1 6452081: 3/4 Allow for Linux builds with Sun Studio Linux compilers
dcubed
parents: 0
diff changeset
665 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
668 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
669
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // return default stack size for thr_type
a61af66fc99e Initial load
duke
parents:
diff changeset
671 size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // default stack size (compiler thread needs larger stack)
a61af66fc99e Initial load
duke
parents:
diff changeset
673 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
674 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
676 size_t s = (thr_type == os::compiler_thread ? 2 * M : 512 * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
677 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
678 return s;
a61af66fc99e Initial load
duke
parents:
diff changeset
679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
680
a61af66fc99e Initial load
duke
parents:
diff changeset
681 size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // Creating guard page is very expensive. Java thread has HotSpot
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // guard page, only enable glibc guard page for non-Java threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
684 return (thr_type == java_thread ? 0 : page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // Java thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
688 //
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // Low memory addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // +------------------------+
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // | |\ JavaThread created by VM does not have glibc
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // | glibc guard page | - guard, attached Java thread usually has
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // | |/ 1 page glibc guard.
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // | |\
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // | HotSpot Guard Pages | - red and yellow pages
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // | |/
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // +------------------------+ JavaThread::stack_yellow_zone_base()
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // | |\
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // | Normal Stack | -
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // | |/
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // P2 +------------------------+ Thread::stack_base()
a61af66fc99e Initial load
duke
parents:
diff changeset
703 //
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // Non-Java thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
705 //
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // Low memory addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // +------------------------+
a61af66fc99e Initial load
duke
parents:
diff changeset
708 // | |\
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // | glibc guard page | - usually 1 page
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // | |/
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
a61af66fc99e Initial load
duke
parents:
diff changeset
712 // | |\
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // | Normal Stack | -
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // | |/
a61af66fc99e Initial load
duke
parents:
diff changeset
715 // P2 +------------------------+ Thread::stack_base()
a61af66fc99e Initial load
duke
parents:
diff changeset
716 //
a61af66fc99e Initial load
duke
parents:
diff changeset
717 // ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // pthread_attr_getstack()
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 static void current_stack_region(address * bottom, size_t * size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (os::Linux::is_initial_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 // initial thread needs special handling because pthread_getattr_np()
a61af66fc99e Initial load
duke
parents:
diff changeset
723 // may return bogus value.
a61af66fc99e Initial load
duke
parents:
diff changeset
724 *bottom = os::Linux::initial_thread_stack_bottom();
a61af66fc99e Initial load
duke
parents:
diff changeset
725 *size = os::Linux::initial_thread_stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
726 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 pthread_attr_t attr;
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 int rslt = pthread_getattr_np(pthread_self(), &attr);
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 // JVM needs to know exact stack location, abort if it fails
a61af66fc99e Initial load
duke
parents:
diff changeset
732 if (rslt != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
733 if (rslt == ENOMEM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 vm_exit_out_of_memory(0, "pthread_getattr_np");
a61af66fc99e Initial load
duke
parents:
diff changeset
735 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 579
diff changeset
736 fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
741 fatal("Can not locate current stack attributes!");
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 pthread_attr_destroy(&attr);
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747 assert(os::current_stack_pointer() >= *bottom &&
a61af66fc99e Initial load
duke
parents:
diff changeset
748 os::current_stack_pointer() < *bottom + *size, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 address os::current_stack_base() {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 address bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 current_stack_region(&bottom, &size);
a61af66fc99e Initial load
duke
parents:
diff changeset
755 return (bottom + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
757
a61af66fc99e Initial load
duke
parents:
diff changeset
758 size_t os::current_stack_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // stack size includes normal stack and HotSpot guard pages
a61af66fc99e Initial load
duke
parents:
diff changeset
760 address bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
762 current_stack_region(&bottom, &size);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 /////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // helper functions for fatal error handler
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769 void os::print_context(outputStream *st, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
770 if (context == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
771
a61af66fc99e Initial load
duke
parents:
diff changeset
772 ucontext_t *uc = (ucontext_t*)context;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 st->print_cr("Registers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
774 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
775 st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
776 st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
777 st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
779 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
780 st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
781 st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
782 st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
783 st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
784 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
785 st->print( "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]);
a61af66fc99e Initial load
duke
parents:
diff changeset
787 st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]);
a61af66fc99e Initial load
duke
parents:
diff changeset
788 st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]);
a61af66fc99e Initial load
duke
parents:
diff changeset
789 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
790 st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]);
a61af66fc99e Initial load
duke
parents:
diff changeset
791 st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]);
a61af66fc99e Initial load
duke
parents:
diff changeset
792 st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]);
a61af66fc99e Initial load
duke
parents:
diff changeset
793 st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
795 st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]);
1907
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
796 st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
797 st->print(", CSGSFS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_CSGSFS]);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 st->print(", ERR=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ERR]);
a61af66fc99e Initial load
duke
parents:
diff changeset
799 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
800 st->print(" TRAPNO=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_TRAPNO]);
a61af66fc99e Initial load
duke
parents:
diff changeset
801 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
802 st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
804 st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
805 st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]);
a61af66fc99e Initial load
duke
parents:
diff changeset
806 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
807 st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_UESP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]);
a61af66fc99e Initial load
duke
parents:
diff changeset
809 st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]);
a61af66fc99e Initial load
duke
parents:
diff changeset
811 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
812 st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]);
1907
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
813 st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
814 st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
816 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
817 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
820 st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
822 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Note: it may be unsafe to inspect memory near pc. For example, pc may
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // point to garbage if entry point in an nmethod is corrupted. Leave
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // this at the end, and hope for the best.
a61af66fc99e Initial load
duke
parents:
diff changeset
827 address pc = os::Linux::ucontext_get_pc(uc);
a61af66fc99e Initial load
duke
parents:
diff changeset
828 st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
1907
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
829 print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
830 }
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
831
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
832 void os::print_register_info(outputStream *st, void *context) {
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
833 if (context == NULL) return;
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
834
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
835 ucontext_t *uc = (ucontext_t*)context;
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
836
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
837 st->print_cr("Register to memory mapping:");
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
838 st->cr();
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
839
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
840 // this is horrendously verbose but the layout of the registers in the
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
841 // context does not match how we defined our abstract Register set, so
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
842 // we can't just iterate through the gregs area
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
843
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
844 // this is only for the "general purpose" registers
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
845
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
846 #ifdef AMD64
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
847 st->print("RAX="); print_location(st, uc->uc_mcontext.gregs[REG_RAX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
848 st->print("RBX="); print_location(st, uc->uc_mcontext.gregs[REG_RBX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
849 st->print("RCX="); print_location(st, uc->uc_mcontext.gregs[REG_RCX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
850 st->print("RDX="); print_location(st, uc->uc_mcontext.gregs[REG_RDX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
851 st->print("RSP="); print_location(st, uc->uc_mcontext.gregs[REG_RSP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
852 st->print("RBP="); print_location(st, uc->uc_mcontext.gregs[REG_RBP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
853 st->print("RSI="); print_location(st, uc->uc_mcontext.gregs[REG_RSI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
854 st->print("RDI="); print_location(st, uc->uc_mcontext.gregs[REG_RDI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
855 st->print("R8 ="); print_location(st, uc->uc_mcontext.gregs[REG_R8]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
856 st->print("R9 ="); print_location(st, uc->uc_mcontext.gregs[REG_R9]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
857 st->print("R10="); print_location(st, uc->uc_mcontext.gregs[REG_R10]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
858 st->print("R11="); print_location(st, uc->uc_mcontext.gregs[REG_R11]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
859 st->print("R12="); print_location(st, uc->uc_mcontext.gregs[REG_R12]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
860 st->print("R13="); print_location(st, uc->uc_mcontext.gregs[REG_R13]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
861 st->print("R14="); print_location(st, uc->uc_mcontext.gregs[REG_R14]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
862 st->print("R15="); print_location(st, uc->uc_mcontext.gregs[REG_R15]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
863 #else
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
864 st->print("EAX="); print_location(st, uc->uc_mcontext.gregs[REG_EAX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
865 st->print("EBX="); print_location(st, uc->uc_mcontext.gregs[REG_EBX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
866 st->print("ECX="); print_location(st, uc->uc_mcontext.gregs[REG_ECX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
867 st->print("EDX="); print_location(st, uc->uc_mcontext.gregs[REG_EDX]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
868 st->print("ESP="); print_location(st, uc->uc_mcontext.gregs[REG_ESP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
869 st->print("EBP="); print_location(st, uc->uc_mcontext.gregs[REG_EBP]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
870 st->print("ESI="); print_location(st, uc->uc_mcontext.gregs[REG_ESI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
871 st->print("EDI="); print_location(st, uc->uc_mcontext.gregs[REG_EDI]);
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
872 #endif // AMD64
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
873
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1681
diff changeset
874 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 void os::setup_fpu() {
a61af66fc99e Initial load
duke
parents:
diff changeset
878 #ifndef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
879 address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std();
a61af66fc99e Initial load
duke
parents:
diff changeset
880 __asm__ volatile ( "fldcw (%0)" :
a61af66fc99e Initial load
duke
parents:
diff changeset
881 : "r" (fpu_cntrl) : "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
882 #endif // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }