hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp

Print this page
rev 611 : Merge
   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