1 /*
2 * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2025 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "asm/macroAssembler.inline.hpp"
27 #include "c1/c1_MacroAssembler.hpp"
28 #include "c1/c1_Runtime1.hpp"
29 #include "gc/shared/collectedHeap.hpp"
30 #include "gc/shared/tlab_globals.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "oops/arrayOop.hpp"
33 #include "oops/markWord.hpp"
34 #include "runtime/basicLock.hpp"
35 #include "runtime/os.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/stubRoutines.hpp"
38 #include "utilities/align.hpp"
39 #include "utilities/macros.hpp"
40 #include "utilities/powerOfTwo.hpp"
41
42
43 void C1_MacroAssembler::explicit_null_check(Register base) {
44 Unimplemented();
45 }
46
47
48 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
49 const Register return_pc = R20;
50 mflr(return_pc);
51
52 // Make sure there is enough stack space for this method's activation.
53 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
54 generate_stack_overflow_check(bang_size_in_bytes);
55
56 std(return_pc, _abi0(lr), R1_SP); // SP->lr = return_pc
57 push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes
58
59 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
60 bs->nmethod_entry_barrier(this, R20);
61 }
62
63
64 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
65 if (breakAtEntry) illtrap();
66 // build frame
67 }
68
69
70 void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) {
71 assert_different_registers(Rmark, Roop, Rbox, Rscratch);
72
73 Label done, cas_failed, slow_int;
74
75 // The following move must be the first instruction of emitted since debug
76 // information may be generated for it.
77 // Load object header.
78 ld(Rmark, oopDesc::mark_offset_in_bytes(), Roop);
79
80 verify_oop(Roop, FILE_AND_LINE);
116
117 void C1_MacroAssembler::try_allocate(
118 Register obj, // result: pointer to object after successful allocation
119 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
120 int con_size_in_bytes, // object size in bytes if known at compile time
121 Register t1, // temp register
122 Register t2, // temp register
123 Label& slow_case // continuation point if fast allocation fails
124 ) {
125 if (UseTLAB) {
126 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
127 } else {
128 b(slow_case);
129 }
130 }
131
132
133 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
134 assert_different_registers(obj, klass, len, t1, t2);
135
136 if (UseCompactObjectHeaders) {
137 ld(t1, in_bytes(Klass::prototype_header_offset()), klass);
138 std(t1, oopDesc::mark_offset_in_bytes(), obj);
139 } else {
140 load_const_optimized(t1, (intx)markWord::prototype().value());
141 std(t1, oopDesc::mark_offset_in_bytes(), obj);
142 store_klass(obj, klass);
143 }
144
145 if (len->is_valid()) {
146 stw(len, arrayOopDesc::length_offset_in_bytes(), obj);
147 } else if (!UseCompactObjectHeaders) {
148 // Otherwise length is in the class gap.
149 store_klass_gap(obj);
150 }
151 }
152
153
154 void C1_MacroAssembler::initialize_body(Register base, Register index) {
155 assert_different_registers(base, index);
156 srdi(index, index, LogBytesPerWord);
157 clear_memory_doubleword(base, index);
158 }
159
160 void C1_MacroAssembler::initialize_body(Register obj, Register tmp1, Register tmp2,
161 int obj_size_in_bytes, int hdr_size_in_bytes) {
315 Label not_null;
316 cmpdi(CR0, r, 0);
317 bne(CR0, not_null);
318 stop("non-null oop required");
319 bind(not_null);
320 verify_oop(r, FILE_AND_LINE);
321 }
322
323 #endif // PRODUCT
324
325 void C1_MacroAssembler::null_check(Register r, Label* Lnull) {
326 if (TrapBasedNullChecks) { // SIGTRAP based
327 trap_null_check(r);
328 } else { // explicit
329 //const address exception_entry = Runtime1::entry_for(StubId::c1_throw_null_pointer_exception_id);
330 assert(Lnull != nullptr, "must have Label for explicit check");
331 cmpdi(CR0, r, 0);
332 bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CR0, Assembler::equal), *Lnull);
333 }
334 }
|
1 /*
2 * Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2026 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "asm/macroAssembler.inline.hpp"
27 #include "c1/c1_MacroAssembler.hpp"
28 #include "c1/c1_Runtime1.hpp"
29 #include "gc/shared/collectedHeap.hpp"
30 #include "gc/shared/barrierSet.hpp"
31 #include "gc/shared/barrierSetAssembler.hpp"
32 #include "gc/shared/tlab_globals.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "oops/arrayOop.hpp"
35 #include "oops/markWord.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/basicLock.hpp"
38 #include "runtime/os.hpp"
39 #include "runtime/sharedRuntime.hpp"
40 #include "runtime/stubRoutines.hpp"
41 #include "utilities/align.hpp"
42 #include "utilities/macros.hpp"
43 #include "utilities/powerOfTwo.hpp"
44
45
46 void C1_MacroAssembler::explicit_null_check(Register base) {
47 Unimplemented();
48 }
49
50
51 void C1_MacroAssembler::build_frame_helper(int frame_size_in_bytes, int sp_offset_for_orig_pc, int sp_inc, bool reset_orig_pc, bool needs_stack_repair) {
52 const Register return_pc = R20;
53 mflr(return_pc);
54 std(return_pc, _abi0(lr), R1_SP); // SP->lr = return_pc
55 push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes
56
57 if (needs_stack_repair) {
58 // Save stack increment (also account for fixed framesize and rbp)
59 Unimplemented();
60 }
61 if (reset_orig_pc) {
62 // Zero orig_pc to detect deoptimization during buffering in the entry points
63 li(R0, 0);
64 untested("build_frame_helper reset_orig_pc");
65 std(R0, sp_offset_for_orig_pc, R1_SP);
66 }
67 }
68
69
70 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes,
71 int sp_offset_for_orig_pc,
72 bool needs_stack_repair, bool has_scalarized_args,
73 Label* verified_inline_entry_label) {
74 // Make sure there is enough stack space for this method's activation.
75 assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
76 generate_stack_overflow_check(bang_size_in_bytes);
77
78 build_frame_helper(frame_size_in_bytes, sp_offset_for_orig_pc, 0, has_scalarized_args, needs_stack_repair);
79
80 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
81 bs->nmethod_entry_barrier(this, R20);
82
83 if (verified_inline_entry_label != nullptr) {
84 // Jump here from the scalarized entry points that already created the frame.
85 bind(*verified_inline_entry_label);
86 }
87 }
88
89
90 void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
91 if (breakAtEntry) illtrap();
92 // build frame
93 }
94
95
96 void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) {
97 assert_different_registers(Rmark, Roop, Rbox, Rscratch);
98
99 Label done, cas_failed, slow_int;
100
101 // The following move must be the first instruction of emitted since debug
102 // information may be generated for it.
103 // Load object header.
104 ld(Rmark, oopDesc::mark_offset_in_bytes(), Roop);
105
106 verify_oop(Roop, FILE_AND_LINE);
142
143 void C1_MacroAssembler::try_allocate(
144 Register obj, // result: pointer to object after successful allocation
145 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
146 int con_size_in_bytes, // object size in bytes if known at compile time
147 Register t1, // temp register
148 Register t2, // temp register
149 Label& slow_case // continuation point if fast allocation fails
150 ) {
151 if (UseTLAB) {
152 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
153 } else {
154 b(slow_case);
155 }
156 }
157
158
159 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
160 assert_different_registers(obj, klass, len, t1, t2);
161
162 if (UseCompactObjectHeaders || Arguments::is_valhalla_enabled()) {
163 // COH: Markword contains class pointer which is only known at runtime.
164 // Valhalla: Could have value class which has a different prototype header to a normal object.
165 // In both cases, we need to fetch dynamically.
166 ld(t1, in_bytes(Klass::prototype_header_offset()), klass);
167 } else {
168 // Otherwise: Can use the statically computed prototype header which is the same for every object.
169 load_const_optimized(t1, (intx)markWord::prototype().value());
170 }
171 std(t1, oopDesc::mark_offset_in_bytes(), obj);
172
173 if (!UseCompactObjectHeaders) {
174 // COH: Markword already contains class pointer. Nothing else to do.
175 // Otherwise: Store encoded klass pointer following the markword
176 store_klass(obj, klass);
177 }
178
179 if (len->is_valid()) {
180 stw(len, arrayOopDesc::length_offset_in_bytes(), obj);
181 } else if (!UseCompactObjectHeaders) {
182 // Otherwise length is in the class gap.
183 store_klass_gap(obj);
184 }
185 }
186
187
188 void C1_MacroAssembler::initialize_body(Register base, Register index) {
189 assert_different_registers(base, index);
190 srdi(index, index, LogBytesPerWord);
191 clear_memory_doubleword(base, index);
192 }
193
194 void C1_MacroAssembler::initialize_body(Register obj, Register tmp1, Register tmp2,
195 int obj_size_in_bytes, int hdr_size_in_bytes) {
349 Label not_null;
350 cmpdi(CR0, r, 0);
351 bne(CR0, not_null);
352 stop("non-null oop required");
353 bind(not_null);
354 verify_oop(r, FILE_AND_LINE);
355 }
356
357 #endif // PRODUCT
358
359 void C1_MacroAssembler::null_check(Register r, Label* Lnull) {
360 if (TrapBasedNullChecks) { // SIGTRAP based
361 trap_null_check(r);
362 } else { // explicit
363 //const address exception_entry = Runtime1::entry_for(StubId::c1_throw_null_pointer_exception_id);
364 assert(Lnull != nullptr, "must have Label for explicit check");
365 cmpdi(CR0, r, 0);
366 bc_far_optimized(Assembler::bcondCRbiIs1, bi0(CR0, Assembler::equal), *Lnull);
367 }
368 }
369
370 int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature* ces, int frame_size_in_bytes, int bang_size_in_bytes, int sp_offset_for_orig_pc, Label& verified_inline_entry_label, bool is_inline_ro_entry) {
371 Unimplemented();
372 }
373
|