1 /*
  2  * Copyright (c) 1997, 2024, 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  *
 23  */
 24 
 25 #ifndef CPU_X86_FRAME_X86_HPP
 26 #define CPU_X86_FRAME_X86_HPP
 27 
 28 // A frame represents a physical stack frame (an activation).  Frames can be
 29 // C or Java frames, and the Java frames can be interpreted or compiled.
 30 // In contrast, vframes represent source-level activations, so that one physical frame
 31 // can correspond to multiple source level frames because of inlining.
 32 // A frame is comprised of {pc, fp, sp}
 33 // ------------------------------ Asm interpreter ----------------------------------------
 34 // Layout of asm interpreter frame:
 35 //    [expression stack      ] * <- sp
 36 //    [monitors              ]   \
 37 //     ...                        | monitor block size
 38 //    [monitors              ]   /
 39 //    [monitor block size    ]
 40 //    [byte code pointer     ]                   = bcp()                bcp_offset
 41 //    [pointer to locals     ]                   = locals()             locals_offset
 42 //    [constant pool cache   ]                   = cache()              cache_offset
 43 //    [methodData            ]                   = mdp()                mdx_offset
 44 //    [klass of method       ]                   = mirror()             mirror_offset
 45 //    [Method*               ]                   = method()             method_offset
 46 //    [last sp               ]                   = last_sp()            last_sp_offset
 47 //    [old stack pointer     ]                     (sender_sp)          sender_sp_offset
 48 //    [old frame pointer     ]   <- fp           = link()
 49 //    [return pc             ]
 50 //    [oop temp              ]                     (only for native calls)
 51 //    [locals and parameters ]
 52 //                               <- sender sp
 53 // ------------------------------ Asm interpreter ----------------------------------------
 54 
 55  public:
 56   enum {
 57     pc_return_offset                                 =  0,
 58     // All frames
 59     link_offset                                      =  0,
 60     return_addr_offset                               =  1,
 61     // non-interpreter frames
 62     sender_sp_offset                                 =  2,
 63 
 64     // Interpreter frames
 65     interpreter_frame_result_handler_offset          =  3, // for native calls only
 66     interpreter_frame_oop_temp_offset                =  2, // for native calls only
 67 
 68     interpreter_frame_sender_sp_offset               = -1,
 69     // outgoing sp before a call to an invoked method
 70     interpreter_frame_last_sp_offset                 = interpreter_frame_sender_sp_offset - 1,
 71     interpreter_frame_method_offset                  = interpreter_frame_last_sp_offset - 1,
 72     interpreter_frame_mirror_offset                  = interpreter_frame_method_offset - 1,
 73     interpreter_frame_mdp_offset                     = interpreter_frame_mirror_offset - 1,
 74     interpreter_frame_cache_offset                   = interpreter_frame_mdp_offset - 1,
 75     interpreter_frame_locals_offset                  = interpreter_frame_cache_offset - 1,
 76     interpreter_frame_bcp_offset                     = interpreter_frame_locals_offset - 1,
 77     interpreter_frame_initial_sp_offset              = interpreter_frame_bcp_offset - 1,
 78 
 79     interpreter_frame_monitor_block_top_offset       = interpreter_frame_initial_sp_offset,
 80     interpreter_frame_monitor_block_bottom_offset    = interpreter_frame_initial_sp_offset,
 81 
 82     // Entry frames
 83 #ifdef AMD64
 84 #ifdef _WIN64
 85     entry_frame_after_call_words                     =  28,
 86     entry_frame_call_wrapper_offset                  =  2,
 87 
 88     arg_reg_save_area_bytes                          = 32, // Register argument save area
 89 #else
 90     entry_frame_after_call_words                     = 13,
 91     entry_frame_call_wrapper_offset                  = -6,
 92 
 93     arg_reg_save_area_bytes                          =  0,
 94 #endif // _WIN64
 95 #else
 96     entry_frame_call_wrapper_offset                  =  2,
 97 #endif // AMD64
 98 
 99     // size, in words, of frame metadata (e.g. pc and link)
100     metadata_words                                   = sender_sp_offset,
101     // size, in words, of metadata at frame bottom, i.e. it is not part of the
102     // caller/callee overlap
103     metadata_words_at_bottom                         = metadata_words,
104     // size, in words, of frame metadata at the frame top, i.e. it is located
105     // between a callee frame and its stack arguments, where it is part
106     // of the caller/callee overlap
107     metadata_words_at_top                            = 0,
108     // size, in words, of frame metadata at the frame top that needs
109     // to be reserved for callee functions in the runtime
110     frame_alignment                                  = 16,
111     // size, in words, of maximum shift in frame position due to alignment
112     align_wiggle                                     =  1
113   };
114 
115   intptr_t ptr_at(int offset) const {
116     return *ptr_at_addr(offset);
117   }
118 
119   void ptr_at_put(int offset, intptr_t value) {
120     *ptr_at_addr(offset) = value;
121   }
122 
123  private:
124   // an additional field beyond _sp and _pc:
125   union {
126     intptr_t*  _fp; // frame pointer
127     int _offset_fp; // relative frame pointer for use in stack-chunk frames
128   };
129   // The interpreter and adapters will extend the frame of the caller.
130   // Since oopMaps are based on the sp of the caller before extension
131   // we need to know that value. However in order to compute the address
132   // of the return address we need the real "raw" sp. By convention we
133   // use sp() to mean "raw" sp and unextended_sp() to mean the caller's
134   // original sp.
135 
136   union {
137     intptr_t* _unextended_sp;
138     int _offset_unextended_sp; // for use in stack-chunk frames
139   };
140 
141   void adjust_unextended_sp() NOT_DEBUG_RETURN;
142 
143   intptr_t* ptr_at_addr(int offset) const {
144     return (intptr_t*) addr_at(offset);
145   }
146 
147 #ifdef ASSERT
148   // Used in frame::sender_for_{interpreter,compiled}_frame
149   static void verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp);
150 #endif
151 
152  public:
153   // Constructors
154 
155   frame(intptr_t* sp, intptr_t* fp, address pc);
156 
157   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc);
158 
159   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb);
160   // used for heap frame construction by continuations
161   frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map, bool relative);
162 
163   frame(intptr_t* sp, intptr_t* fp);
164 
165   void init(intptr_t* sp, intptr_t* fp, address pc);
166   void setup(address pc);
167 
168   // accessors for the instance variables
169   // Note: not necessarily the real 'frame pointer' (see real_fp)
170   intptr_t* fp() const          { assert_absolute(); return _fp; }
171   void set_fp(intptr_t* newfp)  { _fp = newfp; }
172   int offset_fp() const         { assert_offset();  return _offset_fp; }
173   void set_offset_fp(int value) { assert_on_heap(); _offset_fp = value; }
174 
175   inline address* sender_pc_addr() const;
176 
177   // expression stack tos if we are nested in a java call
178   intptr_t* interpreter_frame_last_sp() const;
179 
180   template <typename RegisterMapT>
181   static void update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr);
182 
183   // deoptimization support
184   void interpreter_frame_set_last_sp(intptr_t* sp);
185 
186   static jint interpreter_frame_expression_stack_direction() { return -1; }
187 
188   // returns the sending frame, without applying any barriers
189   inline frame sender_raw(RegisterMap* map) const;
190 
191 #endif // CPU_X86_FRAME_X86_HPP