1 /*
   2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
   4  * Copyright (c) 2015, Linaro Ltd. All rights reserved.
   5  * Copyright (c) 2015-2018, Azul Systems, Inc. All rights reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  *
  26  */
  27 
  28 #include "precompiled.hpp"
  29 #include "asm/macroAssembler.inline.hpp"
  30 #include "interpreter/interp_masm.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "interpreter/interpreterRuntime.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/universe.hpp"
  35 #include "oops/method.hpp"
  36 #include "oops/oop.inline.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "runtime/icache.hpp"
  39 #include "runtime/interfaceSupport.inline.hpp"
  40 #include "runtime/signature.hpp"
  41 
  42 #define __ _masm->
  43 
  44 /*#define print_copy(name, off) \
  45   __ mov(rscratch1, (address)name);\
  46   __ mov(rscratch2, off);\
  47   __ reg_printf("%s copied from offset %p + %d\n", rscratch1, from(), rscratch2);*/
  48 
  49 #define print_copy(name, off)
  50 
  51 // Implementation of SignatureHandlerGenerator
  52 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
  53 Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return r4; }
  54 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
  55 
  56 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
  57   const methodHandle &method, CodeBuffer* buffer):
  58   NativeSignatureIterator(method),
  59   _next_double_dex(0),
  60   _stack_offset(0)
  61 {
  62   _masm = new MacroAssembler(buffer);
  63   _num_int_args = (method->is_static() ? 1 : 0);
  64   // See layout in interpreter_aarch32.cpp
  65   _fp_arg_mask =  (1 <<(Argument::n_float_register_parameters_c * 3)) - 1;
  66 }
  67 
  68 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
  69   print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));
  70   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
  71 
  72   switch (_num_int_args) {
  73   case 0:
  74     __ ldr(c_rarg1, src);
  75     _num_int_args++;
  76     break;
  77   case 1:
  78     __ ldr(c_rarg2, src);
  79     _num_int_args++;
  80     break;
  81   case 2:
  82     __ ldr(c_rarg3, src);
  83     _num_int_args++;
  84     break;
  85   default:
  86     __ ldr(r0, src);
  87     __ str(r0, Address(to(), _stack_offset));
  88     _stack_offset += wordSize;
  89     _num_int_args++;
  90     break;
  91   }
  92 }
  93 
  94 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
  95   print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset() + 1));
  96   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
  97   // Needs to be aligned to even registers. Means also won't be split across
  98   // registers and stack.
  99 
 100   switch (_num_int_args) {
 101   case 0:
 102   case 1:
 103     __ ldrd(c_rarg2, c_rarg3, src);
 104     _num_int_args = 3; // force next args onto stack
 105     break;
 106   default:
 107     __ ldrd(r0, temp(), src);
 108     _stack_offset = (_stack_offset + 7) & ~7; // Align on 8-byte boundary
 109     __ strd(r0, temp(), Address(to(), _stack_offset));
 110     _stack_offset += 2 * wordSize;
 111     _num_int_args += 2;
 112     break;
 113   }
 114 }
 115 
 116 #ifdef HARD_FLOAT_CC
 117 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
 118   print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));
 119   const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
 120 
 121     if (_fp_arg_mask & ((1 << Argument::n_float_register_parameters_c*2)-1)) {
 122         unsigned index = __builtin_ctz(_fp_arg_mask);
 123         __ vldr_f32(as_FloatRegister(index), src);
 124         _fp_arg_mask &= ~(1 << index);
 125         _next_double_dex += (~index) & 1;
 126     } else {
 127         __ ldr(r0, src);
 128         __ str(r0, Address(to(), _stack_offset));
 129         _stack_offset += wordSize;
 130     }
 131 }
 132 
 133 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
 134   print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset() + 1));
 135   const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
 136 
 137     if (_next_double_dex < Argument::n_float_register_parameters_c) {
 138         _fp_arg_mask &= ~((3 << _next_double_dex*2) | ((1 << _next_double_dex+16)));
 139         __ vldr_f64(as_DoubleFloatRegister(_next_double_dex++), src);
 140     } else {
 141         __ ldrd(r0, temp(), src);
 142         _stack_offset = (_stack_offset + 7) & ~7;
 143         __ strd(r0, temp(), Address(to(), _stack_offset));
 144         _stack_offset += 2 * wordSize;
 145     }
 146 }
 147 #else
 148 // Just pass them in integer registers and on the stack as we would
 149 // any other argument
 150 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
 151   pass_int();
 152 }
 153 
 154 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
 155   pass_long();
 156 }
 157 #endif //HARD_FLOAT_CC
 158 
 159 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
 160   print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));
 161 
 162   switch (_num_int_args) {
 163   case 0:
 164     assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
 165     __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
 166     _num_int_args++;
 167     break;
 168   case 1:
 169     {
 170       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
 171       __ mov(c_rarg2, 0);
 172       __ ldr(temp(), r0);
 173       Label L;
 174       __ cbz(temp(), L);
 175       __ mov(c_rarg2, r0);
 176       __ bind(L);
 177       _num_int_args++;
 178       break;
 179     }
 180   case 2:
 181     {
 182       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
 183       __ mov(c_rarg3, 0);
 184       __ ldr(temp(), r0);
 185       Label L;
 186       __ cbz(temp(), L);
 187       __ mov(c_rarg3, r0);
 188       __ bind(L);
 189       _num_int_args++;
 190       break;
 191     }
 192  default:
 193    {
 194       __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
 195       __ ldr(temp(), r0);
 196       Label L;
 197       __ cbnz(temp(), L);
 198       __ mov(r0, 0);
 199       __ bind(L);
 200       __ str(r0, Address(to(), _stack_offset));
 201       _stack_offset += wordSize;
 202       _num_int_args++;
 203       break;
 204    }
 205   }
 206 }
 207 
 208 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
 209   // generate code to handle arguments
 210   iterate(fingerprint);
 211 
 212   // return result handler
 213   __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
 214   __ b(lr);
 215 
 216   __ flush();
 217 }
 218 
 219 
 220 // Implementation of SignatureHandlerLibrary
 221 
 222 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
 223 
 224 
 225 class SlowSignatureHandler : public NativeSignatureIterator {
 226  private:
 227   address   _from;
 228   intptr_t* _to;
 229   intptr_t* _int_args;
 230   intptr_t* _fp_args;
 231   intptr_t* _fp_identifiers;
 232 
 233   int _num_int_reg_args;
 234   int _next_double_dex;
 235 
 236   virtual void pass_int()
 237   {
 238     jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
 239     _from -= Interpreter::stackElementSize;
 240 
 241     if (_num_int_reg_args < Argument::n_int_register_parameters_c-1) {
 242       *_int_args++ = from_obj;
 243       _num_int_reg_args++;
 244     } else {
 245       *_to++ = from_obj;
 246     }
 247   }
 248 
 249   virtual void pass_long()
 250   {
 251     intptr_t high_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
 252     intptr_t low_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
 253     _from -= 2*Interpreter::stackElementSize;
 254 
 255     if (_num_int_reg_args < Argument::n_int_register_parameters_c-2) {
 256       // Passing longs. As c_rarg0 is always reserved for jni_env we could only
 257       // possibly stash a long in r3:r2 due to alignment so we can only enter here
 258       // with either zero or one parameters.
 259       // Align to two
 260       _int_args += 1 - _num_int_reg_args; // 0 or 1
 261       *_int_args++ = low_obj;
 262       *_int_args++ = high_obj;
 263       _num_int_reg_args = 3;
 264     } else {
 265       _to = (intptr_t*)(((intptr_t)_to + 7) & ~7); // Align to eight bytes
 266       *_to++ = low_obj;
 267       *_to++ = high_obj;
 268       _num_int_reg_args = 3;
 269     }
 270   }
 271 
 272   virtual void pass_object()
 273   {
 274     intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
 275     _from -= Interpreter::stackElementSize;
 276 
 277     if (_num_int_reg_args < Argument::n_int_register_parameters_c-1) {
 278       *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
 279       _num_int_reg_args++;
 280     } else {
 281       *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
 282     }
 283   }
 284 #ifdef HARD_FLOAT_CC
 285   virtual void pass_float()
 286   {
 287     jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
 288     _from -= Interpreter::stackElementSize;
 289 
 290     if ((*_fp_identifiers) & 0xffff) {
 291       unsigned index = __builtin_ctz(*_fp_identifiers);
 292       _fp_args[index] = from_obj;
 293       *_fp_identifiers ^= 1 << index;
 294       _next_double_dex += (~index) & 1;
 295     } else {
 296       *_to++ = from_obj;
 297     }
 298   }
 299 
 300   virtual void pass_double()
 301   {
 302     intptr_t high_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
 303     intptr_t low_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
 304     _from -= 2*Interpreter::stackElementSize;
 305 
 306     if (_next_double_dex < Argument::n_float_register_parameters_c) {
 307       //We can allocate to a register.
 308       int index = _next_double_dex++;
 309       *_fp_identifiers &= ~((3 << index*2) | (1 << index+16));
 310       _fp_args[index*2] = low_obj;
 311       _fp_args[index*2 + 1] = high_obj;
 312     } else {
 313       _to = (intptr_t*)(((intptr_t)_to + 7) & ~7); // Align to eight bytes
 314       *_to++ = low_obj;
 315       *_to++ = high_obj;
 316     }
 317   }
 318 #else
 319   virtual void pass_float() { pass_int(); }
 320   virtual void pass_double() { pass_long(); }
 321 #endif // HARD_FLOAT_CC
 322 
 323  public:
 324   SlowSignatureHandler(const methodHandle &method, address from, intptr_t* to)
 325     : NativeSignatureIterator(method)
 326   {
 327     _from = from;
 328     _to   = to;
 329     // See layout in interpreter_aarch32.cpp
 330     _int_args = to - (method->is_static() ? 19 : 20);
 331     _fp_args =  to - 16; //each slot is for a double
 332     _fp_identifiers = to - 21;
 333     *_fp_identifiers = (1 <<(Argument::n_float_register_parameters_c * 3)) - 1;
 334 
 335     _num_int_reg_args = (method->is_static() ? 1 : 0);
 336     _next_double_dex = 0;
 337   }
 338 };
 339 
 340 
 341 IRT_ENTRY(address,
 342           InterpreterRuntime::slow_signature_handler(JavaThread* thread,
 343                                                      Method* method,
 344                                                      intptr_t* from,
 345                                                      intptr_t* to))
 346   methodHandle m(thread, (Method*)method);
 347   assert(m->is_native(), "sanity check");
 348 
 349   // handle arguments
 350   SlowSignatureHandler ssh(m, (address)from, to);
 351   ssh.iterate(UCONST64(-1));
 352 
 353   // return result handler
 354   return Interpreter::result_handler(m->result_type());
 355 IRT_END