1 /*
  2  * Copyright (c) 2003, 2023, 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 "precompiled.hpp"
 28 #include "asm/macroAssembler.inline.hpp"
 29 #include "interpreter/interp_masm.hpp"
 30 #include "interpreter/interpreter.hpp"
 31 #include "interpreter/interpreterRuntime.hpp"
 32 #include "memory/allocation.inline.hpp"
 33 #include "oops/method.hpp"
 34 #include "oops/oop.inline.hpp"
 35 #include "runtime/handles.inline.hpp"
 36 #include "runtime/icache.hpp"
 37 #include "runtime/interfaceSupport.inline.hpp"
 38 #include "runtime/signature.hpp"
 39 
 40 #define __ _masm->
 41 
 42 // Implementation of SignatureHandlerGenerator
 43 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
 44 Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return sp; }
 45 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
 46 
 47 Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() {
 48   if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
 49     return as_Register(_num_reg_int_args++ + c_rarg1->encoding());
 50   }
 51   return noreg;
 52 }
 53 
 54 FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() {
 55   if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
 56     return as_FloatRegister(_num_reg_fp_args++);
 57   }
 58   return fnoreg;
 59 }
 60 
 61 // On macos/aarch64 native stack is packed, int/float are using only 4 bytes
 62 // on stack. Natural alignment for types are still in place,
 63 // for example double/long should be 8 bytes aligned.
 64 
 65 int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset(unsigned elem_size) {
 66   MACOS_ONLY(_stack_offset = align_up(_stack_offset, elem_size));
 67   int ret = _stack_offset;
 68   _stack_offset += NOT_MACOS(wordSize) MACOS_ONLY(elem_size);
 69   return ret;
 70 }
 71 
 72 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
 73       const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
 74   _masm = new MacroAssembler(buffer);
 75   _num_reg_int_args = (method->is_static() ? 1 : 0);
 76   _num_reg_fp_args = 0;
 77   _stack_offset = 0;
 78 }
 79 
 80 void InterpreterRuntime::SignatureHandlerGenerator::pass_byte() {
 81   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
 82 
 83   Register reg = next_gpr();
 84   if (reg != noreg) {
 85     __ ldr(reg, src);
 86   } else {
 87     __ ldrb(r0, src);
 88     __ strb(r0, Address(to(), next_stack_offset(sizeof(jbyte))));
 89   }
 90 }
 91 
 92 void InterpreterRuntime::SignatureHandlerGenerator::pass_short() {
 93   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
 94 
 95   Register reg = next_gpr();
 96   if (reg != noreg) {
 97     __ ldr(reg, src);
 98   } else {
 99     __ ldrh(r0, src);
100     __ strh(r0, Address(to(), next_stack_offset(sizeof(jshort))));
101   }
102 }
103 
104 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
105   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
106 
107   Register reg = next_gpr();
108   if (reg != noreg) {
109     __ ldr(reg, src);
110   } else {
111     __ ldrw(r0, src);
112     __ strw(r0, Address(to(), next_stack_offset(sizeof(jint))));
113   }
114 }
115 
116 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
117   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
118 
119   Register reg = next_gpr();
120   if (reg != noreg) {
121     __ ldr(reg, src);
122   } else {
123     __ ldr(r0, src);
124     __ str(r0, Address(to(), next_stack_offset(sizeof(jlong))));
125   }
126 }
127 
128 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
129   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
130 
131   FloatRegister reg = next_fpr();
132   if (reg != fnoreg) {
133     __ ldrs(reg, src);
134   } else {
135     __ ldrw(r0, src);
136     __ strw(r0, Address(to(), next_stack_offset(sizeof(jfloat))));
137   }
138 }
139 
140 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
141   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
142 
143   FloatRegister reg = next_fpr();
144   if (reg != fnoreg) {
145     __ ldrd(reg, src);
146   } else {
147     __ ldr(r0, src);
148     __ str(r0, Address(to(), next_stack_offset(sizeof(jdouble))));
149   }
150 }
151 
152 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
153   Register reg = next_gpr();
154   if (reg == c_rarg1) {
155     assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
156     __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
157   } else if (reg != noreg) {
158     __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
159     __ mov(reg, 0);
160     __ ldr(temp(), r0);
161     Label L;
162     __ cbz(temp(), L);
163     __ mov(reg, r0);
164     __ bind(L);
165   } else {
166     __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
167     __ ldr(temp(), r0);
168     Label L;
169     __ cbnz(temp(), L);
170     __ mov(r0, zr);
171     __ bind(L);
172     static_assert(sizeof(jobject) == wordSize, "");
173     __ str(r0, Address(to(), next_stack_offset(sizeof(jobject))));
174   }
175 }
176 
177 void InterpreterRuntime::SignatureHandlerGenerator::pass_valuetype() {
178    pass_object();
179 }
180 
181 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
182   // generate code to handle arguments
183   iterate(fingerprint);
184 
185   // return result handler
186   __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
187   __ ret(lr);
188 
189   __ flush();
190 }
191 
192 
193 // Implementation of SignatureHandlerLibrary
194 
195 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
196 
197 
198 class SlowSignatureHandler
199   : public NativeSignatureIterator {
200  private:
201   address   _from;
202   char*     _to;
203   intptr_t* _int_args;
204   intptr_t* _fp_args;
205   intptr_t* _fp_identifiers;
206   unsigned int _num_reg_int_args;
207   unsigned int _num_reg_fp_args;
208 
209   intptr_t* single_slot_addr() {
210     intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
211     _from -= Interpreter::stackElementSize;
212     return from_addr;
213   }
214 
215   intptr_t* double_slot_addr() {
216     intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
217     _from -= 2*Interpreter::stackElementSize;
218     return from_addr;
219   }
220 
221   int pass_gpr(intptr_t value) {
222     if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
223       *_int_args++ = value;
224       return _num_reg_int_args++;
225     }
226     return -1;
227   }
228 
229   int pass_fpr(intptr_t value) {
230     if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
231       *_fp_args++ = value;
232       return _num_reg_fp_args++;
233     }
234     return -1;
235   }
236 
237   template<typename T>
238   void pass_stack(T value) {
239     MACOS_ONLY(_to = align_up(_to, sizeof(value)));
240     *(T *)_to = value;
241     _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value));
242   }
243 
244   virtual void pass_byte() {
245     jbyte value = *(jbyte*)single_slot_addr();
246     if (pass_gpr(value) < 0) {
247       pass_stack<>(value);
248     }
249   }
250 
251   virtual void pass_short() {
252     jshort value = *(jshort*)single_slot_addr();
253     if (pass_gpr(value) < 0) {
254       pass_stack<>(value);
255     }
256   }
257 
258   virtual void pass_int() {
259     jint value = *(jint*)single_slot_addr();
260     if (pass_gpr(value) < 0) {
261       pass_stack<>(value);
262     }
263   }
264 
265   virtual void pass_valuetype() {
266     // values are handled with oops, like objects
267     pass_object();
268   }
269 
270   virtual void pass_long() {
271     intptr_t value = *double_slot_addr();
272     if (pass_gpr(value) < 0) {
273       pass_stack<>(value);
274     }
275   }
276 
277   virtual void pass_object() {
278     intptr_t* addr = single_slot_addr();
279     intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr;
280     if (pass_gpr(value) < 0) {
281       pass_stack<>(value);
282     }
283   }
284 
285   virtual void pass_float() {
286     jint value = *(jint*)single_slot_addr();
287     if (pass_fpr(value) < 0) {
288       pass_stack<>(value);
289     }
290   }
291 
292   virtual void pass_double() {
293     intptr_t value = *double_slot_addr();
294     int arg = pass_fpr(value);
295     if (0 <= arg) {
296       *_fp_identifiers |= (1ull << arg); // mark as double
297     } else {
298       pass_stack<>(value);
299     }
300   }
301 
302  public:
303   SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
304     : NativeSignatureIterator(method)
305   {
306     _from = from;
307     _to   = (char *)to;
308 
309     _int_args = to - (method->is_static() ? 16 : 17);
310     _fp_args =  to - 8;
311     _fp_identifiers = to - 9;
312     *(int*) _fp_identifiers = 0;
313     _num_reg_int_args = (method->is_static() ? 1 : 0);
314     _num_reg_fp_args = 0;
315   }
316 
317 };
318 
319 
320 JRT_ENTRY(address,
321           InterpreterRuntime::slow_signature_handler(JavaThread* current,
322                                                      Method* method,
323                                                      intptr_t* from,
324                                                      intptr_t* to))
325   methodHandle m(current, (Method*)method);
326   assert(m->is_native(), "sanity check");
327 
328   // handle arguments
329   SlowSignatureHandler ssh(m, (address)from, to);
330   ssh.iterate((uint64_t)CONST64(-1));
331 
332   // return result handler
333   return Interpreter::result_handler(m->result_type());
334 JRT_END