1 #ifdef USE_PRAGMA_IDENT_SRC
2 #pragma ident "@(#)os_solaris_x86.cpp 1.122 07/09/17 09:16:14 JVM"
3 #endif
4 /*
5 * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
189 // construct empty ExtendedPC for return value checking
190 epc = ExtendedPC(NULL);
191 if (ret_sp) *ret_sp = (intptr_t *)NULL;
192 if (ret_fp) *ret_fp = (intptr_t *)NULL;
193 }
194
195 return epc;
196 }
197
198 frame os::fetch_frame_from_context(void* ucVoid) {
199 intptr_t* sp;
200 intptr_t* fp;
201 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
202 return frame(sp, fp, epc.pc());
203 }
204
205 frame os::get_sender_for_C_frame(frame* fr) {
206 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
207 }
208
209 extern "C" intptr_t *_get_previous_fp(); // in .il file.
210
211 frame os::current_frame() {
212 intptr_t* fp = _get_previous_fp();
213 frame myframe((intptr_t*)os::current_stack_pointer(),
214 (intptr_t*)fp,
215 CAST_FROM_FN_PTR(address, os::current_frame));
216 if (os::is_first_C_frame(&myframe)) {
217 // stack is not walkable
218 return frame(NULL, NULL, NULL);
219 } else {
220 return os::get_sender_for_C_frame(&myframe);
221 }
222 }
223
224 // This is a simple callback that just fetches a PC for an interrupted thread.
225 // The thread need not be suspended and the fetched PC is just a hint.
226 // This one is currently used for profiling the VMThread ONLY!
227
228 // Must be synchronous
229 void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
230 Thread* thread = args->thread();
231 ucontext_t* uc = args->ucontext();
232 intptr_t* sp;
233
234 assert(ProfileVM && thread->is_VM_thread(), "just checking");
235
236 ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
237 _addr = new_addr;
238 }
561 // If an instruction spans a page boundary, and the page containing
562 // the beginning of the instruction is executable but the following
563 // page is not, the pc and the faulting address might be slightly
564 // different - we still want to unguard the 2nd page in this case.
565 //
566 // 15 bytes seems to be a (very) safe value for max instruction size.
567 bool pc_is_near_addr =
568 (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
569 bool instr_spans_page_boundary =
570 (align_size_down((intptr_t) pc ^ (intptr_t) addr,
571 (intptr_t) page_size) > 0);
572
573 if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
574 static volatile address last_addr =
575 (address) os::non_memory_address_word();
576
577 // In conservative mode, don't unguard unless the address is in the VM
578 if (addr != last_addr &&
579 (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
580
581 // Unguard and retry
582 address page_start =
583 (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
584 bool res = os::unguard_memory((char*) page_start, page_size);
585
586 if (PrintMiscellaneous && Verbose) {
587 char buf[256];
588 jio_snprintf(buf, sizeof(buf), "Execution protection violation "
589 "at " INTPTR_FORMAT
590 ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
591 page_start, (res ? "success" : "failed"), errno);
592 tty->print_raw_cr(buf);
593 }
594 stub = pc;
595
596 // Set last_addr so if we fault again at the same address, we don't end
597 // up in an endless loop.
598 //
599 // There are two potential complications here. Two threads trapping at
600 // the same address at the same time could cause one of the threads to
601 // think it already unguarded, and abort the VM. Likely very rare.
602 //
603 // The other race involves two threads alternately trapping at
604 // different addresses and failing to unguard the page, resulting in
862 (*func)();
863 return;
864 }
865 assert(Threads::number_of_threads() == 0, "for bootstrap only");
866
867 // don't have to do anything for a single thread
868 }
869
870 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap;
871 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap;
872 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
873 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap;
874 fence_func_t* os::fence_func = os::fence_bootstrap;
875
876 extern "C" _solaris_raw_setup_fpu(address ptr);
877 void os::setup_fpu() {
878 address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std();
879 _solaris_raw_setup_fpu(fpu_cntrl);
880 }
881 #endif // AMD64
882
|
1 /*
2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
186 // construct empty ExtendedPC for return value checking
187 epc = ExtendedPC(NULL);
188 if (ret_sp) *ret_sp = (intptr_t *)NULL;
189 if (ret_fp) *ret_fp = (intptr_t *)NULL;
190 }
191
192 return epc;
193 }
194
195 frame os::fetch_frame_from_context(void* ucVoid) {
196 intptr_t* sp;
197 intptr_t* fp;
198 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
199 return frame(sp, fp, epc.pc());
200 }
201
202 frame os::get_sender_for_C_frame(frame* fr) {
203 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
204 }
205
206 extern "C" intptr_t *_get_current_fp(); // in .il file
207
208 frame os::current_frame() {
209 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
210 frame myframe((intptr_t*)os::current_stack_pointer(),
211 (intptr_t*)fp,
212 CAST_FROM_FN_PTR(address, os::current_frame));
213 if (os::is_first_C_frame(&myframe)) {
214 // stack is not walkable
215 frame ret; // This will be a null useless frame
216 return ret;
217 } else {
218 return os::get_sender_for_C_frame(&myframe);
219 }
220 }
221
222 // This is a simple callback that just fetches a PC for an interrupted thread.
223 // The thread need not be suspended and the fetched PC is just a hint.
224 // This one is currently used for profiling the VMThread ONLY!
225
226 // Must be synchronous
227 void GetThreadPC_Callback::execute(OSThread::InterruptArguments *args) {
228 Thread* thread = args->thread();
229 ucontext_t* uc = args->ucontext();
230 intptr_t* sp;
231
232 assert(ProfileVM && thread->is_VM_thread(), "just checking");
233
234 ExtendedPC new_addr((address)uc->uc_mcontext.gregs[REG_PC]);
235 _addr = new_addr;
236 }
559 // If an instruction spans a page boundary, and the page containing
560 // the beginning of the instruction is executable but the following
561 // page is not, the pc and the faulting address might be slightly
562 // different - we still want to unguard the 2nd page in this case.
563 //
564 // 15 bytes seems to be a (very) safe value for max instruction size.
565 bool pc_is_near_addr =
566 (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15);
567 bool instr_spans_page_boundary =
568 (align_size_down((intptr_t) pc ^ (intptr_t) addr,
569 (intptr_t) page_size) > 0);
570
571 if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) {
572 static volatile address last_addr =
573 (address) os::non_memory_address_word();
574
575 // In conservative mode, don't unguard unless the address is in the VM
576 if (addr != last_addr &&
577 (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) {
578
579 // Make memory rwx and retry
580 address page_start =
581 (address) align_size_down((intptr_t) addr, (intptr_t) page_size);
582 bool res = os::protect_memory((char*) page_start, page_size,
583 os::MEM_PROT_RWX);
584
585 if (PrintMiscellaneous && Verbose) {
586 char buf[256];
587 jio_snprintf(buf, sizeof(buf), "Execution protection violation "
588 "at " INTPTR_FORMAT
589 ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr,
590 page_start, (res ? "success" : "failed"), errno);
591 tty->print_raw_cr(buf);
592 }
593 stub = pc;
594
595 // Set last_addr so if we fault again at the same address, we don't end
596 // up in an endless loop.
597 //
598 // There are two potential complications here. Two threads trapping at
599 // the same address at the same time could cause one of the threads to
600 // think it already unguarded, and abort the VM. Likely very rare.
601 //
602 // The other race involves two threads alternately trapping at
603 // different addresses and failing to unguard the page, resulting in
861 (*func)();
862 return;
863 }
864 assert(Threads::number_of_threads() == 0, "for bootstrap only");
865
866 // don't have to do anything for a single thread
867 }
868
869 xchg_func_t* os::atomic_xchg_func = os::atomic_xchg_bootstrap;
870 cmpxchg_func_t* os::atomic_cmpxchg_func = os::atomic_cmpxchg_bootstrap;
871 cmpxchg_long_func_t* os::atomic_cmpxchg_long_func = os::atomic_cmpxchg_long_bootstrap;
872 add_func_t* os::atomic_add_func = os::atomic_add_bootstrap;
873 fence_func_t* os::fence_func = os::fence_bootstrap;
874
875 extern "C" _solaris_raw_setup_fpu(address ptr);
876 void os::setup_fpu() {
877 address fpu_cntrl = StubRoutines::addr_fpu_cntrl_wrd_std();
878 _solaris_raw_setup_fpu(fpu_cntrl);
879 }
880 #endif // AMD64
|