< prev index next >

src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp

Print this page
rev 48556 : 8196401: PPC64+s390: get_frame_at_stack_banging_point uses wrong PC
Reviewed-by: stuefe
   1 /*
   2  * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *


  91   // Must never look like an address returned by reserve_memory,
  92   // even in its subfields (as defined by the CPU immediate fields,
  93   // if the CPU splits constants across multiple instructions).
  94   return (char*) -1;
  95 }
  96 
  97 // OS specific thread initialization.
  98 void os::initialize_thread(Thread* thread) { }
  99 
 100 // Frame information (pc, sp, fp) retrieved via ucontext
 101 // always looks like a C-frame according to the frame
 102 // conventions in frame_s390.hpp.
 103 address os::Linux::ucontext_get_pc(const ucontext_t * uc) {
 104   return (address)uc->uc_mcontext.psw.addr;
 105 }
 106 
 107 void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) {
 108   uc->uc_mcontext.psw.addr = (unsigned long)pc;
 109 }
 110 




 111 intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) {
 112   return (intptr_t*)uc->uc_mcontext.gregs[15/*REG_SP*/];
 113 }
 114 
 115 intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) {
 116   return NULL;
 117 }
 118 
 119 ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
 120                     intptr_t** ret_sp, intptr_t** ret_fp) {
 121 
 122   ExtendedPC  epc;
 123   const ucontext_t* uc = (const ucontext_t*)ucVoid;
 124 
 125   if (uc != NULL) {
 126     epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
 127     if (ret_sp) { *ret_sp = os::Linux::ucontext_get_sp(uc); }
 128     if (ret_fp) { *ret_fp = os::Linux::ucontext_get_fp(uc); }
 129   } else {
 130     // Construct empty ExtendedPC for return value checking.


 148   if (Interpreter::contains(pc)) {
 149     // Interpreter performs stack banging after the fixed frame header has
 150     // been generated while the compilers perform it before. To maintain
 151     // semantic consistency between interpreted and compiled frames, the
 152     // method returns the Java sender of the current frame.
 153     *fr = os::fetch_frame_from_context(uc);
 154     if (!fr->is_first_java_frame()) {
 155       assert(fr->safe_for_sender(thread), "Safety check");
 156       *fr = fr->java_sender();
 157     }
 158   } else {
 159     // More complex code with compiled code.
 160     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
 161     CodeBlob* cb = CodeCache::find_blob(pc);
 162     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
 163       // Not sure where the pc points to, fallback to default
 164       // stack overflow handling. In compiled code, we bang before
 165       // the frame is complete.
 166       return false;
 167     } else {
 168       intptr_t* fp = os::Linux::ucontext_get_fp(uc);
 169       intptr_t* sp = os::Linux::ucontext_get_sp(uc);
 170       *fr = frame(sp, (address)*sp);

 171       if (!fr->is_java_frame()) {
 172         assert(fr->safe_for_sender(thread), "Safety check");
 173         assert(!fr->is_first_frame(), "Safety check");
 174         *fr = fr->java_sender();
 175       }
 176     }
 177   }
 178   assert(fr->is_java_frame(), "Safety check");
 179   return true;
 180 }
 181 
 182 frame os::get_sender_for_C_frame(frame* fr) {
 183   if (*fr->sp() == 0) {
 184     // fr is the last C frame.
 185     return frame();
 186   }
 187 
 188   // If its not one of our frames, the return pc is saved at gpr14
 189   // stack slot. The call_stub stores the return_pc to the stack slot
 190   // of gpr10.


   1 /*
   2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *


  91   // Must never look like an address returned by reserve_memory,
  92   // even in its subfields (as defined by the CPU immediate fields,
  93   // if the CPU splits constants across multiple instructions).
  94   return (char*) -1;
  95 }
  96 
  97 // OS specific thread initialization.
  98 void os::initialize_thread(Thread* thread) { }
  99 
 100 // Frame information (pc, sp, fp) retrieved via ucontext
 101 // always looks like a C-frame according to the frame
 102 // conventions in frame_s390.hpp.
 103 address os::Linux::ucontext_get_pc(const ucontext_t * uc) {
 104   return (address)uc->uc_mcontext.psw.addr;
 105 }
 106 
 107 void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) {
 108   uc->uc_mcontext.psw.addr = (unsigned long)pc;
 109 }
 110 
 111 static address ucontext_get_lr(const ucontext_t * uc) {
 112   return (address)uc->uc_mcontext.gregs[14/*LINK*/];
 113 }
 114 
 115 intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) {
 116   return (intptr_t*)uc->uc_mcontext.gregs[15/*REG_SP*/];
 117 }
 118 
 119 intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) {
 120   return NULL;
 121 }
 122 
 123 ExtendedPC os::fetch_frame_from_context(const void* ucVoid,
 124                     intptr_t** ret_sp, intptr_t** ret_fp) {
 125 
 126   ExtendedPC  epc;
 127   const ucontext_t* uc = (const ucontext_t*)ucVoid;
 128 
 129   if (uc != NULL) {
 130     epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
 131     if (ret_sp) { *ret_sp = os::Linux::ucontext_get_sp(uc); }
 132     if (ret_fp) { *ret_fp = os::Linux::ucontext_get_fp(uc); }
 133   } else {
 134     // Construct empty ExtendedPC for return value checking.


 152   if (Interpreter::contains(pc)) {
 153     // Interpreter performs stack banging after the fixed frame header has
 154     // been generated while the compilers perform it before. To maintain
 155     // semantic consistency between interpreted and compiled frames, the
 156     // method returns the Java sender of the current frame.
 157     *fr = os::fetch_frame_from_context(uc);
 158     if (!fr->is_first_java_frame()) {
 159       assert(fr->safe_for_sender(thread), "Safety check");
 160       *fr = fr->java_sender();
 161     }
 162   } else {
 163     // More complex code with compiled code.
 164     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
 165     CodeBlob* cb = CodeCache::find_blob(pc);
 166     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
 167       // Not sure where the pc points to, fallback to default
 168       // stack overflow handling. In compiled code, we bang before
 169       // the frame is complete.
 170       return false;
 171     } else {

 172       intptr_t* sp = os::Linux::ucontext_get_sp(uc);
 173       address lr = ucontext_get_lr(uc);
 174       *fr = frame(sp, lr);
 175       if (!fr->is_java_frame()) {
 176         assert(fr->safe_for_sender(thread), "Safety check");
 177         assert(!fr->is_first_frame(), "Safety check");
 178         *fr = fr->java_sender();
 179       }
 180     }
 181   }
 182   assert(fr->is_java_frame(), "Safety check");
 183   return true;
 184 }
 185 
 186 frame os::get_sender_for_C_frame(frame* fr) {
 187   if (*fr->sp() == 0) {
 188     // fr is the last C frame.
 189     return frame();
 190   }
 191 
 192   // If its not one of our frames, the return pc is saved at gpr14
 193   // stack slot. The call_stub stores the return_pc to the stack slot
 194   // of gpr10.


< prev index next >