src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp

Print this page


   1 /*
   2  * Copyright (c) 1999, 2014, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 235 
 236   if (uc != NULL) {
 237     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
 238     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
 239   } else {
 240     // construct empty ExtendedPC for return value checking
 241     epc = ExtendedPC(NULL);
 242     if (ret_sp) *ret_sp = (intptr_t *)NULL;
 243   }
 244 
 245   return epc;
 246 }
 247 
 248 frame os::fetch_frame_from_context(void* ucVoid) {
 249   intptr_t* sp;
 250   intptr_t* fp;
 251   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
 252   return frame(sp, frame::unpatchable, epc.pc());
 253 }
 254 



































 255 frame os::get_sender_for_C_frame(frame* fr) {
 256   return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
 257 }
 258 
 259 // Returns an estimate of the current stack pointer. Result must be guaranteed to
 260 // point into the calling threads stack, and be no lower than the current stack
 261 // pointer.
 262 address os::current_stack_pointer() {
 263   volatile int dummy;
 264   address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
 265   return sp;
 266 }
 267 
 268 frame os::current_frame() {
 269   intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
 270   frame myframe(sp, frame::unpatchable,
 271                 CAST_FROM_FN_PTR(address, os::current_frame));
 272   if (os::is_first_C_frame(&myframe)) {
 273     // stack is not walkable
 274     return frame(NULL, NULL, false);


 352 
 353   address pc          = NULL;
 354   address npc         = NULL;
 355 
 356   //%note os_trap_1
 357   if (info != NULL && uc != NULL && thread != NULL) {
 358     // factor me: getPCfromContext
 359     pc  = (address) uc->uc_mcontext.gregs[REG_PC];
 360     npc = (address) uc->uc_mcontext.gregs[REG_nPC];
 361 
 362     // SafeFetch() support
 363     if (StubRoutines::is_safefetch_fault(pc)) {
 364       os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
 365       return 1;
 366     }
 367 
 368     // Handle ALL stack overflow variations here
 369     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
 370       address addr = (address) info->si_addr;
 371       if (thread->in_stack_yellow_zone(addr)) {
 372         thread->disable_stack_yellow_zone();
 373         // Sometimes the register windows are not properly flushed.
 374         if(uc->uc_mcontext.gwins != NULL) {
 375           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
 376         }
 377         if (thread->thread_state() == _thread_in_Java) {














 378           // Throw a stack overflow exception.  Guard pages will be reenabled
 379           // while unwinding the stack.

 380           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 381         } else {
 382           // Thread was in the vm or native code.  Return and try to finish.

 383           return true;
 384         }
 385       } else if (thread->in_stack_red_zone(addr)) {
 386         // Fatal red zone violation.  Disable the guard pages and fall through
 387         // to handle_unexpected_exception way down below.
 388         thread->disable_stack_red_zone();
 389         tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
 390         // Sometimes the register windows are not properly flushed.
 391         if(uc->uc_mcontext.gwins != NULL) {
 392           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
 393         }
 394       }
 395     }
 396 
 397 
 398     if (thread->thread_state() == _thread_in_vm) {
 399       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
 400         stub = StubRoutines::handler_for_unsafe_access();
 401       }
 402     }


   1 /*
   2  * Copyright (c) 1999, 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 235 
 236   if (uc != NULL) {
 237     epc = os::Solaris::ucontext_get_ExtendedPC(uc);
 238     if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
 239   } else {
 240     // construct empty ExtendedPC for return value checking
 241     epc = ExtendedPC(NULL);
 242     if (ret_sp) *ret_sp = (intptr_t *)NULL;
 243   }
 244 
 245   return epc;
 246 }
 247 
 248 frame os::fetch_frame_from_context(void* ucVoid) {
 249   intptr_t* sp;
 250   intptr_t* fp;
 251   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
 252   return frame(sp, frame::unpatchable, epc.pc());
 253 }
 254 
 255 frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
 256   intptr_t* sp;
 257   ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, NULL);
 258   return frame(sp, frame::unpatchable, epc.pc());
 259 }
 260 
 261 bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
 262   address pc = (address) os::Solaris::ucontext_get_pc(uc);
 263   if (Interpreter::contains(pc)) {
 264     *fr = os::fetch_frame_from_ucontext(thread, uc);
 265     assert(fr->safe_for_sender(thread), "Safety check");
 266     if (!fr->is_first_java_frame()) {
 267       *fr = fr->java_sender();
 268     }
 269   } else {
 270     // more complex code with compiled code
 271     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
 272     CodeBlob* cb = CodeCache::find_blob(pc);
 273     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
 274       // Not sure where the pc points to, fallback to default 
 275       // stack overflow handling
 276       return false;
 277     } else {
 278       *fr = os::fetch_frame_from_ucontext(thread, uc);
 279       //assert(fr->safe_for_sender(thread), "Safety check");
 280       *fr = frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
 281       if (!fr->is_java_frame()) {
 282         assert(fr->safe_for_sender(thread), "Safety check");
 283         *fr = fr->java_sender();
 284       }
 285     }
 286   }
 287   return true;
 288 }
 289 
 290 frame os::get_sender_for_C_frame(frame* fr) {
 291   return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
 292 }
 293 
 294 // Returns an estimate of the current stack pointer. Result must be guaranteed to
 295 // point into the calling threads stack, and be no lower than the current stack
 296 // pointer.
 297 address os::current_stack_pointer() {
 298   volatile int dummy;
 299   address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
 300   return sp;
 301 }
 302 
 303 frame os::current_frame() {
 304   intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
 305   frame myframe(sp, frame::unpatchable,
 306                 CAST_FROM_FN_PTR(address, os::current_frame));
 307   if (os::is_first_C_frame(&myframe)) {
 308     // stack is not walkable
 309     return frame(NULL, NULL, false);


 387 
 388   address pc          = NULL;
 389   address npc         = NULL;
 390 
 391   //%note os_trap_1
 392   if (info != NULL && uc != NULL && thread != NULL) {
 393     // factor me: getPCfromContext
 394     pc  = (address) uc->uc_mcontext.gregs[REG_PC];
 395     npc = (address) uc->uc_mcontext.gregs[REG_nPC];
 396 
 397     // SafeFetch() support
 398     if (StubRoutines::is_safefetch_fault(pc)) {
 399       os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
 400       return 1;
 401     }
 402 
 403     // Handle ALL stack overflow variations here
 404     if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
 405       address addr = (address) info->si_addr;
 406       if (thread->in_stack_yellow_zone(addr)) {

 407         // Sometimes the register windows are not properly flushed.
 408         if(uc->uc_mcontext.gwins != NULL) {
 409           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
 410         }
 411         if (thread->thread_state() == _thread_in_Java) {
 412           if (thread->in_stack_reserved_zone(addr)) {
 413             frame fr;
 414             if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) {
 415               assert(fr.is_java_frame(), "Must be a Java frame");
 416               frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
 417               if (activation.sp() != NULL) {
 418                 thread->disable_stack_reserved_zone();
 419                 RegisterMap map(thread);
 420                 int frame_size = activation.frame_size(&map);
 421                 thread->set_reserved_stack_activation((intptr_t*)(((address)activation.sp()) - STACK_BIAS));
 422                 return true;
 423               }
 424             }
 425           }
 426           // Throw a stack overflow exception.  Guard pages will be reenabled
 427           // while unwinding the stack.
 428           thread->disable_stack_yellow_zone();
 429           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
 430         } else {
 431           // Thread was in the vm or native code.  Return and try to finish.
 432           thread->disable_stack_yellow_zone();
 433           return true;
 434         }
 435       } else if (thread->in_stack_red_zone(addr)) {
 436         // Fatal red zone violation.  Disable the guard pages and fall through
 437         // to handle_unexpected_exception way down below.
 438         thread->disable_stack_red_zone();
 439         tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
 440         // Sometimes the register windows are not properly flushed.
 441         if(uc->uc_mcontext.gwins != NULL) {
 442           ::handle_unflushed_register_windows(uc->uc_mcontext.gwins);
 443         }
 444       }
 445     }
 446 
 447 
 448     if (thread->thread_state() == _thread_in_vm) {
 449       if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
 450         stub = StubRoutines::handler_for_unsafe_access();
 451       }
 452     }