src/cpu/x86/vm/frame_x86.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8068945-8u-patched Sdiff src/cpu/x86/vm

src/cpu/x86/vm/frame_x86.hpp

Print this page
rev 7386 : 8068945: Use RBP register as proper frame pointer in JIT compiled code on x86
Summary: Introduce the PreserveFramePointer flag to control if RBP is used as the frame pointer or as a general purpose register.
Reviewed-by: kvn, roland, dlong, enevill, shade


  59 // Layout of C++ interpreter frame: (While executing in BytecodeInterpreter::run)
  60 //
  61 //                             <- SP (current esp/rsp)
  62 //    [local variables         ] BytecodeInterpreter::run local variables
  63 //    ...                        BytecodeInterpreter::run local variables
  64 //    [local variables         ] BytecodeInterpreter::run local variables
  65 //    [old frame pointer       ]   fp [ BytecodeInterpreter::run's ebp/rbp ]
  66 //    [return pc               ]  (return to frame manager)
  67 //    [interpreter_state*      ]  (arg to BytecodeInterpreter::run)   --------------
  68 //    [expression stack        ] <- last_Java_sp                           |
  69 //    [...                     ] * <- interpreter_state.stack              |
  70 //    [expression stack        ] * <- interpreter_state.stack_base         |
  71 //    [monitors                ]   \                                       |
  72 //     ...                          | monitor block size                   |
  73 //    [monitors                ]   / <- interpreter_state.monitor_base     |
  74 //    [struct interpretState   ] <-----------------------------------------|
  75 //    [return pc               ] (return to callee of frame manager [1]
  76 //    [locals and parameters   ]
  77 //                               <- sender sp
  78 
  79 // [1] When the c++ interpreter calls a new method it returns to the frame
  80 //     manager which allocates a new frame on the stack. In that case there
  81 //     is no real callee of this newly allocated frame. The frame manager is
  82 //     aware of the  additional frame(s) and will pop them as nested calls
  83 //     complete. Howevers tTo make it look good in the debugger the frame
  84 //     manager actually installs a dummy pc pointing to RecursiveInterpreterActivation
  85 //     with a fake interpreter_state* parameter to make it easy to debug
  86 //     nested calls.
  87 
  88 // Note that contrary to the layout for the assembly interpreter the
  89 // expression stack allocated for the C++ interpreter is full sized.
  90 // However this is not as bad as it seems as the interpreter frame_manager
  91 // will truncate the unused space on succesive method calls.
  92 //
  93 // ------------------------------ C++ interpreter ----------------------------------------
  94 
  95  public:
  96   enum {
  97     pc_return_offset                                 =  0,
  98     // All frames
  99     link_offset                                      =  0,
 100     return_addr_offset                               =  1,
 101     // non-interpreter frames
 102     sender_sp_offset                                 =  2,
 103 
 104 #ifndef CC_INTERP
 105 
 106     // Interpreter frames
 107     interpreter_frame_result_handler_offset          =  3, // for native calls only
 108     interpreter_frame_oop_temp_offset                =  2, // for native calls only
 109 
 110     interpreter_frame_sender_sp_offset               = -1,
 111     // outgoing sp before a call to an invoked method


 155 
 156  private:
 157   // an additional field beyond _sp and _pc:
 158   intptr_t*   _fp; // frame pointer
 159   // The interpreter and adapters will extend the frame of the caller.
 160   // Since oopMaps are based on the sp of the caller before extension
 161   // we need to know that value. However in order to compute the address
 162   // of the return address we need the real "raw" sp. Since sparc already
 163   // uses sp() to mean "raw" sp and unextended_sp() to mean the caller's
 164   // original sp we use that convention.
 165 
 166   intptr_t*     _unextended_sp;
 167   void adjust_unextended_sp();
 168 
 169   intptr_t* ptr_at_addr(int offset) const {
 170     return (intptr_t*) addr_at(offset);
 171   }
 172 
 173 #ifdef ASSERT
 174   // Used in frame::sender_for_{interpreter,compiled}_frame
 175   static void verify_deopt_original_pc(   nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
 176   static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
 177     verify_deopt_original_pc(nm, unextended_sp, true);
 178   }
 179 #endif
 180 
 181  public:
 182   // Constructors
 183 
 184   frame(intptr_t* sp, intptr_t* fp, address pc);
 185 
 186   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
 187 
 188   frame(intptr_t* sp, intptr_t* fp);
 189 
 190   void init(intptr_t* sp, intptr_t* fp, address pc);
 191 
 192   // accessors for the instance variables
 193   // Note: not necessarily the real 'frame pointer' (see real_fp)
 194   intptr_t*   fp() const { return _fp; }
 195 
 196   inline address* sender_pc_addr() const;
 197 
 198   // return address of param, zero origin index.


  59 // Layout of C++ interpreter frame: (While executing in BytecodeInterpreter::run)
  60 //
  61 //                             <- SP (current esp/rsp)
  62 //    [local variables         ] BytecodeInterpreter::run local variables
  63 //    ...                        BytecodeInterpreter::run local variables
  64 //    [local variables         ] BytecodeInterpreter::run local variables
  65 //    [old frame pointer       ]   fp [ BytecodeInterpreter::run's ebp/rbp ]
  66 //    [return pc               ]  (return to frame manager)
  67 //    [interpreter_state*      ]  (arg to BytecodeInterpreter::run)   --------------
  68 //    [expression stack        ] <- last_Java_sp                           |
  69 //    [...                     ] * <- interpreter_state.stack              |
  70 //    [expression stack        ] * <- interpreter_state.stack_base         |
  71 //    [monitors                ]   \                                       |
  72 //     ...                          | monitor block size                   |
  73 //    [monitors                ]   / <- interpreter_state.monitor_base     |
  74 //    [struct interpretState   ] <-----------------------------------------|
  75 //    [return pc               ] (return to callee of frame manager [1]
  76 //    [locals and parameters   ]
  77 //                               <- sender sp
  78 
  79 // [1] When the C++ interpreter calls a new method it returns to the frame
  80 //     manager which allocates a new frame on the stack. In that case there
  81 //     is no real callee of this newly allocated frame. The frame manager is
  82 //     aware of the additional frame(s) and will pop them as nested calls
  83 //     complete. However, to make it look good in the debugger the frame
  84 //     manager actually installs a dummy pc pointing to RecursiveInterpreterActivation
  85 //     with a fake interpreter_state* parameter to make it easy to debug
  86 //     nested calls.
  87 
  88 // Note that contrary to the layout for the assembly interpreter the
  89 // expression stack allocated for the C++ interpreter is full sized.
  90 // However this is not as bad as it seems as the interpreter frame_manager
  91 // will truncate the unused space on successive method calls.
  92 //
  93 // ------------------------------ C++ interpreter ----------------------------------------
  94 
  95  public:
  96   enum {
  97     pc_return_offset                                 =  0,
  98     // All frames
  99     link_offset                                      =  0,
 100     return_addr_offset                               =  1,
 101     // non-interpreter frames
 102     sender_sp_offset                                 =  2,
 103 
 104 #ifndef CC_INTERP
 105 
 106     // Interpreter frames
 107     interpreter_frame_result_handler_offset          =  3, // for native calls only
 108     interpreter_frame_oop_temp_offset                =  2, // for native calls only
 109 
 110     interpreter_frame_sender_sp_offset               = -1,
 111     // outgoing sp before a call to an invoked method


 155 
 156  private:
 157   // an additional field beyond _sp and _pc:
 158   intptr_t*   _fp; // frame pointer
 159   // The interpreter and adapters will extend the frame of the caller.
 160   // Since oopMaps are based on the sp of the caller before extension
 161   // we need to know that value. However in order to compute the address
 162   // of the return address we need the real "raw" sp. Since sparc already
 163   // uses sp() to mean "raw" sp and unextended_sp() to mean the caller's
 164   // original sp we use that convention.
 165 
 166   intptr_t*     _unextended_sp;
 167   void adjust_unextended_sp();
 168 
 169   intptr_t* ptr_at_addr(int offset) const {
 170     return (intptr_t*) addr_at(offset);
 171   }
 172 
 173 #ifdef ASSERT
 174   // Used in frame::sender_for_{interpreter,compiled}_frame
 175   static void verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp);



 176 #endif
 177 
 178  public:
 179   // Constructors
 180 
 181   frame(intptr_t* sp, intptr_t* fp, address pc);
 182 
 183   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
 184 
 185   frame(intptr_t* sp, intptr_t* fp);
 186 
 187   void init(intptr_t* sp, intptr_t* fp, address pc);
 188 
 189   // accessors for the instance variables
 190   // Note: not necessarily the real 'frame pointer' (see real_fp)
 191   intptr_t*   fp() const { return _fp; }
 192 
 193   inline address* sender_pc_addr() const;
 194 
 195   // return address of param, zero origin index.
src/cpu/x86/vm/frame_x86.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File