Bug Summary

File:jdk/src/hotspot/share/c1/c1_FrameMap.hpp
Warning:line 120, column 5
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name c1_FrameMap_x86.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp

/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_FrameMap_x86.cpp

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
31const int FrameMap::pd_c_runtime_reserved_arg_size = 0;
32
33LIR_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
85LIR_Opr FrameMap::rsi_opr;
86LIR_Opr FrameMap::rdi_opr;
87LIR_Opr FrameMap::rbx_opr;
88LIR_Opr FrameMap::rax_opr;
89LIR_Opr FrameMap::rdx_opr;
90LIR_Opr FrameMap::rcx_opr;
91LIR_Opr FrameMap::rsp_opr;
92LIR_Opr FrameMap::rbp_opr;
93
94LIR_Opr FrameMap::receiver_opr;
95
96LIR_Opr FrameMap::rsi_oop_opr;
97LIR_Opr FrameMap::rdi_oop_opr;
98LIR_Opr FrameMap::rbx_oop_opr;
99LIR_Opr FrameMap::rax_oop_opr;
100LIR_Opr FrameMap::rdx_oop_opr;
101LIR_Opr FrameMap::rcx_oop_opr;
102
103LIR_Opr FrameMap::rsi_metadata_opr;
104LIR_Opr FrameMap::rdi_metadata_opr;
105LIR_Opr FrameMap::rbx_metadata_opr;
106LIR_Opr FrameMap::rax_metadata_opr;
107LIR_Opr FrameMap::rdx_metadata_opr;
108LIR_Opr FrameMap::rcx_metadata_opr;
109
110LIR_Opr FrameMap::long0_opr;
111LIR_Opr FrameMap::long1_opr;
112LIR_Opr FrameMap::fpu0_float_opr;
113LIR_Opr FrameMap::fpu0_double_opr;
114LIR_Opr FrameMap::xmm0_float_opr;
115LIR_Opr FrameMap::xmm0_double_opr;
116
117#ifdef _LP641
118
119LIR_Opr FrameMap::r8_opr;
120LIR_Opr FrameMap::r9_opr;
121LIR_Opr FrameMap::r10_opr;
122LIR_Opr FrameMap::r11_opr;
123LIR_Opr FrameMap::r12_opr;
124LIR_Opr FrameMap::r13_opr;
125LIR_Opr FrameMap::r14_opr;
126LIR_Opr FrameMap::r15_opr;
127
128// r10 and r15 can never contain oops since they aren't available to
129// the allocator
130LIR_Opr FrameMap::r8_oop_opr;
131LIR_Opr FrameMap::r9_oop_opr;
132LIR_Opr FrameMap::r11_oop_opr;
133LIR_Opr FrameMap::r12_oop_opr;
134LIR_Opr FrameMap::r13_oop_opr;
135LIR_Opr FrameMap::r14_oop_opr;
136
137LIR_Opr FrameMap::r8_metadata_opr;
138LIR_Opr FrameMap::r9_metadata_opr;
139LIR_Opr FrameMap::r11_metadata_opr;
140LIR_Opr FrameMap::r12_metadata_opr;
141LIR_Opr FrameMap::r13_metadata_opr;
142LIR_Opr FrameMap::r14_metadata_opr;
143#endif // _LP64
144
145LIR_Opr FrameMap::_caller_save_cpu_regs[] = {};
146LIR_Opr FrameMap::_caller_save_fpu_regs[] = {};
147LIR_Opr FrameMap::_caller_save_xmm_regs[] = {};
148
149XMMRegister FrameMap::_xmm_regs [] = { 0, };
150
151XMMRegister 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
160void 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)
;
1
Assuming '_init_done' is false
2
Taking false branch
3
Loop condition is false. Exiting loop
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)
;
4
Taking false branch
5
Loop condition is false. Exiting loop
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);
6
Passing null pointer value via 2nd parameter 'reg'
7
Calling 'FrameMap::map_register'
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, &regs, 1);
303 receiver_opr = as_oop_opr(regs.first()->as_Register());
304
305}
306
307
308Address 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
355VMReg 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
361LIR_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.
368LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
369 return LIR_OprFact::illegalOpr;
370}
371
372bool FrameMap::validate_frame() {
373 return true;
374}

/home/daniel/Projects/java/jdk/src/hotspot/share/c1/c1_FrameMap.hpp

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
38class ciMethod;
39class 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
65class 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());
8
Called C++ object pointer is null
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
256class 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