hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp
changeset 43680 dd3ea9044937
parent 43292 220ab62f260a
parent 43443 f444a6847614
child 46644 a5813fb66270
equal deleted inserted replaced
43379:f4aff695ffe0 43680:dd3ea9044937
    85 #define REG_FP REG_RBP
    85 #define REG_FP REG_RBP
    86 #define SPELL_REG_SP "rsp"
    86 #define SPELL_REG_SP "rsp"
    87 #define SPELL_REG_FP "rbp"
    87 #define SPELL_REG_FP "rbp"
    88 #else
    88 #else
    89 #define REG_FP 29
    89 #define REG_FP 29
       
    90 #define REG_LR 30
    90 
    91 
    91 #define SPELL_REG_SP "sp"
    92 #define SPELL_REG_SP "sp"
    92 #define SPELL_REG_FP "x29"
    93 #define SPELL_REG_FP "x29"
    93 #endif
    94 #endif
    94 
    95 
   178 frame os::fetch_frame_from_context(const void* ucVoid) {
   179 frame os::fetch_frame_from_context(const void* ucVoid) {
   179   intptr_t* sp;
   180   intptr_t* sp;
   180   intptr_t* fp;
   181   intptr_t* fp;
   181   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   182   ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
   182   return frame(sp, fp, epc.pc());
   183   return frame(sp, fp, epc.pc());
       
   184 }
       
   185 
       
   186 bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
       
   187   address pc = (address) os::Linux::ucontext_get_pc(uc);
       
   188   if (Interpreter::contains(pc)) {
       
   189     // interpreter performs stack banging after the fixed frame header has
       
   190     // been generated while the compilers perform it before. To maintain
       
   191     // semantic consistency between interpreted and compiled frames, the
       
   192     // method returns the Java sender of the current frame.
       
   193     *fr = os::fetch_frame_from_context(uc);
       
   194     if (!fr->is_first_java_frame()) {
       
   195       assert(fr->safe_for_sender(thread), "Safety check");
       
   196       *fr = fr->java_sender();
       
   197     }
       
   198   } else {
       
   199     // more complex code with compiled code
       
   200     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
       
   201     CodeBlob* cb = CodeCache::find_blob(pc);
       
   202     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
       
   203       // Not sure where the pc points to, fallback to default
       
   204       // stack overflow handling
       
   205       return false;
       
   206     } else {
       
   207       // In compiled code, the stack banging is performed before LR
       
   208       // has been saved in the frame.  LR is live, and SP and FP
       
   209       // belong to the caller.
       
   210       intptr_t* fp = os::Linux::ucontext_get_fp(uc);
       
   211       intptr_t* sp = os::Linux::ucontext_get_sp(uc);
       
   212       address pc = (address)(uc->uc_mcontext.regs[REG_LR]
       
   213                          - NativeInstruction::instruction_size);
       
   214       *fr = frame(sp, fp, pc);
       
   215       if (!fr->is_java_frame()) {
       
   216         assert(fr->safe_for_sender(thread), "Safety check");
       
   217         assert(!fr->is_first_frame(), "Safety check");
       
   218         *fr = fr->java_sender();
       
   219       }
       
   220     }
       
   221   }
       
   222   assert(fr->is_java_frame(), "Safety check");
       
   223   return true;
   183 }
   224 }
   184 
   225 
   185 // By default, gcc always saves frame pointer rfp on this stack. This
   226 // By default, gcc always saves frame pointer rfp on this stack. This
   186 // may get turned off by -fomit-frame-pointer.
   227 // may get turned off by -fomit-frame-pointer.
   187 frame os::get_sender_for_C_frame(frame* fr) {
   228 frame os::get_sender_for_C_frame(frame* fr) {
   311       if (thread->on_local_stack(addr)) {
   352       if (thread->on_local_stack(addr)) {
   312         // stack overflow
   353         // stack overflow
   313         if (thread->in_stack_yellow_reserved_zone(addr)) {
   354         if (thread->in_stack_yellow_reserved_zone(addr)) {
   314           thread->disable_stack_yellow_reserved_zone();
   355           thread->disable_stack_yellow_reserved_zone();
   315           if (thread->thread_state() == _thread_in_Java) {
   356           if (thread->thread_state() == _thread_in_Java) {
       
   357             if (thread->in_stack_reserved_zone(addr)) {
       
   358               frame fr;
       
   359               if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) {
       
   360                 assert(fr.is_java_frame(), "Must be a Java frame");
       
   361                 frame activation =
       
   362                   SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
       
   363                 if (activation.sp() != NULL) {
       
   364                   thread->disable_stack_reserved_zone();
       
   365                   if (activation.is_interpreted_frame()) {
       
   366                     thread->set_reserved_stack_activation((address)(
       
   367                       activation.fp() + frame::interpreter_frame_initial_sp_offset));
       
   368                   } else {
       
   369                     thread->set_reserved_stack_activation((address)activation.unextended_sp());
       
   370                   }
       
   371                   return 1;
       
   372                 }
       
   373               }
       
   374             }
   316             // Throw a stack overflow exception.  Guard pages will be reenabled
   375             // Throw a stack overflow exception.  Guard pages will be reenabled
   317             // while unwinding the stack.
   376             // while unwinding the stack.
   318             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
   377             stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
   319           } else {
   378           } else {
   320             // Thread was in the vm or native code.  Return and try to finish.
   379             // Thread was in the vm or native code.  Return and try to finish.