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