1 /*
2 * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
4 * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 */
26
27 #include "asm/macroAssembler.inline.hpp"
28 #include "interpreter/interp_masm.hpp"
29 #include "interpreter/interpreter.hpp"
30 #include "interpreter/interpreterRuntime.hpp"
31 #include "memory/allocation.inline.hpp"
32 #include "oops/method.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "runtime/handles.inline.hpp"
35 #include "runtime/icache.hpp"
36 #include "runtime/interfaceSupport.inline.hpp"
37 #include "runtime/signature.hpp"
38
39 #define __ _masm->
40
41 // Implementation of SignatureHandlerGenerator
42 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
43 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; }
44 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
45
46 Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() {
47 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
48 return as_Register(_num_reg_int_args++ + c_rarg1->encoding());
49 }
50 return noreg;
51 }
52
53 FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() {
54 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
55 return as_FloatRegister(_num_reg_fp_args++);
56 }
57 return fnoreg;
58 }
59
60 // On macos/aarch64 native stack is packed, int/float are using only 4 bytes
61 // on stack. Natural alignment for types are still in place,
62 // for example double/long should be 8 bytes aligned.
63
64 int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset(unsigned elem_size) {
65 MACOS_ONLY(_stack_offset = align_up(_stack_offset, elem_size));
66 int ret = _stack_offset;
67 _stack_offset += NOT_MACOS(wordSize) MACOS_ONLY(elem_size);
68 return ret;
69 }
70
71 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
72 const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
73 _masm = new MacroAssembler(buffer);
74 _num_reg_int_args = (method->is_static() ? 1 : 0);
75 _num_reg_fp_args = 0;
76 _stack_offset = 0;
77 }
78
79 void InterpreterRuntime::SignatureHandlerGenerator::pass_byte() {
80 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
81
82 Register reg = next_gpr();
83 if (reg != noreg) {
84 __ ldr(reg, src);
85 } else {
86 __ ldrb(r0, src);
87 __ strb(r0, Address(to(), next_stack_offset(sizeof(jbyte))));
88 }
89 }
90
91 void InterpreterRuntime::SignatureHandlerGenerator::pass_short() {
92 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
93
94 Register reg = next_gpr();
95 if (reg != noreg) {
96 __ ldr(reg, src);
97 } else {
98 __ ldrh(r0, src);
99 __ strh(r0, Address(to(), next_stack_offset(sizeof(jshort))));
100 }
101 }
102
103 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
104 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
105
106 Register reg = next_gpr();
107 if (reg != noreg) {
108 __ ldr(reg, src);
109 } else {
110 __ ldrw(r0, src);
111 __ strw(r0, Address(to(), next_stack_offset(sizeof(jint))));
112 }
113 }
114
115 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
116 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
117
118 Register reg = next_gpr();
119 if (reg != noreg) {
120 __ ldr(reg, src);
121 } else {
122 __ ldr(r0, src);
123 __ str(r0, Address(to(), next_stack_offset(sizeof(jlong))));
124 }
125 }
126
127 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
128 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
129
130 FloatRegister reg = next_fpr();
131 if (reg != fnoreg) {
132 __ ldrs(reg, src);
133 } else {
134 __ ldrw(r0, src);
135 __ strw(r0, Address(to(), next_stack_offset(sizeof(jfloat))));
136 }
137 }
138
139 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
140 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
141
142 FloatRegister reg = next_fpr();
143 if (reg != fnoreg) {
144 __ ldrd(reg, src);
145 } else {
146 __ ldr(r0, src);
147 __ str(r0, Address(to(), next_stack_offset(sizeof(jdouble))));
148 }
149 }
150
151 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
152 Register reg = next_gpr();
153 if (reg == c_rarg1) {
154 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
155 __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
156 } else if (reg != noreg) {
157 __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
158 __ mov(reg, 0);
159 __ ldr(temp(), r0);
160 Label L;
161 __ cbz(temp(), L);
162 __ mov(reg, r0);
163 __ bind(L);
164 } else {
165 __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
166 __ ldr(temp(), r0);
167 Label L;
168 __ cbnz(temp(), L);
169 __ mov(r0, zr);
170 __ bind(L);
171 static_assert(sizeof(jobject) == wordSize, "");
172 __ str(r0, Address(to(), next_stack_offset(sizeof(jobject))));
173 }
174 }
175
176 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
177 // generate code to handle arguments
178 iterate(fingerprint);
179
180 // return result handler
181 __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
182 __ ret(lr);
183
184 __ flush();
185 }
186
187
188 // Implementation of SignatureHandlerLibrary
189
190 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
191
192
193 class SlowSignatureHandler
194 : public NativeSignatureIterator {
195 private:
196 address _from;
197 char* _to;
198 intptr_t* _int_args;
199 intptr_t* _fp_args;
200 intptr_t* _fp_identifiers;
201 unsigned int _num_reg_int_args;
202 unsigned int _num_reg_fp_args;
203
204 intptr_t* single_slot_addr() {
205 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
206 _from -= Interpreter::stackElementSize;
207 return from_addr;
208 }
209
210 intptr_t* double_slot_addr() {
211 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
212 _from -= 2*Interpreter::stackElementSize;
213 return from_addr;
214 }
215
216 int pass_gpr(intptr_t value) {
217 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
218 *_int_args++ = value;
219 return _num_reg_int_args++;
220 }
221 return -1;
222 }
223
224 int pass_fpr(intptr_t value) {
225 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
226 *_fp_args++ = value;
227 return _num_reg_fp_args++;
228 }
229 return -1;
230 }
231
232 template<typename T>
233 void pass_stack(T value) {
234 MACOS_ONLY(_to = align_up(_to, sizeof(value)));
235 *(T *)_to = value;
236 _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value));
237 }
238
239 virtual void pass_byte() {
240 jbyte value = *(jbyte*)single_slot_addr();
241 if (pass_gpr(value) < 0) {
242 pass_stack<>(value);
243 }
244 }
245
246 virtual void pass_short() {
247 jshort value = *(jshort*)single_slot_addr();
248 if (pass_gpr(value) < 0) {
249 pass_stack<>(value);
250 }
251 }
252
253 virtual void pass_int() {
254 jint value = *(jint*)single_slot_addr();
255 if (pass_gpr(value) < 0) {
256 pass_stack<>(value);
257 }
258 }
259
260 virtual void pass_long() {
261 intptr_t value = *double_slot_addr();
262 if (pass_gpr(value) < 0) {
263 pass_stack<>(value);
264 }
265 }
266
267 virtual void pass_object() {
268 intptr_t* addr = single_slot_addr();
269 intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr;
270 if (pass_gpr(value) < 0) {
271 pass_stack<>(value);
272 }
273 }
274
275 virtual void pass_float() {
276 jint value = *(jint*)single_slot_addr();
277 if (pass_fpr(value) < 0) {
278 pass_stack<>(value);
279 }
280 }
281
282 virtual void pass_double() {
283 intptr_t value = *double_slot_addr();
284 int arg = pass_fpr(value);
285 if (0 <= arg) {
286 *_fp_identifiers |= (1ull << arg); // mark as double
287 } else {
288 pass_stack<>(value);
289 }
290 }
291
292 public:
293 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
294 : NativeSignatureIterator(method)
295 {
296 _from = from;
297 _to = (char *)to;
298
299 _int_args = to - (method->is_static() ? 16 : 17);
300 _fp_args = to - 8;
301 _fp_identifiers = to - 9;
302 *(int*) _fp_identifiers = 0;
303 _num_reg_int_args = (method->is_static() ? 1 : 0);
304 _num_reg_fp_args = 0;
305 }
306
307 };
308
309
310 JRT_ENTRY(address,
311 InterpreterRuntime::slow_signature_handler(JavaThread* current,
312 Method* method,
313 intptr_t* from,
314 intptr_t* to))
315 methodHandle m(current, (Method*)method);
316 assert(m->is_native(), "sanity check");
317
318 // handle arguments
319 SlowSignatureHandler ssh(m, (address)from, to);
320 ssh.iterate((uint64_t)CONST64(-1));
321
322 // return result handler
323 return Interpreter::result_handler(m->result_type());
324 JRT_END