| 1 | /* | 
|---|
| 2 | * Copyright (c) 2000, 2019, 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 SHARE_C1_C1_FRAMEMAP_HPP | 
|---|
| 26 | #define SHARE_C1_C1_FRAMEMAP_HPP | 
|---|
| 27 |  | 
|---|
| 28 | #include "asm/macroAssembler.hpp" | 
|---|
| 29 | #include "c1/c1_Defs.hpp" | 
|---|
| 30 | #include "c1/c1_LIR.hpp" | 
|---|
| 31 | #include "code/vmreg.hpp" | 
|---|
| 32 | #include "memory/allocation.hpp" | 
|---|
| 33 | #include "runtime/frame.hpp" | 
|---|
| 34 | #include "runtime/synchronizer.hpp" | 
|---|
| 35 | #include "utilities/globalDefinitions.hpp" | 
|---|
| 36 | #include "utilities/macros.hpp" | 
|---|
| 37 |  | 
|---|
| 38 | class ciMethod; | 
|---|
| 39 | class CallingConvention; | 
|---|
| 40 |  | 
|---|
| 41 | //-------------------------------------------------------- | 
|---|
| 42 | //               FrameMap | 
|---|
| 43 | //-------------------------------------------------------- | 
|---|
| 44 |  | 
|---|
| 45 | //  This class is responsible of mapping items (locals, monitors, spill | 
|---|
| 46 | //  slots and registers to their frame location | 
|---|
| 47 | // | 
|---|
| 48 | //  The monitors are specified by a consecutive index, although each monitor entry | 
|---|
| 49 | //  occupies two words. The monitor_index is 0.._num_monitors | 
|---|
| 50 | //  The spill index is similar to local index; it is in range 0..(open) | 
|---|
| 51 | // | 
|---|
| 52 | //  The CPU registers are mapped using a fixed table; register with number 0 | 
|---|
| 53 | //  is the most used one. | 
|---|
| 54 |  | 
|---|
| 55 |  | 
|---|
| 56 | //   stack grow direction -->                                        SP | 
|---|
| 57 | //  +----------+---+----------+-------+------------------------+-----+ | 
|---|
| 58 | //  |arguments | x | monitors | spill | reserved argument area | ABI | | 
|---|
| 59 | //  +----------+---+----------+-------+------------------------+-----+ | 
|---|
| 60 | // | 
|---|
| 61 | //  x =  ABI area (SPARC) or  return adress and link (i486) | 
|---|
| 62 | //  ABI  = ABI area (SPARC) or nothing (i486) | 
|---|
| 63 |  | 
|---|
| 64 |  | 
|---|
| 65 | class LIR_OprDesc; | 
|---|
| 66 | typedef LIR_OprDesc* LIR_Opr; | 
|---|
| 67 |  | 
|---|
| 68 |  | 
|---|
| 69 | class FrameMap : public CompilationResourceObj { | 
|---|
| 70 | public: | 
|---|
| 71 | enum { | 
|---|
| 72 | nof_cpu_regs = pd_nof_cpu_regs_frame_map, | 
|---|
| 73 | nof_fpu_regs = pd_nof_fpu_regs_frame_map, | 
|---|
| 74 |  | 
|---|
| 75 | nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc, | 
|---|
| 76 | nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc, | 
|---|
| 77 |  | 
|---|
| 78 | max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map, | 
|---|
| 79 | nof_caller_save_fpu_regs     = pd_nof_caller_save_fpu_regs_frame_map, | 
|---|
| 80 |  | 
|---|
| 81 | spill_slot_size_in_bytes = 4 | 
|---|
| 82 | }; | 
|---|
| 83 |  | 
|---|
| 84 | #include CPU_HEADER(c1_FrameMap) | 
|---|
| 85 |  | 
|---|
| 86 | friend class LIR_OprDesc; | 
|---|
| 87 |  | 
|---|
| 88 | private: | 
|---|
| 89 | static bool         _init_done; | 
|---|
| 90 | static Register     _cpu_rnr2reg [nof_cpu_regs]; | 
|---|
| 91 | static int          _cpu_reg2rnr [nof_cpu_regs]; | 
|---|
| 92 |  | 
|---|
| 93 | static LIR_Opr      _caller_save_cpu_regs [max_nof_caller_save_cpu_regs]; | 
|---|
| 94 | static LIR_Opr      _caller_save_fpu_regs [nof_caller_save_fpu_regs]; | 
|---|
| 95 |  | 
|---|
| 96 | int                 _framesize; | 
|---|
| 97 | int                 _argcount; | 
|---|
| 98 | int                 _num_monitors; | 
|---|
| 99 | int                 _num_spills; | 
|---|
| 100 | int                 _reserved_argument_area_size; | 
|---|
| 101 | int                 _oop_map_arg_count; | 
|---|
| 102 |  | 
|---|
| 103 | CallingConvention*  _incoming_arguments; | 
|---|
| 104 | intArray*           _argument_locations; | 
|---|
| 105 |  | 
|---|
| 106 | void check_spill_index   (int spill_index)   const { assert(spill_index   >= 0, "bad index"); } | 
|---|
| 107 | void check_monitor_index (int monitor_index) const { assert(monitor_index >= 0 && | 
|---|
| 108 | monitor_index < _num_monitors, "bad index"); } | 
|---|
| 109 |  | 
|---|
| 110 | static Register cpu_rnr2reg (int rnr) { | 
|---|
| 111 | assert(_init_done, "tables not initialized"); | 
|---|
| 112 | debug_only(cpu_range_check(rnr);) | 
|---|
| 113 | return _cpu_rnr2reg[rnr]; | 
|---|
| 114 | } | 
|---|
| 115 |  | 
|---|
| 116 | static int cpu_reg2rnr (Register reg) { | 
|---|
| 117 | assert(_init_done, "tables not initialized"); | 
|---|
| 118 | debug_only(cpu_range_check(reg->encoding());) | 
|---|
| 119 | return _cpu_reg2rnr[reg->encoding()]; | 
|---|
| 120 | } | 
|---|
| 121 |  | 
|---|
| 122 | static void map_register(int rnr, Register reg) { | 
|---|
| 123 | debug_only(cpu_range_check(rnr);) | 
|---|
| 124 | debug_only(cpu_range_check(reg->encoding());) | 
|---|
| 125 | _cpu_rnr2reg[rnr] = reg; | 
|---|
| 126 | _cpu_reg2rnr[reg->encoding()] = rnr; | 
|---|
| 127 | } | 
|---|
| 128 |  | 
|---|
| 129 | void update_reserved_argument_area_size (int size) { | 
|---|
| 130 | assert(size >= 0, "check"); | 
|---|
| 131 | _reserved_argument_area_size = MAX2(_reserved_argument_area_size, size); | 
|---|
| 132 | } | 
|---|
| 133 |  | 
|---|
| 134 | protected: | 
|---|
| 135 | #ifndef PRODUCT | 
|---|
| 136 | static void cpu_range_check (int rnr)          { assert(0 <= rnr && rnr < nof_cpu_regs, "cpu register number is too big"); } | 
|---|
| 137 | static void fpu_range_check (int rnr)          { assert(0 <= rnr && rnr < nof_fpu_regs, "fpu register number is too big"); } | 
|---|
| 138 | #endif | 
|---|
| 139 |  | 
|---|
| 140 |  | 
|---|
| 141 | ByteSize sp_offset_for_monitor_base(const int idx) const; | 
|---|
| 142 |  | 
|---|
| 143 | Address make_new_address(ByteSize sp_offset) const; | 
|---|
| 144 |  | 
|---|
| 145 | ByteSize sp_offset_for_slot(const int idx) const; | 
|---|
| 146 | ByteSize sp_offset_for_double_slot(const int idx) const; | 
|---|
| 147 | ByteSize sp_offset_for_spill(const int idx) const; | 
|---|
| 148 | ByteSize sp_offset_for_monitor_lock(int monitor_index) const; | 
|---|
| 149 | ByteSize sp_offset_for_monitor_object(int monitor_index) const; | 
|---|
| 150 |  | 
|---|
| 151 | VMReg sp_offset2vmreg(ByteSize offset) const; | 
|---|
| 152 |  | 
|---|
| 153 | // platform dependent hook used to check that frame is properly | 
|---|
| 154 | // addressable on the platform.  Used by sparc to verify that all | 
|---|
| 155 | // stack addresses are expressable in a simm13. | 
|---|
| 156 | bool validate_frame(); | 
|---|
| 157 |  | 
|---|
| 158 | static LIR_Opr map_to_opr(BasicType type, VMRegPair* reg, bool incoming); | 
|---|
| 159 |  | 
|---|
| 160 | public: | 
|---|
| 161 | // Opr representing the stack_pointer on this platform | 
|---|
| 162 | static LIR_Opr stack_pointer(); | 
|---|
| 163 |  | 
|---|
| 164 | // JSR 292 | 
|---|
| 165 | static LIR_Opr method_handle_invoke_SP_save_opr(); | 
|---|
| 166 |  | 
|---|
| 167 | static BasicTypeArray*     signature_type_array_for(const ciMethod* method); | 
|---|
| 168 |  | 
|---|
| 169 | // for outgoing calls, these also update the reserved area to | 
|---|
| 170 | // include space for arguments and any ABI area. | 
|---|
| 171 | CallingConvention* c_calling_convention(const BasicTypeArray* signature); | 
|---|
| 172 | CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing); | 
|---|
| 173 |  | 
|---|
| 174 | // deopt support | 
|---|
| 175 | ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); } | 
|---|
| 176 |  | 
|---|
| 177 | static LIR_Opr as_opr(Register r) { | 
|---|
| 178 | return LIR_OprFact::single_cpu(cpu_reg2rnr(r)); | 
|---|
| 179 | } | 
|---|
| 180 | static LIR_Opr as_oop_opr(Register r) { | 
|---|
| 181 | return LIR_OprFact::single_cpu_oop(cpu_reg2rnr(r)); | 
|---|
| 182 | } | 
|---|
| 183 |  | 
|---|
| 184 | static LIR_Opr as_metadata_opr(Register r) { | 
|---|
| 185 | return LIR_OprFact::single_cpu_metadata(cpu_reg2rnr(r)); | 
|---|
| 186 | } | 
|---|
| 187 |  | 
|---|
| 188 | FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size); | 
|---|
| 189 | bool finalize_frame(int nof_slots); | 
|---|
| 190 |  | 
|---|
| 191 | int   reserved_argument_area_size () const     { return _reserved_argument_area_size; } | 
|---|
| 192 | int   framesize                   () const     { assert(_framesize != -1, "hasn't been calculated"); return _framesize; } | 
|---|
| 193 | ByteSize framesize_in_bytes       () const     { return in_ByteSize(framesize() * 4); } | 
|---|
| 194 | int   num_monitors                () const     { return _num_monitors; } | 
|---|
| 195 | int   num_spills                  () const     { assert(_num_spills >= 0, "not set"); return _num_spills; } | 
|---|
| 196 | int   argcount              () const     { assert(_argcount >= 0, "not set"); return _argcount; } | 
|---|
| 197 |  | 
|---|
| 198 | int oop_map_arg_count() const { return _oop_map_arg_count; } | 
|---|
| 199 |  | 
|---|
| 200 | CallingConvention* incoming_arguments() const  { return _incoming_arguments; } | 
|---|
| 201 |  | 
|---|
| 202 | // convenience routines | 
|---|
| 203 | Address address_for_slot(int index, int sp_adjust = 0) const { | 
|---|
| 204 | return make_new_address(sp_offset_for_slot(index) + in_ByteSize(sp_adjust)); | 
|---|
| 205 | } | 
|---|
| 206 | Address address_for_double_slot(int index, int sp_adjust = 0) const { | 
|---|
| 207 | return make_new_address(sp_offset_for_double_slot(index) + in_ByteSize(sp_adjust)); | 
|---|
| 208 | } | 
|---|
| 209 | Address address_for_monitor_lock(int monitor_index) const { | 
|---|
| 210 | return make_new_address(sp_offset_for_monitor_lock(monitor_index)); | 
|---|
| 211 | } | 
|---|
| 212 | Address address_for_monitor_object(int monitor_index) const { | 
|---|
| 213 | return make_new_address(sp_offset_for_monitor_object(monitor_index)); | 
|---|
| 214 | } | 
|---|
| 215 |  | 
|---|
| 216 | // Creates Location describing desired slot and returns it via pointer | 
|---|
| 217 | // to Location object. Returns true if the stack frame offset was legal | 
|---|
| 218 | // (as defined by Location::legal_offset_in_bytes()), false otherwise. | 
|---|
| 219 | // Do not use the returned location if this returns false. | 
|---|
| 220 | bool location_for_sp_offset(ByteSize byte_offset_from_sp, | 
|---|
| 221 | Location::Type loc_type, Location* loc) const; | 
|---|
| 222 |  | 
|---|
| 223 | bool location_for_monitor_lock  (int monitor_index, Location* loc) const { | 
|---|
| 224 | return location_for_sp_offset(sp_offset_for_monitor_lock(monitor_index), Location::normal, loc); | 
|---|
| 225 | } | 
|---|
| 226 | bool location_for_monitor_object(int monitor_index, Location* loc) const { | 
|---|
| 227 | return location_for_sp_offset(sp_offset_for_monitor_object(monitor_index), Location::oop, loc); | 
|---|
| 228 | } | 
|---|
| 229 | bool locations_for_slot  (int index, Location::Type loc_type, | 
|---|
| 230 | Location* loc, Location* second = NULL) const; | 
|---|
| 231 |  | 
|---|
| 232 | VMReg slot_regname(int index) const { | 
|---|
| 233 | return sp_offset2vmreg(sp_offset_for_slot(index)); | 
|---|
| 234 | } | 
|---|
| 235 | VMReg monitor_object_regname(int monitor_index) const { | 
|---|
| 236 | return sp_offset2vmreg(sp_offset_for_monitor_object(monitor_index)); | 
|---|
| 237 | } | 
|---|
| 238 | VMReg regname(LIR_Opr opr) const; | 
|---|
| 239 |  | 
|---|
| 240 | static LIR_Opr caller_save_cpu_reg_at(int i) { | 
|---|
| 241 | assert(i >= 0 && i < max_nof_caller_save_cpu_regs, "out of bounds"); | 
|---|
| 242 | return _caller_save_cpu_regs[i]; | 
|---|
| 243 | } | 
|---|
| 244 |  | 
|---|
| 245 | static LIR_Opr caller_save_fpu_reg_at(int i) { | 
|---|
| 246 | assert(i >= 0 && i < nof_caller_save_fpu_regs, "out of bounds"); | 
|---|
| 247 | return _caller_save_fpu_regs[i]; | 
|---|
| 248 | } | 
|---|
| 249 |  | 
|---|
| 250 | static void initialize(); | 
|---|
| 251 | }; | 
|---|
| 252 |  | 
|---|
| 253 | //               CallingConvention | 
|---|
| 254 | //-------------------------------------------------------- | 
|---|
| 255 |  | 
|---|
| 256 | class CallingConvention: public ResourceObj { | 
|---|
| 257 | private: | 
|---|
| 258 | LIR_OprList* _args; | 
|---|
| 259 | int          _reserved_stack_slots; | 
|---|
| 260 |  | 
|---|
| 261 | public: | 
|---|
| 262 | CallingConvention (LIR_OprList* args, int reserved_stack_slots) | 
|---|
| 263 | : _args(args) | 
|---|
| 264 | , _reserved_stack_slots(reserved_stack_slots)  {} | 
|---|
| 265 |  | 
|---|
| 266 | LIR_OprList* args()       { return _args; } | 
|---|
| 267 |  | 
|---|
| 268 | LIR_Opr at(int i) const   { return _args->at(i); } | 
|---|
| 269 | int length() const        { return _args->length(); } | 
|---|
| 270 |  | 
|---|
| 271 | // Indicates number of real frame slots used by arguments passed on stack. | 
|---|
| 272 | int reserved_stack_slots() const            { return _reserved_stack_slots; } | 
|---|
| 273 |  | 
|---|
| 274 | #ifndef PRODUCT | 
|---|
| 275 | void print () const { | 
|---|
| 276 | for (int i = 0; i < length(); i++) { | 
|---|
| 277 | at(i)->print(); | 
|---|
| 278 | } | 
|---|
| 279 | } | 
|---|
| 280 | #endif // PRODUCT | 
|---|
| 281 | }; | 
|---|
| 282 |  | 
|---|
| 283 | #endif // SHARE_C1_C1_FRAMEMAP_HPP | 
|---|
| 284 |  | 
|---|