interpreterRT_x86_64.cpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 2003, 2012, 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/interpreter.hpp"
27#include "interpreter/interpreterRuntime.hpp"
28#include "memory/allocation.inline.hpp"
29#include "memory/universe.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.hpp"
35#include "runtime/signature.hpp"
36
37#define __ _masm->
38
39// Implementation of SignatureHandlerGenerator
40
41Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
42Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return rsp; }
43Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
44
45void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
46  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
47
48#ifdef _WIN64
49  switch (_num_args) {
50  case 0:
51    __ movl(c_rarg1, src);
52    _num_args++;
53    break;
54  case 1:
55    __ movl(c_rarg2, src);
56    _num_args++;
57    break;
58  case 2:
59    __ movl(c_rarg3, src);
60    _num_args++;
61    break;
62  default:
63    __ movl(rax, src);
64    __ movl(Address(to(), _stack_offset), rax);
65    _stack_offset += wordSize;
66    break;
67  }
68#else
69  switch (_num_int_args) {
70  case 0:
71    __ movl(c_rarg1, src);
72    _num_int_args++;
73    break;
74  case 1:
75    __ movl(c_rarg2, src);
76    _num_int_args++;
77    break;
78  case 2:
79    __ movl(c_rarg3, src);
80    _num_int_args++;
81    break;
82  case 3:
83    __ movl(c_rarg4, src);
84    _num_int_args++;
85    break;
86  case 4:
87    __ movl(c_rarg5, src);
88    _num_int_args++;
89    break;
90  default:
91    __ movl(rax, src);
92    __ movl(Address(to(), _stack_offset), rax);
93    _stack_offset += wordSize;
94    break;
95  }
96#endif
97}
98
99void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
100  const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
101
102#ifdef _WIN64
103  switch (_num_args) {
104  case 0:
105    __ movptr(c_rarg1, src);
106    _num_args++;
107    break;
108  case 1:
109    __ movptr(c_rarg2, src);
110    _num_args++;
111    break;
112  case 2:
113    __ movptr(c_rarg3, src);
114    _num_args++;
115    break;
116  case 3:
117  default:
118    __ movptr(rax, src);
119    __ movptr(Address(to(), _stack_offset), rax);
120    _stack_offset += wordSize;
121    break;
122  }
123#else
124  switch (_num_int_args) {
125  case 0:
126    __ movptr(c_rarg1, src);
127    _num_int_args++;
128    break;
129  case 1:
130    __ movptr(c_rarg2, src);
131    _num_int_args++;
132    break;
133  case 2:
134    __ movptr(c_rarg3, src);
135    _num_int_args++;
136    break;
137  case 3:
138    __ movptr(c_rarg4, src);
139    _num_int_args++;
140    break;
141  case 4:
142    __ movptr(c_rarg5, src);
143    _num_int_args++;
144    break;
145  default:
146    __ movptr(rax, src);
147    __ movptr(Address(to(), _stack_offset), rax);
148    _stack_offset += wordSize;
149    break;
150  }
151#endif
152}
153
154void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
155  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
156
157#ifdef _WIN64
158  if (_num_args < Argument::n_float_register_parameters_c-1) {
159    __ movflt(as_XMMRegister(++_num_args), src);
160  } else {
161    __ movl(rax, src);
162    __ movl(Address(to(), _stack_offset), rax);
163    _stack_offset += wordSize;
164  }
165#else
166  if (_num_fp_args < Argument::n_float_register_parameters_c) {
167    __ movflt(as_XMMRegister(_num_fp_args++), src);
168  } else {
169    __ movl(rax, src);
170    __ movl(Address(to(), _stack_offset), rax);
171    _stack_offset += wordSize;
172  }
173#endif
174}
175
176void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
177  const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
178
179#ifdef _WIN64
180  if (_num_args < Argument::n_float_register_parameters_c-1) {
181    __ movdbl(as_XMMRegister(++_num_args), src);
182  } else {
183    __ movptr(rax, src);
184    __ movptr(Address(to(), _stack_offset), rax);
185    _stack_offset += wordSize;
186  }
187#else
188  if (_num_fp_args < Argument::n_float_register_parameters_c) {
189    __ movdbl(as_XMMRegister(_num_fp_args++), src);
190  } else {
191    __ movptr(rax, src);
192    __ movptr(Address(to(), _stack_offset), rax);
193    _stack_offset += wordSize;
194  }
195#endif
196}
197
198void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
199  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
200
201#ifdef _WIN64
202  switch (_num_args) {
203  case 0:
204    assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
205    __ lea(c_rarg1, src);
206    _num_args++;
207    break;
208  case 1:
209    __ lea(rax, src);
210    __ xorl(c_rarg2, c_rarg2);
211    __ cmpptr(src, 0);
212    __ cmov(Assembler::notEqual, c_rarg2, rax);
213    _num_args++;
214    break;
215  case 2:
216    __ lea(rax, src);
217    __ xorl(c_rarg3, c_rarg3);
218    __ cmpptr(src, 0);
219    __ cmov(Assembler::notEqual, c_rarg3, rax);
220    _num_args++;
221    break;
222  default:
223    __ lea(rax, src);
224    __ xorl(temp(), temp());
225    __ cmpptr(src, 0);
226    __ cmov(Assembler::notEqual, temp(), rax);
227    __ movptr(Address(to(), _stack_offset), temp());
228    _stack_offset += wordSize;
229    break;
230  }
231#else
232  switch (_num_int_args) {
233  case 0:
234    assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
235    __ lea(c_rarg1, src);
236    _num_int_args++;
237    break;
238  case 1:
239    __ lea(rax, src);
240    __ xorl(c_rarg2, c_rarg2);
241    __ cmpptr(src, 0);
242    __ cmov(Assembler::notEqual, c_rarg2, rax);
243    _num_int_args++;
244    break;
245  case 2:
246    __ lea(rax, src);
247    __ xorl(c_rarg3, c_rarg3);
248    __ cmpptr(src, 0);
249    __ cmov(Assembler::notEqual, c_rarg3, rax);
250    _num_int_args++;
251    break;
252  case 3:
253    __ lea(rax, src);
254    __ xorl(c_rarg4, c_rarg4);
255    __ cmpptr(src, 0);
256    __ cmov(Assembler::notEqual, c_rarg4, rax);
257    _num_int_args++;
258    break;
259  case 4:
260    __ lea(rax, src);
261    __ xorl(c_rarg5, c_rarg5);
262    __ cmpptr(src, 0);
263    __ cmov(Assembler::notEqual, c_rarg5, rax);
264    _num_int_args++;
265    break;
266  default:
267    __ lea(rax, src);
268    __ xorl(temp(), temp());
269    __ cmpptr(src, 0);
270    __ cmov(Assembler::notEqual, temp(), rax);
271    __ movptr(Address(to(), _stack_offset), temp());
272    _stack_offset += wordSize;
273    break;
274  }
275#endif
276}
277
278void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
279  // generate code to handle arguments
280  iterate(fingerprint);
281
282  // return result handler
283  __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));
284  __ ret(0);
285
286  __ flush();
287}
288
289
290// Implementation of SignatureHandlerLibrary
291
292void SignatureHandlerLibrary::pd_set_handler(address handler) {}
293
294
295#ifdef _WIN64
296class SlowSignatureHandler
297  : public NativeSignatureIterator {
298 private:
299  address   _from;
300  intptr_t* _to;
301  intptr_t* _reg_args;
302  intptr_t* _fp_identifiers;
303  unsigned int _num_args;
304
305  virtual void pass_int()
306  {
307    jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
308    _from -= Interpreter::stackElementSize;
309
310    if (_num_args < Argument::n_int_register_parameters_c-1) {
311      *_reg_args++ = from_obj;
312      _num_args++;
313    } else {
314      *_to++ = from_obj;
315    }
316  }
317
318  virtual void pass_long()
319  {
320    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
321    _from -= 2*Interpreter::stackElementSize;
322
323    if (_num_args < Argument::n_int_register_parameters_c-1) {
324      *_reg_args++ = from_obj;
325      _num_args++;
326    } else {
327      *_to++ = from_obj;
328    }
329  }
330
331  virtual void pass_object()
332  {
333    intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
334    _from -= Interpreter::stackElementSize;
335    if (_num_args < Argument::n_int_register_parameters_c-1) {
336      *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
337      _num_args++;
338    } else {
339      *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
340    }
341  }
342
343  virtual void pass_float()
344  {
345    jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
346    _from -= Interpreter::stackElementSize;
347
348    if (_num_args < Argument::n_float_register_parameters_c-1) {
349      *_reg_args++ = from_obj;
350      *_fp_identifiers |= (intptr_t)(0x01 << (_num_args*2)); // mark as float
351      _num_args++;
352    } else {
353      *_to++ = from_obj;
354    }
355  }
356
357  virtual void pass_double()
358  {
359    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
360    _from -= 2*Interpreter::stackElementSize;
361
362    if (_num_args < Argument::n_float_register_parameters_c-1) {
363      *_reg_args++ = from_obj;
364      *_fp_identifiers |= (intptr_t)(0x3 << (_num_args*2)); // mark as double
365      _num_args++;
366    } else {
367      *_to++ = from_obj;
368    }
369  }
370
371 public:
372  SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
373    : NativeSignatureIterator(method)
374  {
375    _from = from;
376    _to   = to;
377
378    _reg_args = to - (method->is_static() ? 4 : 5);
379    _fp_identifiers = to - 2;
380    _to = _to + 4;  // Windows reserves stack space for register arguments
381    *(int*) _fp_identifiers = 0;
382    _num_args = (method->is_static() ? 1 : 0);
383  }
384};
385#else
386class SlowSignatureHandler
387  : public NativeSignatureIterator {
388 private:
389  address   _from;
390  intptr_t* _to;
391  intptr_t* _int_args;
392  intptr_t* _fp_args;
393  intptr_t* _fp_identifiers;
394  unsigned int _num_int_args;
395  unsigned int _num_fp_args;
396
397  virtual void pass_int()
398  {
399    jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
400    _from -= Interpreter::stackElementSize;
401
402    if (_num_int_args < Argument::n_int_register_parameters_c-1) {
403      *_int_args++ = from_obj;
404      _num_int_args++;
405    } else {
406      *_to++ = from_obj;
407    }
408  }
409
410  virtual void pass_long()
411  {
412    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
413    _from -= 2*Interpreter::stackElementSize;
414
415    if (_num_int_args < Argument::n_int_register_parameters_c-1) {
416      *_int_args++ = from_obj;
417      _num_int_args++;
418    } else {
419      *_to++ = from_obj;
420    }
421  }
422
423  virtual void pass_object()
424  {
425    intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
426    _from -= Interpreter::stackElementSize;
427
428    if (_num_int_args < Argument::n_int_register_parameters_c-1) {
429      *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
430      _num_int_args++;
431    } else {
432      *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
433    }
434  }
435
436  virtual void pass_float()
437  {
438    jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
439    _from -= Interpreter::stackElementSize;
440
441    if (_num_fp_args < Argument::n_float_register_parameters_c) {
442      *_fp_args++ = from_obj;
443      _num_fp_args++;
444    } else {
445      *_to++ = from_obj;
446    }
447  }
448
449  virtual void pass_double()
450  {
451    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
452    _from -= 2*Interpreter::stackElementSize;
453
454    if (_num_fp_args < Argument::n_float_register_parameters_c) {
455      *_fp_args++ = from_obj;
456      *_fp_identifiers |= (1 << _num_fp_args); // mark as double
457      _num_fp_args++;
458    } else {
459      *_to++ = from_obj;
460    }
461  }
462
463 public:
464  SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
465    : NativeSignatureIterator(method)
466  {
467    _from = from;
468    _to   = to;
469
470    _int_args = to - (method->is_static() ? 14 : 15);
471    _fp_args =  to - 9;
472    _fp_identifiers = to - 10;
473    *(int*) _fp_identifiers = 0;
474    _num_int_args = (method->is_static() ? 1 : 0);
475    _num_fp_args = 0;
476  }
477};
478#endif
479
480
481IRT_ENTRY(address,
482          InterpreterRuntime::slow_signature_handler(JavaThread* thread,
483                                                     Method* method,
484                                                     intptr_t* from,
485                                                     intptr_t* to))
486  methodHandle m(thread, (Method*)method);
487  assert(m->is_native(), "sanity check");
488
489  // handle arguments
490  SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
491
492  // return result handler
493  return Interpreter::result_handler(m->result_type());
494IRT_END
495