1 /*
2  * Copyright (c) 2013, Red Hat Inc.
3  * Copyright (c) 2003, 2016, Oracle and/or its affiliates.
4  * 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 "interpreter/interpreter.hpp"
29 #include "interpreter/interpreterRuntime.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "memory/universe.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.hpp"
37 #include "runtime/signature.hpp"
38 
39 #define __ _masm->
40 
41 // Implementation of SignatureHandlerGenerator
from()42 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
to()43 Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return sp; }
temp()44 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
45 
pass_int()46 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
47   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
48 
49   switch (_num_int_args) {
50   case 0:
51     __ ldr(c_rarg1, src);
52     _num_int_args++;
53     break;
54   case 1:
55     __ ldr(c_rarg2, src);
56     _num_int_args++;
57     break;
58   case 2:
59     __ ldr(c_rarg3, src);
60     _num_int_args++;
61     break;
62   case 3:
63     __ ldr(c_rarg4, src);
64     _num_int_args++;
65     break;
66   case 4:
67     __ ldr(c_rarg5, src);
68     _num_int_args++;
69     break;
70   case 5:
71     __ ldr(c_rarg6, src);
72     _num_int_args++;
73     break;
74   case 6:
75     __ ldr(c_rarg7, src);
76     _num_int_args++;
77     break;
78   default:
79     __ ldr(r0, src);
80     __ str(r0, Address(to(), _stack_offset));
81     _stack_offset += wordSize;
82     _num_int_args++;
83     break;
84   }
85 }
86 
pass_long()87 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
88   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
89 
90   switch (_num_int_args) {
91   case 0:
92     __ ldr(c_rarg1, src);
93     _num_int_args++;
94     break;
95   case 1:
96     __ ldr(c_rarg2, src);
97     _num_int_args++;
98     break;
99   case 2:
100     __ ldr(c_rarg3, src);
101     _num_int_args++;
102     break;
103   case 3:
104     __ ldr(c_rarg4, src);
105     _num_int_args++;
106     break;
107   case 4:
108     __ ldr(c_rarg5, src);
109     _num_int_args++;
110     break;
111   case 5:
112     __ ldr(c_rarg6, src);
113     _num_int_args++;
114     break;
115   case 6:
116     __ ldr(c_rarg7, src);
117     _num_int_args++;
118     break;
119   default:
120     __ ldr(r0, src);
121     __ str(r0, Address(to(), _stack_offset));
122     _stack_offset += wordSize;
123     _num_int_args++;
124     break;
125   }
126 }
127 
pass_float()128 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
129   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
130 
131   if (_num_fp_args < Argument::n_float_register_parameters_c) {
132     __ ldrs(as_FloatRegister(_num_fp_args++), src);
133   } else {
134     __ ldrw(r0, src);
135     __ strw(r0, Address(to(), _stack_offset));
136     _stack_offset += wordSize;
137     _num_fp_args++;
138   }
139 }
140 
pass_double()141 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
142   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
143 
144   if (_num_fp_args < Argument::n_float_register_parameters_c) {
145     __ ldrd(as_FloatRegister(_num_fp_args++), src);
146   } else {
147     __ ldr(r0, src);
148     __ str(r0, Address(to(), _stack_offset));
149     _stack_offset += wordSize;
150     _num_fp_args++;
151   }
152 }
153 
pass_object()154 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
155 
156   switch (_num_int_args) {
157   case 0:
158     assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
159     __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
160     _num_int_args++;
161     break;
162   case 1:
163     {
164       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
165       __ mov(c_rarg2, 0);
166       __ ldr(temp(), r0);
167       Label L;
168       __ cbz(temp(), L);
169       __ mov(c_rarg2, r0);
170       __ bind(L);
171       _num_int_args++;
172       break;
173     }
174   case 2:
175     {
176       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
177       __ mov(c_rarg3, 0);
178       __ ldr(temp(), r0);
179       Label L;
180       __ cbz(temp(), L);
181       __ mov(c_rarg3, r0);
182       __ bind(L);
183       _num_int_args++;
184       break;
185     }
186   case 3:
187     {
188       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
189       __ mov(c_rarg4, 0);
190       __ ldr(temp(), r0);
191       Label L;
192       __ cbz(temp(), L);
193       __ mov(c_rarg4, r0);
194       __ bind(L);
195       _num_int_args++;
196       break;
197     }
198   case 4:
199     {
200       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
201       __ mov(c_rarg5, 0);
202       __ ldr(temp(), r0);
203       Label L;
204       __ cbz(temp(), L);
205       __ mov(c_rarg5, r0);
206       __ bind(L);
207       _num_int_args++;
208       break;
209     }
210   case 5:
211     {
212       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
213       __ mov(c_rarg6, 0);
214       __ ldr(temp(), r0);
215       Label L;
216       __ cbz(temp(), L);
217       __ mov(c_rarg6, r0);
218       __ bind(L);
219       _num_int_args++;
220       break;
221     }
222   case 6:
223     {
224       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
225       __ mov(c_rarg7, 0);
226       __ ldr(temp(), r0);
227       Label L;
228       __ cbz(temp(), L);
229       __ mov(c_rarg7, r0);
230       __ bind(L);
231       _num_int_args++;
232       break;
233     }
234  default:
235    {
236       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
237       __ ldr(temp(), r0);
238       Label L;
239       __ cbnz(temp(), L);
240       __ mov(r0, zr);
241       __ bind(L);
242       __ str(r0, Address(to(), _stack_offset));
243       _stack_offset += wordSize;
244       _num_int_args++;
245       break;
246    }
247   }
248 }
249 
generate(uint64_t fingerprint)250 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
251   // generate code to handle arguments
252   iterate(fingerprint);
253 
254   // return result handler
255   __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
256   __ ret(lr);
257 
258   __ flush();
259 }
260 
261 
262 // Implementation of SignatureHandlerLibrary
263 
pd_set_handler(address handler)264 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
265 
266 
267 class SlowSignatureHandler
268   : public NativeSignatureIterator {
269  private:
270   address   _from;
271   intptr_t* _to;
272   intptr_t* _int_args;
273   intptr_t* _fp_args;
274   intptr_t* _fp_identifiers;
275   unsigned int _num_int_args;
276   unsigned int _num_fp_args;
277 
pass_int()278   virtual void pass_int()
279   {
280     jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
281     _from -= Interpreter::stackElementSize;
282 
283     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
284       *_int_args++ = from_obj;
285       _num_int_args++;
286     } else {
287       *_to++ = from_obj;
288       _num_int_args++;
289     }
290   }
291 
pass_long()292   virtual void pass_long()
293   {
294     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
295     _from -= 2*Interpreter::stackElementSize;
296 
297     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
298       *_int_args++ = from_obj;
299       _num_int_args++;
300     } else {
301       *_to++ = from_obj;
302       _num_int_args++;
303     }
304   }
305 
pass_object()306   virtual void pass_object()
307   {
308     intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
309     _from -= Interpreter::stackElementSize;
310 
311     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
312       *_int_args++ = (*from_addr == 0) ? 0 : (intptr_t)from_addr;
313       _num_int_args++;
314     } else {
315       *_to++ = (*from_addr == 0) ? 0 : (intptr_t) from_addr;
316       _num_int_args++;
317     }
318   }
319 
pass_float()320   virtual void pass_float()
321   {
322     jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
323     _from -= Interpreter::stackElementSize;
324 
325     if (_num_fp_args < Argument::n_float_register_parameters_c) {
326       *_fp_args++ = from_obj;
327       _num_fp_args++;
328     } else {
329       *_to++ = from_obj;
330       _num_fp_args++;
331     }
332   }
333 
pass_double()334   virtual void pass_double()
335   {
336     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
337     _from -= 2*Interpreter::stackElementSize;
338 
339     if (_num_fp_args < Argument::n_float_register_parameters_c) {
340       *_fp_args++ = from_obj;
341       *_fp_identifiers |= (1 << _num_fp_args); // mark as double
342       _num_fp_args++;
343     } else {
344       *_to++ = from_obj;
345       _num_fp_args++;
346     }
347   }
348 
349  public:
SlowSignatureHandler(methodHandle method,address from,intptr_t * to)350   SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
351     : NativeSignatureIterator(method)
352   {
353     _from = from;
354     _to   = to;
355 
356     _int_args = to - (method->is_static() ? 16 : 17);
357     _fp_args =  to - 8;
358     _fp_identifiers = to - 9;
359     *(int*) _fp_identifiers = 0;
360     _num_int_args = (method->is_static() ? 1 : 0);
361     _num_fp_args = 0;
362   }
363 };
364 
365 
366 IRT_ENTRY(address,
367           InterpreterRuntime::slow_signature_handler(JavaThread* thread,
368                                                      Method* method,
369                                                      intptr_t* from,
370                                                      intptr_t* to))
371   methodHandle m(thread, (Method*)method);
372   assert(m->is_native(), "sanity check");
373 
374   // handle arguments
375   SlowSignatureHandler ssh(m, (address)from, to);
376   ssh.iterate(UCONST64(-1));
377 
378   // return result handler
379   return Interpreter::result_handler(m->result_type());
380 IRT_END
381