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 | |
41 | InterpreterRuntime::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 | |
56 | Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; } |
57 | Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; } |
58 | Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } |
59 | |
60 | void 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 | |
114 | void 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 | |
169 | void 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 | |
191 | void 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 | |
213 | void 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 | |
293 | void 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 | |
307 | void SignatureHandlerLibrary::pd_set_handler(address handler) {} |
308 | |
309 | |
310 | #ifdef _WIN64 |
311 | class 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 |
403 | class 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 | |
498 | JRT_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()); |
511 | JRT_END |
512 | |