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 |