1/*
2 * Copyright (c) 2008, 2017, 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#ifdef SHARING_FAST_NATIVE_FINGERPRINTS
40// mapping from SignatureIterator param to (common) type of parsing
41static const u1 shared_type[] = {
42  (u1) SignatureIterator::int_parm, // bool
43  (u1) SignatureIterator::int_parm, // byte
44  (u1) SignatureIterator::int_parm, // char
45  (u1) SignatureIterator::int_parm, // short
46  (u1) SignatureIterator::int_parm, // int
47  (u1) SignatureIterator::long_parm, // long
48#ifndef __ABI_HARD__
49  (u1) SignatureIterator::int_parm, // float, passed as int
50  (u1) SignatureIterator::long_parm, // double, passed as long
51#else
52  (u1) SignatureIterator::float_parm, // float
53  (u1) SignatureIterator::double_parm, // double
54#endif
55  (u1) SignatureIterator::obj_parm, // obj
56  (u1) SignatureIterator::done_parm // done
57};
58
59uint64_t InterpreterRuntime::normalize_fast_native_fingerprint(uint64_t fingerprint) {
60  if (fingerprint == UCONST64(-1)) {
61    // special signature used when the argument list cannot be encoded in a 64 bits value
62    return fingerprint;
63  }
64  int shift = SignatureIterator::static_feature_size;
65  uint64_t result = fingerprint & ((1 << shift) - 1);
66  fingerprint >>= shift;
67
68  BasicType ret_type = (BasicType) (fingerprint & SignatureIterator::result_feature_mask);
69  // For ARM, the fast signature handler only needs to know whether
70  // the return value must be unboxed. T_OBJECT and T_ARRAY need not
71  // be distinguished from each other and all other return values
72  // behave like integers with respect to the handler.
73  bool unbox = (ret_type == T_OBJECT) || (ret_type == T_ARRAY);
74  if (unbox) {
75    ret_type = T_OBJECT;
76  } else {
77    ret_type = T_INT;
78  }
79  result |= ((uint64_t) ret_type) << shift;
80  shift += SignatureIterator::result_feature_size;
81  fingerprint >>= SignatureIterator::result_feature_size;
82
83  while (true) {
84    uint32_t type = (uint32_t) (fingerprint & SignatureIterator::parameter_feature_mask);
85    if (type == SignatureIterator::done_parm) {
86      result |= ((uint64_t) SignatureIterator::done_parm) << shift;
87      return result;
88    }
89    assert((type >= SignatureIterator::bool_parm) && (type <= SignatureIterator::obj_parm), "check fingerprint encoding");
90    int shared = shared_type[type - SignatureIterator::bool_parm];
91    result |= ((uint64_t) shared) << shift;
92    shift += SignatureIterator::parameter_feature_size;
93    fingerprint >>= SignatureIterator::parameter_feature_size;
94  }
95}
96#endif // SHARING_FAST_NATIVE_FINGERPRINTS
97
98// Implementation of SignatureHandlerGenerator
99void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
100  if (_ireg < GPR_PARAMS) {
101    Register dst = as_Register(_ireg);
102    __ ldr_s32(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
103    _ireg++;
104  } else {
105    __ ldr_s32(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
106    __ str_32(Rtemp, Address(SP, _abi_offset * wordSize));
107    _abi_offset++;
108  }
109}
110
111void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
112#ifdef AARCH64
113  if (_ireg < GPR_PARAMS) {
114    Register dst = as_Register(_ireg);
115    __ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
116    _ireg++;
117  } else {
118    __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
119    __ str(Rtemp, Address(SP, _abi_offset * wordSize));
120    _abi_offset++;
121  }
122#else
123  if (_ireg <= 2) {
124#if (ALIGN_WIDE_ARGUMENTS == 1)
125    if ((_ireg & 1) != 0) {
126      // 64-bit values should be 8-byte aligned
127      _ireg++;
128    }
129#endif
130    Register dst1 = as_Register(_ireg);
131    Register dst2 = as_Register(_ireg+1);
132    __ ldr(dst1, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
133    __ ldr(dst2, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
134    _ireg += 2;
135#if (ALIGN_WIDE_ARGUMENTS == 0)
136  } else if (_ireg == 3) {
137    // uses R3 + one stack slot
138    Register dst1 = as_Register(_ireg);
139    __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
140    __ ldr(dst1, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
141    __ str(Rtemp, Address(SP, _abi_offset * wordSize));
142    _ireg += 1;
143    _abi_offset += 1;
144#endif
145  } else {
146#if (ALIGN_WIDE_ARGUMENTS == 1)
147    if(_abi_offset & 1) _abi_offset++;
148#endif
149    __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
150    __ str(Rtemp, Address(SP, (_abi_offset) * wordSize));
151    __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
152    __ str(Rtemp, Address(SP, (_abi_offset+1) * wordSize));
153    _abi_offset += 2;
154    _ireg = 4;
155  }
156#endif // AARCH64
157}
158
159void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
160#ifdef AARCH64
161  __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
162  __ cmp(Rtemp, 0);
163  __ sub(Rtemp, Rlocals, -Interpreter::local_offset_in_bytes(offset()));
164  if (_ireg < GPR_PARAMS) {
165    Register dst = as_Register(_ireg);
166    __ csel(dst, ZR, Rtemp, eq);
167    _ireg++;
168  } else {
169    __ csel(Rtemp, ZR, Rtemp, eq);
170    __ str(Rtemp, Address(SP, _abi_offset * wordSize));
171    _abi_offset++;
172  }
173#else
174  if (_ireg < 4) {
175    Register dst = as_Register(_ireg);
176    __ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
177    __ cmp(dst, 0);
178    __ sub(dst, Rlocals, -Interpreter::local_offset_in_bytes(offset()), ne);
179    _ireg++;
180  } else {
181    __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
182    __ cmp(Rtemp, 0);
183    __ sub(Rtemp, Rlocals, -Interpreter::local_offset_in_bytes(offset()), ne);
184    __ str(Rtemp, Address(SP, _abi_offset * wordSize));
185    _abi_offset++;
186  }
187#endif // AARCH64
188}
189
190#ifndef __ABI_HARD__
191void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
192  if (_ireg < 4) {
193    Register dst = as_Register(_ireg);
194    __ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
195    _ireg++;
196  } else {
197    __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
198    __ str(Rtemp, Address(SP, _abi_offset * wordSize));
199    _abi_offset++;
200  }
201}
202
203#else
204#ifndef __SOFTFP__
205void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
206#ifdef AARCH64
207    if (_freg < FPR_PARAMS) {
208      FloatRegister dst = as_FloatRegister(_freg);
209      __ ldr_s(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
210      _freg++;
211    } else {
212      __ ldr_u32(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
213      __ str_32(Rtemp, Address(SP, _abi_offset * wordSize));
214      _abi_offset++;
215    }
216#else
217    if((_fp_slot < 16) || (_single_fpr_slot & 1)) {
218      if ((_single_fpr_slot & 1) == 0) {
219        _single_fpr_slot = _fp_slot;
220        _fp_slot += 2;
221      }
222      __ flds(as_FloatRegister(_single_fpr_slot), Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
223      _single_fpr_slot++;
224    } else {
225      __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
226      __ str(Rtemp, Address(SP, _abi_offset * wordSize));
227      _abi_offset++;
228    }
229#endif // AARCH64
230}
231
232void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
233#ifdef AARCH64
234    if (_freg < FPR_PARAMS) {
235      FloatRegister dst = as_FloatRegister(_freg);
236      __ ldr_d(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
237      _freg++;
238    } else {
239      __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1)));
240      __ str(Rtemp, Address(SP, _abi_offset * wordSize));
241      _abi_offset++;
242    }
243#else
244    if(_fp_slot <= 14) {
245      __ fldd(as_FloatRegister(_fp_slot), Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
246      _fp_slot += 2;
247    } else {
248      __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1)));
249      __ str(Rtemp, Address(SP, (_abi_offset) * wordSize));
250      __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset())));
251      __ str(Rtemp, Address(SP, (_abi_offset+1) * wordSize));
252      _abi_offset += 2;
253      _single_fpr_slot = 16;
254    }
255#endif // AARCH64
256}
257#endif // __SOFTFP__
258#endif // __ABI_HARD__
259
260void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
261  iterate(fingerprint);
262
263  BasicType result_type = SignatureIterator::return_type(fingerprint);
264
265  address result_handler = Interpreter::result_handler(result_type);
266
267#ifdef AARCH64
268  __ mov_slow(R0, (address)result_handler);
269#else
270  // Check that result handlers are not real handler on ARM (0 or -1).
271  // This ensures the signature handlers do not need symbolic information.
272  assert((result_handler == NULL)||(result_handler==(address)0xffffffff),"");
273  __ mov_slow(R0, (intptr_t)result_handler);
274#endif
275
276  __ ret();
277}
278
279
280// Implementation of SignatureHandlerLibrary
281
282void SignatureHandlerLibrary::pd_set_handler(address handler) {}
283
284class SlowSignatureHandler: public NativeSignatureIterator {
285 private:
286  address   _from;
287  intptr_t* _to;
288
289#ifndef __ABI_HARD__
290  virtual void pass_int() {
291    *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
292    _from -= Interpreter::stackElementSize;
293  }
294
295  virtual void pass_float() {
296    *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
297    _from -= Interpreter::stackElementSize;
298  }
299
300  virtual void pass_long() {
301#if (ALIGN_WIDE_ARGUMENTS == 1)
302    if (((intptr_t)_to & 7) != 0) {
303      // 64-bit values should be 8-byte aligned
304      _to++;
305    }
306#endif
307    _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
308    _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
309    _to += 2;
310    _from -= 2*Interpreter::stackElementSize;
311  }
312
313  virtual void pass_object() {
314    intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0));
315    *_to++ = (*(intptr_t*)from_addr == 0) ? (intptr_t)NULL : from_addr;
316    _from -= Interpreter::stackElementSize;
317   }
318
319#else
320
321  intptr_t* _toFP;
322  intptr_t* _toGP;
323  int       _last_gp;
324  int       _last_fp;
325#ifndef AARCH64
326  int       _last_single_fp;
327#endif // !AARCH64
328
329  virtual void pass_int() {
330    if(_last_gp < GPR_PARAMS) {
331      _toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
332    } else {
333      *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
334    }
335    _from -= Interpreter::stackElementSize;
336  }
337
338  virtual void pass_long() {
339#ifdef AARCH64
340    if(_last_gp < GPR_PARAMS) {
341      _toGP[_last_gp++] = *(jlong *)(_from+Interpreter::local_offset_in_bytes(1));
342    } else {
343      *_to++ = *(jlong *)(_from+Interpreter::local_offset_in_bytes(1));
344    }
345#else
346    assert(ALIGN_WIDE_ARGUMENTS == 1, "ABI_HARD not supported with unaligned wide arguments");
347    if (_last_gp <= 2) {
348      if(_last_gp & 1) _last_gp++;
349      _toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(1));
350      _toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
351    } else {
352      if (((intptr_t)_to & 7) != 0) {
353        // 64-bit values should be 8-byte aligned
354        _to++;
355      }
356      _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
357      _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
358      _to += 2;
359      _last_gp = 4;
360    }
361#endif // AARCH64
362    _from -= 2*Interpreter::stackElementSize;
363  }
364
365  virtual void pass_object() {
366    intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0));
367    if(_last_gp < GPR_PARAMS) {
368      _toGP[_last_gp++] = (*(intptr_t*)from_addr == 0) ? NULL : from_addr;
369    } else {
370      *_to++ = (*(intptr_t*)from_addr == 0) ? NULL : from_addr;
371    }
372    _from -= Interpreter::stackElementSize;
373  }
374
375  virtual void pass_float() {
376#ifdef AARCH64
377    if(_last_fp < FPR_PARAMS) {
378      _toFP[_last_fp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
379    } else {
380      *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
381    }
382#else
383    if((_last_fp < 16) || (_last_single_fp & 1)) {
384      if ((_last_single_fp & 1) == 0) {
385        _last_single_fp = _last_fp;
386        _last_fp += 2;
387      }
388
389      _toFP[_last_single_fp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
390    } else {
391      *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
392    }
393#endif // AARCH64
394    _from -= Interpreter::stackElementSize;
395  }
396
397  virtual void pass_double() {
398#ifdef AARCH64
399    if(_last_fp < FPR_PARAMS) {
400      _toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
401    } else {
402      *_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
403    }
404#else
405    assert(ALIGN_WIDE_ARGUMENTS == 1, "ABI_HARD not supported with unaligned wide arguments");
406    if(_last_fp <= 14) {
407      _toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
408      _toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
409    } else {
410      if (((intptr_t)_to & 7) != 0) {      // 64-bit values should be 8-byte aligned
411        _to++;
412      }
413      _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
414      _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
415      _to += 2;
416      _last_single_fp = 16;
417    }
418#endif // AARCH64
419    _from -= 2*Interpreter::stackElementSize;
420  }
421
422#endif // !__ABI_HARD__
423
424 public:
425  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) :
426    NativeSignatureIterator(method) {
427    _from = from;
428
429#ifdef __ABI_HARD__
430    _toGP  = to;
431    _toFP = _toGP + GPR_PARAMS;
432    _to   = _toFP + AARCH64_ONLY(FPR_PARAMS) NOT_AARCH64(8*2);
433    _last_gp = (is_static() ? 2 : 1);
434    _last_fp = 0;
435#ifndef AARCH64
436    _last_single_fp = 0;
437#endif // !AARCH64
438#else
439    _to   = to + (is_static() ? 2 : 1);
440#endif // __ABI_HARD__
441  }
442};
443
444IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to))
445  methodHandle m(thread, (Method*)method);
446  assert(m->is_native(), "sanity check");
447  SlowSignatureHandler(m, (address)from, to).iterate(UCONST64(-1));
448  return Interpreter::result_handler(m->result_type());
449IRT_END
450