| File: | jdk/src/hotspot/share/c1/c1_FrameMap.hpp |
| Warning: | line 120, column 5 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* | |||
| 2 | * Copyright (c) 1999, 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 | #include "precompiled.hpp" | |||
| 26 | #include "c1/c1_FrameMap.hpp" | |||
| 27 | #include "c1/c1_LIR.hpp" | |||
| 28 | #include "runtime/sharedRuntime.hpp" | |||
| 29 | #include "vmreg_x86.inline.hpp" | |||
| 30 | ||||
| 31 | const int FrameMap::pd_c_runtime_reserved_arg_size = 0; | |||
| 32 | ||||
| 33 | LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool) { | |||
| 34 | LIR_Opr opr = LIR_OprFact::illegalOpr; | |||
| 35 | VMReg r_1 = reg->first(); | |||
| 36 | VMReg r_2 = reg->second(); | |||
| 37 | if (r_1->is_stack()) { | |||
| 38 | // Convert stack slot to an SP offset | |||
| 39 | // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value | |||
| 40 | // so we must add it in here. | |||
| 41 | int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; | |||
| 42 | opr = LIR_OprFact::address(new LIR_Address(rsp_opr, st_off, type)); | |||
| 43 | } else if (r_1->is_Register()) { | |||
| 44 | Register reg = r_1->as_Register(); | |||
| 45 | if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) { | |||
| 46 | Register reg2 = r_2->as_Register(); | |||
| 47 | #ifdef _LP641 | |||
| 48 | assert(reg2 == reg, "must be same register")do { if (!(reg2 == reg)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 48, "assert(" "reg2 == reg" ") failed", "must be same register" ); ::breakpoint(); } } while (0); | |||
| 49 | opr = as_long_opr(reg); | |||
| 50 | #else | |||
| 51 | opr = as_long_opr(reg2, reg); | |||
| 52 | #endif // _LP64 | |||
| 53 | } else if (is_reference_type(type)) { | |||
| 54 | opr = as_oop_opr(reg); | |||
| 55 | } else if (type == T_METADATA) { | |||
| 56 | opr = as_metadata_opr(reg); | |||
| 57 | } else if (type == T_ADDRESS) { | |||
| 58 | opr = as_address_opr(reg); | |||
| 59 | } else { | |||
| 60 | opr = as_opr(reg); | |||
| 61 | } | |||
| 62 | } else if (r_1->is_FloatRegister()) { | |||
| 63 | assert(type == T_DOUBLE || type == T_FLOAT, "wrong type")do { if (!(type == T_DOUBLE || type == T_FLOAT)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 63, "assert(" "type == T_DOUBLE || type == T_FLOAT" ") failed" , "wrong type"); ::breakpoint(); } } while (0); | |||
| 64 | int num = r_1->as_FloatRegister()->encoding(); | |||
| 65 | if (type == T_FLOAT) { | |||
| 66 | opr = LIR_OprFact::single_fpu(num); | |||
| 67 | } else { | |||
| 68 | opr = LIR_OprFact::double_fpu(num); | |||
| 69 | } | |||
| 70 | } else if (r_1->is_XMMRegister()) { | |||
| 71 | assert(type == T_DOUBLE || type == T_FLOAT, "wrong type")do { if (!(type == T_DOUBLE || type == T_FLOAT)) { (*g_assert_poison ) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 71, "assert(" "type == T_DOUBLE || type == T_FLOAT" ") failed" , "wrong type"); ::breakpoint(); } } while (0); | |||
| 72 | int num = r_1->as_XMMRegister()->encoding(); | |||
| 73 | if (type == T_FLOAT) { | |||
| 74 | opr = LIR_OprFact::single_xmm(num); | |||
| 75 | } else { | |||
| 76 | opr = LIR_OprFact::double_xmm(num); | |||
| 77 | } | |||
| 78 | } else { | |||
| 79 | ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here( "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 79); ::breakpoint(); } while (0); | |||
| 80 | } | |||
| 81 | return opr; | |||
| 82 | } | |||
| 83 | ||||
| 84 | ||||
| 85 | LIR_Opr FrameMap::rsi_opr; | |||
| 86 | LIR_Opr FrameMap::rdi_opr; | |||
| 87 | LIR_Opr FrameMap::rbx_opr; | |||
| 88 | LIR_Opr FrameMap::rax_opr; | |||
| 89 | LIR_Opr FrameMap::rdx_opr; | |||
| 90 | LIR_Opr FrameMap::rcx_opr; | |||
| 91 | LIR_Opr FrameMap::rsp_opr; | |||
| 92 | LIR_Opr FrameMap::rbp_opr; | |||
| 93 | ||||
| 94 | LIR_Opr FrameMap::receiver_opr; | |||
| 95 | ||||
| 96 | LIR_Opr FrameMap::rsi_oop_opr; | |||
| 97 | LIR_Opr FrameMap::rdi_oop_opr; | |||
| 98 | LIR_Opr FrameMap::rbx_oop_opr; | |||
| 99 | LIR_Opr FrameMap::rax_oop_opr; | |||
| 100 | LIR_Opr FrameMap::rdx_oop_opr; | |||
| 101 | LIR_Opr FrameMap::rcx_oop_opr; | |||
| 102 | ||||
| 103 | LIR_Opr FrameMap::rsi_metadata_opr; | |||
| 104 | LIR_Opr FrameMap::rdi_metadata_opr; | |||
| 105 | LIR_Opr FrameMap::rbx_metadata_opr; | |||
| 106 | LIR_Opr FrameMap::rax_metadata_opr; | |||
| 107 | LIR_Opr FrameMap::rdx_metadata_opr; | |||
| 108 | LIR_Opr FrameMap::rcx_metadata_opr; | |||
| 109 | ||||
| 110 | LIR_Opr FrameMap::long0_opr; | |||
| 111 | LIR_Opr FrameMap::long1_opr; | |||
| 112 | LIR_Opr FrameMap::fpu0_float_opr; | |||
| 113 | LIR_Opr FrameMap::fpu0_double_opr; | |||
| 114 | LIR_Opr FrameMap::xmm0_float_opr; | |||
| 115 | LIR_Opr FrameMap::xmm0_double_opr; | |||
| 116 | ||||
| 117 | #ifdef _LP641 | |||
| 118 | ||||
| 119 | LIR_Opr FrameMap::r8_opr; | |||
| 120 | LIR_Opr FrameMap::r9_opr; | |||
| 121 | LIR_Opr FrameMap::r10_opr; | |||
| 122 | LIR_Opr FrameMap::r11_opr; | |||
| 123 | LIR_Opr FrameMap::r12_opr; | |||
| 124 | LIR_Opr FrameMap::r13_opr; | |||
| 125 | LIR_Opr FrameMap::r14_opr; | |||
| 126 | LIR_Opr FrameMap::r15_opr; | |||
| 127 | ||||
| 128 | // r10 and r15 can never contain oops since they aren't available to | |||
| 129 | // the allocator | |||
| 130 | LIR_Opr FrameMap::r8_oop_opr; | |||
| 131 | LIR_Opr FrameMap::r9_oop_opr; | |||
| 132 | LIR_Opr FrameMap::r11_oop_opr; | |||
| 133 | LIR_Opr FrameMap::r12_oop_opr; | |||
| 134 | LIR_Opr FrameMap::r13_oop_opr; | |||
| 135 | LIR_Opr FrameMap::r14_oop_opr; | |||
| 136 | ||||
| 137 | LIR_Opr FrameMap::r8_metadata_opr; | |||
| 138 | LIR_Opr FrameMap::r9_metadata_opr; | |||
| 139 | LIR_Opr FrameMap::r11_metadata_opr; | |||
| 140 | LIR_Opr FrameMap::r12_metadata_opr; | |||
| 141 | LIR_Opr FrameMap::r13_metadata_opr; | |||
| 142 | LIR_Opr FrameMap::r14_metadata_opr; | |||
| 143 | #endif // _LP64 | |||
| 144 | ||||
| 145 | LIR_Opr FrameMap::_caller_save_cpu_regs[] = {}; | |||
| 146 | LIR_Opr FrameMap::_caller_save_fpu_regs[] = {}; | |||
| 147 | LIR_Opr FrameMap::_caller_save_xmm_regs[] = {}; | |||
| 148 | ||||
| 149 | XMMRegister FrameMap::_xmm_regs [] = { 0, }; | |||
| 150 | ||||
| 151 | XMMRegister FrameMap::nr2xmmreg(int rnr) { | |||
| 152 | assert(_init_done, "tables not initialized")do { if (!(_init_done)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 152, "assert(" "_init_done" ") failed", "tables not initialized" ); ::breakpoint(); } } while (0); | |||
| 153 | return _xmm_regs[rnr]; | |||
| 154 | } | |||
| 155 | ||||
| 156 | //-------------------------------------------------------- | |||
| 157 | // FrameMap | |||
| 158 | //-------------------------------------------------------- | |||
| 159 | ||||
| 160 | void FrameMap::initialize() { | |||
| 161 | assert(!_init_done, "once")do { if (!(!_init_done)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 161, "assert(" "!_init_done" ") failed", "once"); ::breakpoint (); } } while (0); | |||
| ||||
| 162 | ||||
| 163 | assert(nof_cpu_regs == LP64_ONLY(16) NOT_LP64(8), "wrong number of CPU registers")do { if (!(nof_cpu_regs == 16)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp" , 163, "assert(" "nof_cpu_regs == 16" ") failed", "wrong number of CPU registers" ); ::breakpoint(); } } while (0); | |||
| 164 | map_register(0, rsi); rsi_opr = LIR_OprFact::single_cpu(0); | |||
| 165 | map_register(1, rdi); rdi_opr = LIR_OprFact::single_cpu(1); | |||
| 166 | map_register(2, rbx); rbx_opr = LIR_OprFact::single_cpu(2); | |||
| 167 | map_register(3, rax); rax_opr = LIR_OprFact::single_cpu(3); | |||
| 168 | map_register(4, rdx); rdx_opr = LIR_OprFact::single_cpu(4); | |||
| 169 | map_register(5, rcx); rcx_opr = LIR_OprFact::single_cpu(5); | |||
| 170 | ||||
| 171 | #ifndef _LP641 | |||
| 172 | // The unallocatable registers are at the end | |||
| 173 | map_register(6, rsp); | |||
| 174 | map_register(7, rbp); | |||
| 175 | #else | |||
| 176 | map_register( 6, r8); r8_opr = LIR_OprFact::single_cpu(6); | |||
| 177 | map_register( 7, r9); r9_opr = LIR_OprFact::single_cpu(7); | |||
| 178 | map_register( 8, r11); r11_opr = LIR_OprFact::single_cpu(8); | |||
| 179 | map_register( 9, r13); r13_opr = LIR_OprFact::single_cpu(9); | |||
| 180 | map_register(10, r14); r14_opr = LIR_OprFact::single_cpu(10); | |||
| 181 | // r12 is allocated conditionally. With compressed oops it holds | |||
| 182 | // the heapbase value and is not visible to the allocator. | |||
| 183 | map_register(11, r12); r12_opr = LIR_OprFact::single_cpu(11); | |||
| 184 | // The unallocatable registers are at the end | |||
| 185 | map_register(12, r10); r10_opr = LIR_OprFact::single_cpu(12); | |||
| 186 | map_register(13, r15); r15_opr = LIR_OprFact::single_cpu(13); | |||
| 187 | map_register(14, rsp); | |||
| 188 | map_register(15, rbp); | |||
| 189 | #endif // _LP64 | |||
| 190 | ||||
| 191 | #ifdef _LP641 | |||
| 192 | long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 3 /*eax*/); | |||
| 193 | long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 2 /*ebx*/); | |||
| 194 | #else | |||
| 195 | long0_opr = LIR_OprFact::double_cpu(3 /*eax*/, 4 /*edx*/); | |||
| 196 | long1_opr = LIR_OprFact::double_cpu(2 /*ebx*/, 5 /*ecx*/); | |||
| 197 | #endif // _LP64 | |||
| 198 | fpu0_float_opr = LIR_OprFact::single_fpu(0); | |||
| 199 | fpu0_double_opr = LIR_OprFact::double_fpu(0); | |||
| 200 | xmm0_float_opr = LIR_OprFact::single_xmm(0); | |||
| 201 | xmm0_double_opr = LIR_OprFact::double_xmm(0); | |||
| 202 | ||||
| 203 | _caller_save_cpu_regs[0] = rsi_opr; | |||
| 204 | _caller_save_cpu_regs[1] = rdi_opr; | |||
| 205 | _caller_save_cpu_regs[2] = rbx_opr; | |||
| 206 | _caller_save_cpu_regs[3] = rax_opr; | |||
| 207 | _caller_save_cpu_regs[4] = rdx_opr; | |||
| 208 | _caller_save_cpu_regs[5] = rcx_opr; | |||
| 209 | ||||
| 210 | #ifdef _LP641 | |||
| 211 | _caller_save_cpu_regs[6] = r8_opr; | |||
| 212 | _caller_save_cpu_regs[7] = r9_opr; | |||
| 213 | _caller_save_cpu_regs[8] = r11_opr; | |||
| 214 | _caller_save_cpu_regs[9] = r13_opr; | |||
| 215 | _caller_save_cpu_regs[10] = r14_opr; | |||
| 216 | _caller_save_cpu_regs[11] = r12_opr; | |||
| 217 | #endif // _LP64 | |||
| 218 | ||||
| 219 | ||||
| 220 | _xmm_regs[0] = xmm0; | |||
| 221 | _xmm_regs[1] = xmm1; | |||
| 222 | _xmm_regs[2] = xmm2; | |||
| 223 | _xmm_regs[3] = xmm3; | |||
| 224 | _xmm_regs[4] = xmm4; | |||
| 225 | _xmm_regs[5] = xmm5; | |||
| 226 | _xmm_regs[6] = xmm6; | |||
| 227 | _xmm_regs[7] = xmm7; | |||
| 228 | ||||
| 229 | #ifdef _LP641 | |||
| 230 | _xmm_regs[8] = xmm8; | |||
| 231 | _xmm_regs[9] = xmm9; | |||
| 232 | _xmm_regs[10] = xmm10; | |||
| 233 | _xmm_regs[11] = xmm11; | |||
| 234 | _xmm_regs[12] = xmm12; | |||
| 235 | _xmm_regs[13] = xmm13; | |||
| 236 | _xmm_regs[14] = xmm14; | |||
| 237 | _xmm_regs[15] = xmm15; | |||
| 238 | _xmm_regs[16] = xmm16; | |||
| 239 | _xmm_regs[17] = xmm17; | |||
| 240 | _xmm_regs[18] = xmm18; | |||
| 241 | _xmm_regs[19] = xmm19; | |||
| 242 | _xmm_regs[20] = xmm20; | |||
| 243 | _xmm_regs[21] = xmm21; | |||
| 244 | _xmm_regs[22] = xmm22; | |||
| 245 | _xmm_regs[23] = xmm23; | |||
| 246 | _xmm_regs[24] = xmm24; | |||
| 247 | _xmm_regs[25] = xmm25; | |||
| 248 | _xmm_regs[26] = xmm26; | |||
| 249 | _xmm_regs[27] = xmm27; | |||
| 250 | _xmm_regs[28] = xmm28; | |||
| 251 | _xmm_regs[29] = xmm29; | |||
| 252 | _xmm_regs[30] = xmm30; | |||
| 253 | _xmm_regs[31] = xmm31; | |||
| 254 | #endif // _LP64 | |||
| 255 | ||||
| 256 | for (int i = 0; i < 8; i++) { | |||
| 257 | _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); | |||
| 258 | } | |||
| 259 | ||||
| 260 | int num_caller_save_xmm_regs = get_num_caller_save_xmms(); | |||
| 261 | for (int i = 0; i < num_caller_save_xmm_regs; i++) { | |||
| 262 | _caller_save_xmm_regs[i] = LIR_OprFact::single_xmm(i); | |||
| 263 | } | |||
| 264 | ||||
| 265 | _init_done = true; | |||
| 266 | ||||
| 267 | rsi_oop_opr = as_oop_opr(rsi); | |||
| 268 | rdi_oop_opr = as_oop_opr(rdi); | |||
| 269 | rbx_oop_opr = as_oop_opr(rbx); | |||
| 270 | rax_oop_opr = as_oop_opr(rax); | |||
| 271 | rdx_oop_opr = as_oop_opr(rdx); | |||
| 272 | rcx_oop_opr = as_oop_opr(rcx); | |||
| 273 | ||||
| 274 | rsi_metadata_opr = as_metadata_opr(rsi); | |||
| 275 | rdi_metadata_opr = as_metadata_opr(rdi); | |||
| 276 | rbx_metadata_opr = as_metadata_opr(rbx); | |||
| 277 | rax_metadata_opr = as_metadata_opr(rax); | |||
| 278 | rdx_metadata_opr = as_metadata_opr(rdx); | |||
| 279 | rcx_metadata_opr = as_metadata_opr(rcx); | |||
| 280 | ||||
| 281 | rsp_opr = as_pointer_opr(rsp); | |||
| 282 | rbp_opr = as_pointer_opr(rbp); | |||
| 283 | ||||
| 284 | #ifdef _LP641 | |||
| 285 | r8_oop_opr = as_oop_opr(r8); | |||
| 286 | r9_oop_opr = as_oop_opr(r9); | |||
| 287 | r11_oop_opr = as_oop_opr(r11); | |||
| 288 | r12_oop_opr = as_oop_opr(r12); | |||
| 289 | r13_oop_opr = as_oop_opr(r13); | |||
| 290 | r14_oop_opr = as_oop_opr(r14); | |||
| 291 | ||||
| 292 | r8_metadata_opr = as_metadata_opr(r8); | |||
| 293 | r9_metadata_opr = as_metadata_opr(r9); | |||
| 294 | r11_metadata_opr = as_metadata_opr(r11); | |||
| 295 | r12_metadata_opr = as_metadata_opr(r12); | |||
| 296 | r13_metadata_opr = as_metadata_opr(r13); | |||
| 297 | r14_metadata_opr = as_metadata_opr(r14); | |||
| 298 | #endif // _LP64 | |||
| 299 | ||||
| 300 | VMRegPair regs; | |||
| 301 | BasicType sig_bt = T_OBJECT; | |||
| 302 | SharedRuntime::java_calling_convention(&sig_bt, ®s, 1); | |||
| 303 | receiver_opr = as_oop_opr(regs.first()->as_Register()); | |||
| 304 | ||||
| 305 | } | |||
| 306 | ||||
| 307 | ||||
| 308 | Address FrameMap::make_new_address(ByteSize sp_offset) const { | |||
| 309 | // for rbp, based address use this: | |||
| 310 | // return Address(rbp, in_bytes(sp_offset) - (framesize() - 2) * 4); | |||
| 311 | return Address(rsp, in_bytes(sp_offset)); | |||
| 312 | } | |||
| 313 | ||||
| 314 | ||||
| 315 | // ----------------mapping----------------------- | |||
| 316 | // all mapping is based on rbp, addressing, except for simple leaf methods where we access | |||
| 317 | // the locals rsp based (and no frame is built) | |||
| 318 | ||||
| 319 | ||||
| 320 | // Frame for simple leaf methods (quick entries) | |||
| 321 | // | |||
| 322 | // +----------+ | |||
| 323 | // | ret addr | <- TOS | |||
| 324 | // +----------+ | |||
| 325 | // | args | | |||
| 326 | // | ...... | | |||
| 327 | ||||
| 328 | // Frame for standard methods | |||
| 329 | // | |||
| 330 | // | .........| <- TOS | |||
| 331 | // | locals | | |||
| 332 | // +----------+ | |||
| 333 | // | old rbp, | <- EBP | |||
| 334 | // +----------+ | |||
| 335 | // | ret addr | | |||
| 336 | // +----------+ | |||
| 337 | // | args | | |||
| 338 | // | .........| | |||
| 339 | ||||
| 340 | ||||
| 341 | // For OopMaps, map a local variable or spill index to an VMRegImpl name. | |||
| 342 | // This is the offset from sp() in the frame of the slot for the index, | |||
| 343 | // skewed by VMRegImpl::stack0 to indicate a stack location (vs.a register.) | |||
| 344 | // | |||
| 345 | // framesize + | |||
| 346 | // stack0 stack0 0 <- VMReg | |||
| 347 | // | | <registers> | | |||
| 348 | // ...........|..............|.............| | |||
| 349 | // 0 1 2 3 x x 4 5 6 ... | <- local indices | |||
| 350 | // ^ ^ sp() ( x x indicate link | |||
| 351 | // | | and return addr) | |||
| 352 | // arguments non-argument locals | |||
| 353 | ||||
| 354 | ||||
| 355 | VMReg FrameMap::fpu_regname (int n) { | |||
| 356 | // Return the OptoReg name for the fpu stack slot "n" | |||
| 357 | // A spilled fpu stack slot comprises to two single-word OptoReg's. | |||
| 358 | return as_FloatRegister(n)->as_VMReg(); | |||
| 359 | } | |||
| 360 | ||||
| 361 | LIR_Opr FrameMap::stack_pointer() { | |||
| 362 | return FrameMap::rsp_opr; | |||
| 363 | } | |||
| 364 | ||||
| 365 | // JSR 292 | |||
| 366 | // On x86, there is no need to save the SP, because neither | |||
| 367 | // method handle intrinsics, nor compiled lambda forms modify it. | |||
| 368 | LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() { | |||
| 369 | return LIR_OprFact::illegalOpr; | |||
| 370 | } | |||
| 371 | ||||
| 372 | bool FrameMap::validate_frame() { | |||
| 373 | return true; | |||
| 374 | } |
| 1 | /* | |||
| 2 | * Copyright (c) 2000, 2021, 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 FrameMap : public CompilationResourceObj { | |||
| 66 | public: | |||
| 67 | enum { | |||
| 68 | nof_cpu_regs = pd_nof_cpu_regs_frame_map, | |||
| 69 | nof_fpu_regs = pd_nof_fpu_regs_frame_map, | |||
| 70 | ||||
| 71 | nof_cpu_regs_reg_alloc = pd_nof_cpu_regs_reg_alloc, | |||
| 72 | nof_fpu_regs_reg_alloc = pd_nof_fpu_regs_reg_alloc, | |||
| 73 | ||||
| 74 | max_nof_caller_save_cpu_regs = pd_nof_caller_save_cpu_regs_frame_map, | |||
| 75 | nof_caller_save_fpu_regs = pd_nof_caller_save_fpu_regs_frame_map, | |||
| 76 | ||||
| 77 | spill_slot_size_in_bytes = 4 | |||
| 78 | }; | |||
| 79 | ||||
| 80 | #include CPU_HEADER(c1_FrameMap)"c1_FrameMap_x86.hpp" | |||
| 81 | ||||
| 82 | friend class LIR_Opr; | |||
| 83 | ||||
| 84 | private: | |||
| 85 | static bool _init_done; | |||
| 86 | static Register _cpu_rnr2reg [nof_cpu_regs]; | |||
| 87 | static int _cpu_reg2rnr [nof_cpu_regs]; | |||
| 88 | ||||
| 89 | static LIR_Opr _caller_save_cpu_regs [max_nof_caller_save_cpu_regs]; | |||
| 90 | static LIR_Opr _caller_save_fpu_regs [nof_caller_save_fpu_regs]; | |||
| 91 | ||||
| 92 | int _framesize; | |||
| 93 | int _argcount; | |||
| 94 | int _num_monitors; | |||
| 95 | int _num_spills; | |||
| 96 | int _reserved_argument_area_size; | |||
| 97 | int _oop_map_arg_count; | |||
| 98 | ||||
| 99 | CallingConvention* _incoming_arguments; | |||
| 100 | intArray* _argument_locations; | |||
| 101 | ||||
| 102 | void check_spill_index (int spill_index) const { assert(spill_index >= 0, "bad index")do { if (!(spill_index >= 0)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 102, "assert(" "spill_index >= 0" ") failed", "bad index" ); ::breakpoint(); } } while (0); } | |||
| 103 | void check_monitor_index (int monitor_index) const { assert(monitor_index >= 0 &&do { if (!(monitor_index >= 0 && monitor_index < _num_monitors)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 104, "assert(" "monitor_index >= 0 && monitor_index < _num_monitors" ") failed", "bad index"); ::breakpoint(); } } while (0) | |||
| 104 | monitor_index < _num_monitors, "bad index")do { if (!(monitor_index >= 0 && monitor_index < _num_monitors)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 104, "assert(" "monitor_index >= 0 && monitor_index < _num_monitors" ") failed", "bad index"); ::breakpoint(); } } while (0); } | |||
| 105 | ||||
| 106 | static Register cpu_rnr2reg (int rnr) { | |||
| 107 | assert(_init_done, "tables not initialized")do { if (!(_init_done)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 107, "assert(" "_init_done" ") failed", "tables not initialized" ); ::breakpoint(); } } while (0); | |||
| 108 | debug_only(cpu_range_check(rnr);)cpu_range_check(rnr); | |||
| 109 | return _cpu_rnr2reg[rnr]; | |||
| 110 | } | |||
| 111 | ||||
| 112 | static int cpu_reg2rnr (Register reg) { | |||
| 113 | assert(_init_done, "tables not initialized")do { if (!(_init_done)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 113, "assert(" "_init_done" ") failed", "tables not initialized" ); ::breakpoint(); } } while (0); | |||
| 114 | debug_only(cpu_range_check(reg->encoding());)cpu_range_check(reg->encoding()); | |||
| 115 | return _cpu_reg2rnr[reg->encoding()]; | |||
| 116 | } | |||
| 117 | ||||
| 118 | static void map_register(int rnr, Register reg) { | |||
| 119 | debug_only(cpu_range_check(rnr);)cpu_range_check(rnr); | |||
| 120 | debug_only(cpu_range_check(reg->encoding());)cpu_range_check(reg->encoding()); | |||
| ||||
| 121 | _cpu_rnr2reg[rnr] = reg; | |||
| 122 | _cpu_reg2rnr[reg->encoding()] = rnr; | |||
| 123 | } | |||
| 124 | ||||
| 125 | void update_reserved_argument_area_size (int size) { | |||
| 126 | assert(size >= 0, "check")do { if (!(size >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 126, "assert(" "size >= 0" ") failed", "check"); ::breakpoint (); } } while (0); | |||
| 127 | _reserved_argument_area_size = MAX2(_reserved_argument_area_size, size); | |||
| 128 | } | |||
| 129 | ||||
| 130 | protected: | |||
| 131 | #ifndef PRODUCT | |||
| 132 | static void cpu_range_check (int rnr) { assert(0 <= rnr && rnr < nof_cpu_regs, "cpu register number is too big")do { if (!(0 <= rnr && rnr < nof_cpu_regs)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 132, "assert(" "0 <= rnr && rnr < nof_cpu_regs" ") failed", "cpu register number is too big"); ::breakpoint( ); } } while (0); } | |||
| 133 | static void fpu_range_check (int rnr) { assert(0 <= rnr && rnr < nof_fpu_regs, "fpu register number is too big")do { if (!(0 <= rnr && rnr < nof_fpu_regs)) { ( *g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 133, "assert(" "0 <= rnr && rnr < nof_fpu_regs" ") failed", "fpu register number is too big"); ::breakpoint( ); } } while (0); } | |||
| 134 | #endif | |||
| 135 | ||||
| 136 | ||||
| 137 | ByteSize sp_offset_for_monitor_base(const int idx) const; | |||
| 138 | ||||
| 139 | Address make_new_address(ByteSize sp_offset) const; | |||
| 140 | ||||
| 141 | ByteSize sp_offset_for_slot(const int idx) const; | |||
| 142 | ByteSize sp_offset_for_double_slot(const int idx) const; | |||
| 143 | ByteSize sp_offset_for_spill(const int idx) const; | |||
| 144 | ByteSize sp_offset_for_monitor_lock(int monitor_index) const; | |||
| 145 | ByteSize sp_offset_for_monitor_object(int monitor_index) const; | |||
| 146 | ||||
| 147 | VMReg sp_offset2vmreg(ByteSize offset) const; | |||
| 148 | ||||
| 149 | // platform dependent hook used to check that frame is properly | |||
| 150 | // addressable on the platform. Used by arm, ppc to verify that all | |||
| 151 | // stack addresses are valid. | |||
| 152 | bool validate_frame(); | |||
| 153 | ||||
| 154 | static LIR_Opr map_to_opr(BasicType type, VMRegPair* reg, bool incoming); | |||
| 155 | ||||
| 156 | public: | |||
| 157 | // Opr representing the stack_pointer on this platform | |||
| 158 | static LIR_Opr stack_pointer(); | |||
| 159 | ||||
| 160 | // JSR 292 | |||
| 161 | static LIR_Opr method_handle_invoke_SP_save_opr(); | |||
| 162 | ||||
| 163 | static BasicTypeArray* signature_type_array_for(const ciMethod* method); | |||
| 164 | ||||
| 165 | // for outgoing calls, these also update the reserved area to | |||
| 166 | // include space for arguments and any ABI area. | |||
| 167 | CallingConvention* c_calling_convention(const BasicTypeArray* signature); | |||
| 168 | CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing); | |||
| 169 | ||||
| 170 | // deopt support | |||
| 171 | ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); } | |||
| 172 | ||||
| 173 | static LIR_Opr as_opr(Register r) { | |||
| 174 | return LIR_OprFact::single_cpu(cpu_reg2rnr(r)); | |||
| 175 | } | |||
| 176 | static LIR_Opr as_oop_opr(Register r) { | |||
| 177 | return LIR_OprFact::single_cpu_oop(cpu_reg2rnr(r)); | |||
| 178 | } | |||
| 179 | ||||
| 180 | static LIR_Opr as_metadata_opr(Register r) { | |||
| 181 | return LIR_OprFact::single_cpu_metadata(cpu_reg2rnr(r)); | |||
| 182 | } | |||
| 183 | ||||
| 184 | static LIR_Opr as_address_opr(Register r) { | |||
| 185 | return LIR_OprFact::single_cpu_address(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")do { if (!(_framesize != -1)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 192, "assert(" "_framesize != -1" ") failed", "hasn't been calculated" ); ::breakpoint(); } } while (0); 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")do { if (!(_num_spills >= 0)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 195, "assert(" "_num_spills >= 0" ") failed", "not set") ; ::breakpoint(); } } while (0); return _num_spills; } | |||
| 196 | int argcount () const { assert(_argcount >= 0, "not set")do { if (!(_argcount >= 0)) { (*g_assert_poison) = 'X';; report_vm_error ("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 196, "assert(" "_argcount >= 0" ") failed", "not set"); :: breakpoint(); } } while (0); 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__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")do { if (!(i >= 0 && i < max_nof_caller_save_cpu_regs )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 241, "assert(" "i >= 0 && i < max_nof_caller_save_cpu_regs" ") failed", "out of bounds"); ::breakpoint(); } } while (0); | |||
| 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")do { if (!(i >= 0 && i < nof_caller_save_fpu_regs )) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp" , 246, "assert(" "i >= 0 && i < nof_caller_save_fpu_regs" ") failed", "out of bounds"); ::breakpoint(); } } while (0); | |||
| 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 |