Bug Summary

File:jdk/src/hotspot/share/asm/register.hpp
Warning:line 70, column 7
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_MacroAssembler_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_MacroAssembler_x86.cpp

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

1/*
2 * Copyright (c) 1999, 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#include "precompiled.hpp"
26#include "c1/c1_MacroAssembler.hpp"
27#include "c1/c1_Runtime1.hpp"
28#include "gc/shared/barrierSet.hpp"
29#include "gc/shared/barrierSetAssembler.hpp"
30#include "gc/shared/collectedHeap.hpp"
31#include "gc/shared/tlab_globals.hpp"
32#include "interpreter/interpreter.hpp"
33#include "oops/arrayOop.hpp"
34#include "oops/markWord.hpp"
35#include "runtime/basicLock.hpp"
36#include "runtime/os.hpp"
37#include "runtime/sharedRuntime.hpp"
38#include "runtime/stubRoutines.hpp"
39
40int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
41 const Register rklass_decode_tmp = LP64_ONLY(rscratch1)rscratch1 NOT_LP64(noreg);
42 const int aligned_mask = BytesPerWord -1;
43 const int hdr_offset = oopDesc::mark_offset_in_bytes();
44 assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction")do { if (!(hdr == rax)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 44, "assert(" "hdr == rax" ") failed", "hdr must be rax, for the cmpxchg instruction"
); ::breakpoint(); } } while (0)
;
45 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different")do { if (!(hdr != obj && hdr != disp_hdr && obj
!= disp_hdr)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 45, "assert(" "hdr != obj && hdr != disp_hdr && obj != disp_hdr"
") failed", "registers must be different"); ::breakpoint(); }
} while (0)
;
46 Label done;
47 int null_check_offset = -1;
48
49 verify_oop(obj)_verify_oop_checked(obj, "broken oop " "obj", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 49)
;
50
51 // save object being locked into the BasicObjectLock
52 movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
53
54 null_check_offset = offset();
55
56 if (DiagnoseSyncOnValueBasedClasses != 0) {
57 load_klass(hdr, obj, rklass_decode_tmp);
58 movl(hdr, Address(hdr, Klass::access_flags_offset()));
59 testl(hdr, JVM_ACC_IS_VALUE_BASED_CLASS);
60 jcc(Assembler::notZero, slow_case);
61 }
62
63 // Load object header
64 movptr(hdr, Address(obj, hdr_offset));
65 // and mark it as unlocked
66 orptr(hdr, markWord::unlocked_value);
67 // save unlocked object header into the displaced header location on the stack
68 movptr(Address(disp_hdr, 0), hdr);
69 // test if object header is still the same (i.e. unlocked), and if so, store the
70 // displaced header address in the object header - if it is not the same, get the
71 // object header instead
72 MacroAssembler::lock(); // must be immediately before cmpxchg!
73 cmpxchgptr(disp_hdr, Address(obj, hdr_offset));
74 // if the object header was the same, we're done
75 jcc(Assembler::equal, done);
76 // if the object header was not the same, it is now in the hdr register
77 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
78 //
79 // 1) (hdr & aligned_mask) == 0
80 // 2) rsp <= hdr
81 // 3) hdr <= rsp + page_size
82 //
83 // these 3 tests can be done by evaluating the following expression:
84 //
85 // (hdr - rsp) & (aligned_mask - page_size)
86 //
87 // assuming both the stack pointer and page_size have their least
88 // significant 2 bits cleared and page_size is a power of 2
89 subptr(hdr, rsp);
90 andptr(hdr, aligned_mask - os::vm_page_size());
91 // for recursive locking, the result is zero => save it in the displaced header
92 // location (NULL in the displaced hdr location indicates recursive locking)
93 movptr(Address(disp_hdr, 0), hdr);
94 // otherwise we don't care about the result and handle locking via runtime call
95 jcc(Assembler::notZero, slow_case);
96 // done
97 bind(done);
98 return null_check_offset;
99}
100
101
102void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
103 const int aligned_mask = BytesPerWord -1;
104 const int hdr_offset = oopDesc::mark_offset_in_bytes();
105 assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction")do { if (!(disp_hdr == rax)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 105, "assert(" "disp_hdr == rax" ") failed", "disp_hdr must be rax, for the cmpxchg instruction"
); ::breakpoint(); } } while (0)
;
106 assert(hdr != obj && hdr != disp_hdr && obj != disp_hdr, "registers must be different")do { if (!(hdr != obj && hdr != disp_hdr && obj
!= disp_hdr)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 106, "assert(" "hdr != obj && hdr != disp_hdr && obj != disp_hdr"
") failed", "registers must be different"); ::breakpoint(); }
} while (0)
;
107 Label done;
108
109 // load displaced header
110 movptr(hdr, Address(disp_hdr, 0));
111 // if the loaded hdr is NULL we had recursive locking
112 testptr(hdr, hdr);
113 // if we had recursive locking, we are done
114 jcc(Assembler::zero, done);
115 // load object
116 movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
117
118 verify_oop(obj)_verify_oop_checked(obj, "broken oop " "obj", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 118)
;
119 // test if object header is pointing to the displaced header, and if so, restore
120 // the displaced header in the object - if the object header is not pointing to
121 // the displaced header, get the object header instead
122 MacroAssembler::lock(); // must be immediately before cmpxchg!
123 cmpxchgptr(hdr, Address(obj, hdr_offset));
124 // if the object header was not pointing to the displaced header,
125 // we do unlocking via runtime call
126 jcc(Assembler::notEqual, slow_case);
127 // done
128 bind(done);
129}
130
131
132// Defines obj, preserves var_size_in_bytes
133void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
134 if (UseTLAB) {
135 tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
136 } else {
137 eden_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
138 }
139}
140
141
142void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
143 assert_different_registers(obj, klass, len);
144 Register tmp_encode_klass = LP64_ONLY(rscratch1)rscratch1 NOT_LP64(noreg);
145 // This assumes that all prototype bits fit in an int32_t
146 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markWord::prototype().value());
147#ifdef _LP641
148 if (UseCompressedClassPointers) { // Take care not to kill klass
149 movptr(t1, klass);
150 encode_klass_not_null(t1, tmp_encode_klass);
151 movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
152 } else
153#endif
154 {
155 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
156 }
157
158 if (len->is_valid()) {
159 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
160 }
161#ifdef _LP641
162 else if (UseCompressedClassPointers) {
163 xorptr(t1, t1);
164 store_klass_gap(obj, t1);
165 }
166#endif
167}
168
169
170// preserves obj, destroys len_in_bytes
171void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
172 assert(hdr_size_in_bytes >= 0, "header size must be positive or 0")do { if (!(hdr_size_in_bytes >= 0)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 172, "assert(" "hdr_size_in_bytes >= 0" ") failed", "header size must be positive or 0"
); ::breakpoint(); } } while (0)
;
173 Label done;
174
175 // len_in_bytes is positive and ptr sized
176 subptr(len_in_bytes, hdr_size_in_bytes);
177 jcc(Assembler::zero, done);
178 zero_memory(obj, len_in_bytes, hdr_size_in_bytes, t1);
179 bind(done);
180}
181
182
183void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
184 assert(obj == rax, "obj must be in rax, for cmpxchg")do { if (!(obj == rax)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 184, "assert(" "obj == rax" ") failed", "obj must be in rax, for cmpxchg"
); ::breakpoint(); } } while (0)
;
185 assert_different_registers(obj, t1, t2); // XXX really?
186 assert(header_size >= 0 && object_size >= header_size, "illegal sizes")do { if (!(header_size >= 0 && object_size >= header_size
)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 186, "assert(" "header_size >= 0 && object_size >= header_size"
") failed", "illegal sizes"); ::breakpoint(); } } while (0)
;
187
188 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
189
190 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB);
191}
192
193void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, bool is_tlab_allocated) {
194 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,do { if (!((con_size_in_bytes & MinObjAlignmentInBytesMask
) == 0)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 195, "assert(" "(con_size_in_bytes & MinObjAlignmentInBytesMask) == 0"
") failed", "con_size_in_bytes is not multiple of alignment"
); ::breakpoint(); } } while (0)
195 "con_size_in_bytes is not multiple of alignment")do { if (!((con_size_in_bytes & MinObjAlignmentInBytesMask
) == 0)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 195, "assert(" "(con_size_in_bytes & MinObjAlignmentInBytesMask) == 0"
") failed", "con_size_in_bytes is not multiple of alignment"
); ::breakpoint(); } } while (0)
;
196 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
197
198 initialize_header(obj, klass, noreg, t1, t2);
199
200 if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) {
201 // clear rest of allocated space
202 const Register t1_zero = t1;
203 const Register index = t2;
204 const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below)
205 if (var_size_in_bytes != noreg) {
206 mov(index, var_size_in_bytes);
207 initialize_body(obj, index, hdr_size_in_bytes, t1_zero);
208 } else if (con_size_in_bytes <= threshold) {
209 // use explicit null stores
210 // code size = 2 + 3*n bytes (n = number of fields to clear)
211 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code)
212 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord)
213 movptr(Address(obj, i), t1_zero);
214 } else if (con_size_in_bytes > hdr_size_in_bytes) {
215 // use loop to null out the fields
216 // code size = 16 bytes for even n (n = number of fields to clear)
217 // initialize last object field first if odd number of fields
218 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code)
219 movptr(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3);
220 // initialize last object field if constant size is odd
221 if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0)
222 movptr(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero);
223 // initialize remaining object fields: rdx is a multiple of 2
224 { Label loop;
225 bind(loop);
226 movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (1*BytesPerWord)),
227 t1_zero);
228 NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (2*BytesPerWord)),
229 t1_zero);)
230 decrement(index);
231 jcc(Assembler::notZero, loop);
232 }
233 }
234 }
235
236 if (CURRENT_ENVciEnv::current()->dtrace_alloc_probes()) {
237 assert(obj == rax, "must be")do { if (!(obj == rax)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 237, "assert(" "obj == rax" ") failed", "must be"); ::breakpoint
(); } } while (0)
;
238 call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
239 }
240
241 verify_oop(obj)_verify_oop_checked(obj, "broken oop " "obj", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 241)
;
242}
243
244void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, Address::ScaleFactor f, Register klass, Label& slow_case) {
245 assert(obj == rax, "obj must be in rax, for cmpxchg")do { if (!(obj == rax)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 245, "assert(" "obj == rax" ") failed", "obj must be in rax, for cmpxchg"
); ::breakpoint(); } } while (0)
;
1
Assuming 'obj' is equal to 'rax'
2
Taking false branch
3
Loop condition is false. Exiting loop
246 assert_different_registers(obj, len, t1, t2, klass);
4
Calling 'assert_different_registers<RegisterImpl *, RegisterImpl *, RegisterImpl *, RegisterImpl *, RegisterImpl *>'
247
248 // determine alignment mask
249 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work")do { if (!(!(BytesPerWord & 1))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 249, "assert(" "!(BytesPerWord & 1)" ") failed", "must be a multiple of 2 for masking code to work"
); ::breakpoint(); } } while (0)
;
250
251 // check for negative or excessive length
252 cmpptr(len, (int32_t)max_array_allocation_length);
253 jcc(Assembler::above, slow_case);
254
255 const Register arr_size = t2; // okay to be the same
256 // align object end
257 movptr(arr_size, (int32_t)header_size * BytesPerWord + MinObjAlignmentInBytesMask);
258 lea(arr_size, Address(arr_size, len, f));
259 andptr(arr_size, ~MinObjAlignmentInBytesMask);
260
261 try_allocate(obj, arr_size, 0, t1, t2, slow_case);
262
263 initialize_header(obj, klass, len, t1, t2);
264
265 // clear rest of allocated space
266 const Register len_zero = len;
267 initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
268
269 if (CURRENT_ENVciEnv::current()->dtrace_alloc_probes()) {
270 assert(obj == rax, "must be")do { if (!(obj == rax)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 270, "assert(" "obj == rax" ") failed", "must be"); ::breakpoint
(); } } while (0)
;
271 call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
272 }
273
274 verify_oop(obj)_verify_oop_checked(obj, "broken oop " "obj", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 274)
;
275}
276
277
278
279void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
280 verify_oop(receiver)_verify_oop_checked(receiver, "broken oop " "receiver", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 280)
;
281 // explicit NULL check not needed since load from [klass_offset] causes a trap
282 // check against inline cache
283 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check")do { if (!(!MacroAssembler::needs_explicit_null_check(oopDesc
::klass_offset_in_bytes()))) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 283, "assert(" "!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes())"
") failed", "must add explicit null check"); ::breakpoint();
} } while (0)
;
284 int start_offset = offset();
285 Register tmp_load_klass = LP64_ONLY(rscratch2)rscratch2 NOT_LP64(noreg);
286
287 if (UseCompressedClassPointers) {
288 load_klass(rscratch1, receiver, tmp_load_klass);
289 cmpptr(rscratch1, iCache);
290 } else {
291 cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
292 }
293 // if icache check fails, then jump to runtime routine
294 // Note: RECEIVER must still contain the receiver!
295 jump_cc(Assembler::notEqual,
296 RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
297 const int ic_cmp_size = LP64_ONLY(10)10 NOT_LP64(9);
298 assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry")do { if (!(UseCompressedClassPointers || offset() - start_offset
== ic_cmp_size)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 298, "assert(" "UseCompressedClassPointers || offset() - start_offset == ic_cmp_size"
") failed", "check alignment in emit_method_entry"); ::breakpoint
(); } } while (0)
;
299}
300
301
302void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
303 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect")do { if (!(bang_size_in_bytes >= frame_size_in_bytes)) { (
*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 303, "assert(" "bang_size_in_bytes >= frame_size_in_bytes"
") failed", "stack bang size incorrect"); ::breakpoint(); } }
while (0)
;
304 // Make sure there is enough stack space for this method's activation.
305 // Note that we do this before doing an enter(). This matches the
306 // ordering of C2's stack overflow check / rsp decrement and allows
307 // the SharedRuntime stack overflow handling to be consistent
308 // between the two compilers.
309 generate_stack_overflow_check(bang_size_in_bytes);
310
311 push(rbp);
312 if (PreserveFramePointer) {
313 mov(rbp, rsp);
314 }
315#if !defined(_LP641) && defined(COMPILER21)
316 if (UseSSE < 2 && !CompilerConfig::is_c1_only_no_jvmci()) {
317 // c2 leaves fpu stack dirty. Clean it on entry
318 empty_FPU_stack();
319 }
320#endif // !_LP64 && COMPILER2
321 decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
322
323 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
324 bs->nmethod_entry_barrier(this);
325}
326
327
328void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
329 increment(rsp, frame_size_in_bytes); // Does not emit code for frame_size == 0
330 pop(rbp);
331}
332
333
334void C1_MacroAssembler::verified_entry() {
335 if (C1Breakpoint || VerifyFPU) {
336 // Verified Entry first instruction should be 5 bytes long for correct
337 // patching by patch_verified_entry().
338 //
339 // C1Breakpoint and VerifyFPU have one byte first instruction.
340 // Also first instruction will be one byte "push(rbp)" if stack banging
341 // code is not generated (see build_frame() above).
342 // For all these cases generate long instruction first.
343 fat_nop();
344 }
345 if (C1Breakpoint)int3();
346 // build frame
347 IA32_ONLY( verify_FPU(0, "method_entry"); )
348}
349
350void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
351 // rbp, + 0: link
352 // + 1: return address
353 // + 2: argument with offset 0
354 // + 3: argument with offset 1
355 // + 4: ...
356
357 movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord));
358}
359
360#ifndef PRODUCT
361
362void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
363 if (!VerifyOops) return;
364 verify_oop_addr(Address(rsp, stack_offset))_verify_oop_addr_checked(Address(rsp, stack_offset), "broken oop addr "
"Address(rsp, stack_offset)", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 364)
;
365}
366
367void C1_MacroAssembler::verify_not_null_oop(Register r) {
368 if (!VerifyOops) return;
369 Label not_null;
370 testptr(r, r);
371 jcc(Assembler::notZero, not_null);
372 stop("non-null oop required");
373 bind(not_null);
374 verify_oop(r)_verify_oop_checked(r, "broken oop " "r", "/home/daniel/Projects/java/jdk/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp"
, 374)
;
375}
376
377void C1_MacroAssembler::invalidate_registers(bool inv_rax, bool inv_rbx, bool inv_rcx, bool inv_rdx, bool inv_rsi, bool inv_rdi) {
378#ifdef ASSERT1
379 if (inv_rax) movptr(rax, 0xDEAD);
380 if (inv_rbx) movptr(rbx, 0xDEAD);
381 if (inv_rcx) movptr(rcx, 0xDEAD);
382 if (inv_rdx) movptr(rdx, 0xDEAD);
383 if (inv_rsi) movptr(rsi, 0xDEAD);
384 if (inv_rdi) movptr(rdi, 0xDEAD);
385#endif
386}
387
388#endif // ifndef PRODUCT

/home/daniel/Projects/java/jdk/src/hotspot/share/asm/register.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_ASM_REGISTER_HPP
26#define SHARE_ASM_REGISTER_HPP
27
28#include "utilities/debug.hpp"
29#include "utilities/globalDefinitions.hpp"
30#include "utilities/macros.hpp"
31
32// Use AbstractRegister as shortcut
33class AbstractRegisterImpl;
34typedef AbstractRegisterImpl* AbstractRegister;
35
36
37// The super class for platform specific registers. Instead of using value objects,
38// registers are implemented as pointers. Subclassing is used so all registers can
39// use the debugging suport below. No virtual functions are used for efficiency.
40// They are canonicalized; i.e., registers are equal if their pointers are equal,
41// and vice versa. A concrete implementation may just map the register onto 'this'.
42
43class AbstractRegisterImpl {
44 protected:
45 int value() const { return (int)(intx)this; }
46};
47
48#define AS_REGISTER(type,name)((type)name_typeEnumValue) ((type)name##_##type##EnumValue)
49
50#define CONSTANT_REGISTER_DECLARATION(type, name, value)const type name = ((type)value); enum { name_typeEnumValue = (
value) }
\
51const type name = ((type)value); \
52enum { name##_##type##EnumValue = (value) }
53
54#define REGISTER_DECLARATION(type, name, value)const type name = ((type)value) \
55const type name = ((type)value)
56
57#define REGISTER_DEFINITION(type, name)
58
59#include CPU_HEADER(register)"register_x86.hpp"
60
61// Debugging support
62
63template<typename R, typename... Rx>
64inline void assert_different_registers(R first_register, Rx... more_registers) {
65#ifdef ASSERT1
66 const R regs[] = { first_register, more_registers... };
5
Initializing to a null pointer value
67 // Verify there are no equal entries.
68 for (size_t i = 0; i < ARRAY_SIZE(regs)sizeof(array_size_impl(regs)) - 1; ++i) {
6
'i' initialized to 0
7
Loop condition is true. Entering loop body
69 for (size_t j = i + 1; j < ARRAY_SIZE(regs)sizeof(array_size_impl(regs)); ++j) {
8
Loop condition is true. Entering loop body
70 assert(regs[i] != regs[j], "Multiple uses of register: %s", regs[i]->name())do { if (!(regs[i] != regs[j])) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/asm/register.hpp"
, 70, "assert(" "regs[i] != regs[j]" ") failed", "Multiple uses of register: %s"
, regs[i]->name()); ::breakpoint(); } } while (0)
;
9
Assuming the condition is false
10
Taking true branch
11
Called C++ object pointer is null
71 }
72 }
73#endif
74}
75
76#endif // SHARE_ASM_REGISTER_HPP