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