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::pass_valuetype() {
177 pass_object();
178 }
179
180 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
181 // generate code to handle arguments
182 iterate(fingerprint);
183
184 // return result handler
185 __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
186 __ ret(lr);
187
188 __ flush();
189 }
190
191
192 // Implementation of SignatureHandlerLibrary
193
194 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
195
196
197 class SlowSignatureHandler
198 : public NativeSignatureIterator {
199 private:
200 address _from;
201 char* _to;
202 intptr_t* _int_args;
203 intptr_t* _fp_args;
204 intptr_t* _fp_identifiers;
205 unsigned int _num_reg_int_args;
206 unsigned int _num_reg_fp_args;
207
208 intptr_t* single_slot_addr() {
209 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
210 _from -= Interpreter::stackElementSize;
211 return from_addr;
212 }
213
214 intptr_t* double_slot_addr() {
215 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
216 _from -= 2*Interpreter::stackElementSize;
217 return from_addr;
218 }
219
220 int pass_gpr(intptr_t value) {
221 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
222 *_int_args++ = value;
223 return _num_reg_int_args++;
224 }
225 return -1;
226 }
227
228 int pass_fpr(intptr_t value) {
229 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
230 *_fp_args++ = value;
231 return _num_reg_fp_args++;
232 }
233 return -1;
234 }
235
236 template<typename T>
237 void pass_stack(T value) {
238 MACOS_ONLY(_to = align_up(_to, sizeof(value)));
239 *(T *)_to = value;
240 _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value));
241 }
242
243 virtual void pass_byte() {
244 jbyte value = *(jbyte*)single_slot_addr();
245 if (pass_gpr(value) < 0) {
246 pass_stack<>(value);
247 }
248 }
249
250 virtual void pass_short() {
251 jshort value = *(jshort*)single_slot_addr();
252 if (pass_gpr(value) < 0) {
253 pass_stack<>(value);
254 }
255 }
256
257 virtual void pass_int() {
258 jint value = *(jint*)single_slot_addr();
259 if (pass_gpr(value) < 0) {
260 pass_stack<>(value);
261 }
262 }
263
264 virtual void pass_valuetype() {
265 // values are handled with oops, like objects
266 pass_object();
267 }
268
269 virtual void pass_long() {
270 intptr_t value = *double_slot_addr();
271 if (pass_gpr(value) < 0) {
272 pass_stack<>(value);
273 }
274 }
275
276 virtual void pass_object() {
277 intptr_t* addr = single_slot_addr();
278 intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr;
279 if (pass_gpr(value) < 0) {
280 pass_stack<>(value);
281 }
282 }
283
284 virtual void pass_float() {
285 jint value = *(jint*)single_slot_addr();
286 if (pass_fpr(value) < 0) {
287 pass_stack<>(value);
288 }
289 }
290
291 virtual void pass_double() {
292 intptr_t value = *double_slot_addr();
293 int arg = pass_fpr(value);
294 if (0 <= arg) {
295 *_fp_identifiers |= (1ull << arg); // mark as double
296 } else {
297 pass_stack<>(value);
298 }
299 }
300
301 public:
302 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
303 : NativeSignatureIterator(method)
304 {
305 _from = from;
306 _to = (char *)to;
307
308 _int_args = to - (method->is_static() ? 16 : 17);
309 _fp_args = to - 8;
310 _fp_identifiers = to - 9;
311 *(int*) _fp_identifiers = 0;
312 _num_reg_int_args = (method->is_static() ? 1 : 0);
313 _num_reg_fp_args = 0;
314 }
315
316 };
317
318
319 JRT_ENTRY(address,
320 InterpreterRuntime::slow_signature_handler(JavaThread* current,
321 Method* method,
322 intptr_t* from,
323 intptr_t* to))
324 methodHandle m(current, (Method*)method);
325 assert(m->is_native(), "sanity check");
326
327 // handle arguments
328 SlowSignatureHandler ssh(m, (address)from, to);
329 ssh.iterate((uint64_t)CONST64(-1));
330
331 // return result handler
332 return Interpreter::result_handler(m->result_type());
333 JRT_END