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