1/*
2 * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "interpreter/interp_masm.hpp"
27#include "interpreter/interpreter.hpp"
28#include "interpreter/interpreterRuntime.hpp"
29#include "memory/allocation.inline.hpp"
30#include "oops/method.hpp"
31#include "oops/oop.inline.hpp"
32#include "runtime/handles.inline.hpp"
33#include "runtime/icache.hpp"
34#include "runtime/interfaceSupport.inline.hpp"
35#include "runtime/signature.hpp"
36
37#define __ _masm->
38
39// Implementation of SignatureHandlerGenerator
40
41InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) :
42 NativeSignatureIterator(method) {
43 _masm = new MacroAssembler(buffer);
44#ifdef AMD64
45#ifdef _WIN64
46 _num_args = (method->is_static() ? 1 : 0);
47 _stack_offset = (Argument::n_int_register_parameters_c+1)* wordSize; // don't overwrite return address
48#else
49 _num_int_args = (method->is_static() ? 1 : 0);
50 _num_fp_args = 0;
51 _stack_offset = wordSize; // don't overwrite return address
52#endif // _WIN64
53#endif // AMD64
54}
55
56Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
57Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; }
58Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
59
60void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
61 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
62
63#ifdef _WIN64
64 switch (_num_args) {
65 case 0:
66 __ movl(c_rarg1, src);
67 _num_args++;
68 break;
69 case 1:
70 __ movl(c_rarg2, src);
71 _num_args++;
72 break;
73 case 2:
74 __ movl(c_rarg3, src);
75 _num_args++;
76 break;
77 default:
78 __ movl(rax, src);
79 __ movl(Address(to(), _stack_offset), rax);
80 _stack_offset += wordSize;
81 break;
82 }
83#else
84 switch (_num_int_args) {
85 case 0:
86 __ movl(c_rarg1, src);
87 _num_int_args++;
88 break;
89 case 1:
90 __ movl(c_rarg2, src);
91 _num_int_args++;
92 break;
93 case 2:
94 __ movl(c_rarg3, src);
95 _num_int_args++;
96 break;
97 case 3:
98 __ movl(c_rarg4, src);
99 _num_int_args++;
100 break;
101 case 4:
102 __ movl(c_rarg5, src);
103 _num_int_args++;
104 break;
105 default:
106 __ movl(rax, src);
107 __ movl(Address(to(), _stack_offset), rax);
108 _stack_offset += wordSize;
109 break;
110 }
111#endif
112}
113
114void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
115 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
116
117#ifdef _WIN64
118 switch (_num_args) {
119 case 0:
120 __ movptr(c_rarg1, src);
121 _num_args++;
122 break;
123 case 1:
124 __ movptr(c_rarg2, src);
125 _num_args++;
126 break;
127 case 2:
128 __ movptr(c_rarg3, src);
129 _num_args++;
130 break;
131 case 3:
132 default:
133 __ movptr(rax, src);
134 __ movptr(Address(to(), _stack_offset), rax);
135 _stack_offset += wordSize;
136 break;
137 }
138#else
139 switch (_num_int_args) {
140 case 0:
141 __ movptr(c_rarg1, src);
142 _num_int_args++;
143 break;
144 case 1:
145 __ movptr(c_rarg2, src);
146 _num_int_args++;
147 break;
148 case 2:
149 __ movptr(c_rarg3, src);
150 _num_int_args++;
151 break;
152 case 3:
153 __ movptr(c_rarg4, src);
154 _num_int_args++;
155 break;
156 case 4:
157 __ movptr(c_rarg5, src);
158 _num_int_args++;
159 break;
160 default:
161 __ movptr(rax, src);
162 __ movptr(Address(to(), _stack_offset), rax);
163 _stack_offset += wordSize;
164 break;
165 }
166#endif
167}
168
169void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
170 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
171
172#ifdef _WIN64
173 if (_num_args < Argument::n_float_register_parameters_c-1) {
174 __ movflt(as_XMMRegister(++_num_args), src);
175 } else {
176 __ movl(rax, src);
177 __ movl(Address(to(), _stack_offset), rax);
178 _stack_offset += wordSize;
179 }
180#else
181 if (_num_fp_args < Argument::n_float_register_parameters_c) {
182 __ movflt(as_XMMRegister(_num_fp_args++), src);
183 } else {
184 __ movl(rax, src);
185 __ movl(Address(to(), _stack_offset), rax);
186 _stack_offset += wordSize;
187 }
188#endif
189}
190
191void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
192 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
193
194#ifdef _WIN64
195 if (_num_args < Argument::n_float_register_parameters_c-1) {
196 __ movdbl(as_XMMRegister(++_num_args), src);
197 } else {
198 __ movptr(rax, src);
199 __ movptr(Address(to(), _stack_offset), rax);
200 _stack_offset += wordSize;
201 }
202#else
203 if (_num_fp_args < Argument::n_float_register_parameters_c) {
204 __ movdbl(as_XMMRegister(_num_fp_args++), src);
205 } else {
206 __ movptr(rax, src);
207 __ movptr(Address(to(), _stack_offset), rax);
208 _stack_offset += wordSize;
209 }
210#endif
211}
212
213void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
214 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
215
216#ifdef _WIN64
217 switch (_num_args) {
218 case 0:
219 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
220 __ lea(c_rarg1, src);
221 _num_args++;
222 break;
223 case 1:
224 __ lea(rax, src);
225 __ xorl(c_rarg2, c_rarg2);
226 __ cmpptr(src, 0);
227 __ cmov(Assembler::notEqual, c_rarg2, rax);
228 _num_args++;
229 break;
230 case 2:
231 __ lea(rax, src);
232 __ xorl(c_rarg3, c_rarg3);
233 __ cmpptr(src, 0);
234 __ cmov(Assembler::notEqual, c_rarg3, rax);
235 _num_args++;
236 break;
237 default:
238 __ lea(rax, src);
239 __ xorl(temp(), temp());
240 __ cmpptr(src, 0);
241 __ cmov(Assembler::notEqual, temp(), rax);
242 __ movptr(Address(to(), _stack_offset), temp());
243 _stack_offset += wordSize;
244 break;
245 }
246#else
247 switch (_num_int_args) {
248 case 0:
249 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
250 __ lea(c_rarg1, src);
251 _num_int_args++;
252 break;
253 case 1:
254 __ lea(rax, src);
255 __ xorl(c_rarg2, c_rarg2);
256 __ cmpptr(src, 0);
257 __ cmov(Assembler::notEqual, c_rarg2, rax);
258 _num_int_args++;
259 break;
260 case 2:
261 __ lea(rax, src);
262 __ xorl(c_rarg3, c_rarg3);
263 __ cmpptr(src, 0);
264 __ cmov(Assembler::notEqual, c_rarg3, rax);
265 _num_int_args++;
266 break;
267 case 3:
268 __ lea(rax, src);
269 __ xorl(c_rarg4, c_rarg4);
270 __ cmpptr(src, 0);
271 __ cmov(Assembler::notEqual, c_rarg4, rax);
272 _num_int_args++;
273 break;
274 case 4:
275 __ lea(rax, src);
276 __ xorl(c_rarg5, c_rarg5);
277 __ cmpptr(src, 0);
278 __ cmov(Assembler::notEqual, c_rarg5, rax);
279 _num_int_args++;
280 break;
281 default:
282 __ lea(rax, src);
283 __ xorl(temp(), temp());
284 __ cmpptr(src, 0);
285 __ cmov(Assembler::notEqual, temp(), rax);
286 __ movptr(Address(to(), _stack_offset), temp());
287 _stack_offset += wordSize;
288 break;
289 }
290#endif
291}
292
293void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
294 // generate code to handle arguments
295 iterate(fingerprint);
296
297 // return result handler
298 __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));
299 __ ret(0);
300
301 __ flush();
302}
303
304
305// Implementation of SignatureHandlerLibrary
306
307void SignatureHandlerLibrary::pd_set_handler(address handler) {}
308
309
310#ifdef _WIN64
311class SlowSignatureHandler
312 : public NativeSignatureIterator {
313 private:
314 address _from;
315 intptr_t* _to;
316 intptr_t* _reg_args;
317 intptr_t* _fp_identifiers;
318 unsigned int _num_args;
319
320 virtual void pass_int()
321 {
322 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
323 _from -= Interpreter::stackElementSize;
324
325 if (_num_args < Argument::n_int_register_parameters_c-1) {
326 *_reg_args++ = from_obj;
327 _num_args++;
328 } else {
329 *_to++ = from_obj;
330 }
331 }
332
333 virtual void pass_long()
334 {
335 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
336 _from -= 2*Interpreter::stackElementSize;
337
338 if (_num_args < Argument::n_int_register_parameters_c-1) {
339 *_reg_args++ = from_obj;
340 _num_args++;
341 } else {
342 *_to++ = from_obj;
343 }
344 }
345
346 virtual void pass_object()
347 {
348 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
349 _from -= Interpreter::stackElementSize;
350 if (_num_args < Argument::n_int_register_parameters_c-1) {
351 *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
352 _num_args++;
353 } else {
354 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
355 }
356 }
357
358 virtual void pass_float()
359 {
360 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
361 _from -= Interpreter::stackElementSize;
362
363 if (_num_args < Argument::n_float_register_parameters_c-1) {
364 assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
365 *_reg_args++ = from_obj;
366 *_fp_identifiers |= ((intptr_t)0x01 << (_num_args*2)); // mark as float
367 _num_args++;
368 } else {
369 *_to++ = from_obj;
370 }
371 }
372
373 virtual void pass_double()
374 {
375 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
376 _from -= 2*Interpreter::stackElementSize;
377
378 if (_num_args < Argument::n_float_register_parameters_c-1) {
379 assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
380 *_reg_args++ = from_obj;
381 *_fp_identifiers |= ((intptr_t)0x3 << (_num_args*2)); // mark as double
382 _num_args++;
383 } else {
384 *_to++ = from_obj;
385 }
386 }
387
388 public:
389 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
390 : NativeSignatureIterator(method)
391 {
392 _from = from;
393 _to = to;
394
395 _reg_args = to - (method->is_static() ? 4 : 5);
396 _fp_identifiers = to - 2;
397 _to = _to + 4; // Windows reserves stack space for register arguments
398 *(int*) _fp_identifiers = 0;
399 _num_args = (method->is_static() ? 1 : 0);
400 }
401};
402#else
403class SlowSignatureHandler
404 : public NativeSignatureIterator {
405 private:
406 address _from;
407 intptr_t* _to;
408 intptr_t* _int_args;
409 intptr_t* _fp_args;
410 intptr_t* _fp_identifiers;
411 unsigned int _num_int_args;
412 unsigned int _num_fp_args;
413
414 virtual void pass_int()
415 {
416 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
417 _from -= Interpreter::stackElementSize;
418
419 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
420 *_int_args++ = from_obj;
421 _num_int_args++;
422 } else {
423 *_to++ = from_obj;
424 }
425 }
426
427 virtual void pass_long()
428 {
429 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
430 _from -= 2*Interpreter::stackElementSize;
431
432 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
433 *_int_args++ = from_obj;
434 _num_int_args++;
435 } else {
436 *_to++ = from_obj;
437 }
438 }
439
440 virtual void pass_object()
441 {
442 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
443 _from -= Interpreter::stackElementSize;
444
445 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
446 *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
447 _num_int_args++;
448 } else {
449 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
450 }
451 }
452
453 virtual void pass_float()
454 {
455 jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
456 _from -= Interpreter::stackElementSize;
457
458 if (_num_fp_args < Argument::n_float_register_parameters_c) {
459 *_fp_args++ = from_obj;
460 _num_fp_args++;
461 } else {
462 *_to++ = from_obj;
463 }
464 }
465
466 virtual void pass_double()
467 {
468 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
469 _from -= 2*Interpreter::stackElementSize;
470
471 if (_num_fp_args < Argument::n_float_register_parameters_c) {
472 *_fp_args++ = from_obj;
473 *_fp_identifiers |= (1 << _num_fp_args); // mark as double
474 _num_fp_args++;
475 } else {
476 *_to++ = from_obj;
477 }
478 }
479
480 public:
481 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
482 : NativeSignatureIterator(method)
483 {
484 _from = from;
485 _to = to;
486
487 _int_args = to - (method->is_static() ? 14 : 15);
488 _fp_args = to - 9;
489 _fp_identifiers = to - 10;
490 *(int*) _fp_identifiers = 0;
491 _num_int_args = (method->is_static() ? 1 : 0);
492 _num_fp_args = 0;
493 }
494};
495#endif
496
497
498JRT_ENTRY(address,
499 InterpreterRuntime::slow_signature_handler(JavaThread* thread,
500 Method* method,
501 intptr_t* from,
502 intptr_t* to))
503 methodHandle m(thread, (Method*)method);
504 assert(m->is_native(), "sanity check");
505
506 // handle arguments
507 SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));
508
509 // return result handler
510 return Interpreter::result_handler(m->result_type());
511JRT_END
512