1 /* 2 * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved. 4 * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. 5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6 * 7 * This code is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License version 2 only, as 9 * published by the Free Software Foundation. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 * 25 */ 26 27 #include "precompiled.hpp" 28 #include "asm/macroAssembler.inline.hpp" 29 #include "interpreter/interp_masm.hpp" 30 #include "interpreter/interpreter.hpp" 31 #include "interpreter/interpreterRuntime.hpp" 32 #include "memory/allocation.inline.hpp" 33 #include "oops/method.hpp" 34 #include "oops/oop.inline.hpp" 35 #include "runtime/handles.inline.hpp" 36 #include "runtime/icache.hpp" 37 #include "runtime/interfaceSupport.inline.hpp" 38 #include "runtime/signature.hpp" 39 40 #define __ _masm-> 41 42 // Implementation of SignatureHandlerGenerator 43 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; } 44 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; } 45 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } 46 47 Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() { 48 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { 49 return as_Register(_num_reg_int_args++ + c_rarg1->encoding()); 50 } 51 return noreg; 52 } 53 54 FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() { 55 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { 56 return as_FloatRegister(_num_reg_fp_args++); 57 } 58 return fnoreg; 59 } 60 61 // On macos/aarch64 native stack is packed, int/float are using only 4 bytes 62 // on stack. Natural alignment for types are still in place, 63 // for example double/long should be 8 bytes aligned. 64 65 int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset(unsigned elem_size) { 66 MACOS_ONLY(_stack_offset = align_up(_stack_offset, elem_size)); 67 int ret = _stack_offset; 68 _stack_offset += NOT_MACOS(wordSize) MACOS_ONLY(elem_size); 69 return ret; 70 } 71 72 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator( 73 const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) { 74 _masm = new MacroAssembler(buffer); 75 _num_reg_int_args = (method->is_static() ? 1 : 0); 76 _num_reg_fp_args = 0; 77 _stack_offset = 0; 78 } 79 80 void InterpreterRuntime::SignatureHandlerGenerator::pass_byte() { 81 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 82 83 Register reg = next_gpr(); 84 if (reg != noreg) { 85 __ ldr(reg, src); 86 } else { 87 __ ldrb(r0, src); 88 __ strb(r0, Address(to(), next_stack_offset(sizeof(jbyte)))); 89 } 90 } 91 92 void InterpreterRuntime::SignatureHandlerGenerator::pass_short() { 93 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 94 95 Register reg = next_gpr(); 96 if (reg != noreg) { 97 __ ldr(reg, src); 98 } else { 99 __ ldrh(r0, src); 100 __ strh(r0, Address(to(), next_stack_offset(sizeof(jshort)))); 101 } 102 } 103 104 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { 105 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 106 107 Register reg = next_gpr(); 108 if (reg != noreg) { 109 __ ldr(reg, src); 110 } else { 111 __ ldrw(r0, src); 112 __ strw(r0, Address(to(), next_stack_offset(sizeof(jint)))); 113 } 114 } 115 116 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { 117 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); 118 119 Register reg = next_gpr(); 120 if (reg != noreg) { 121 __ ldr(reg, src); 122 } else { 123 __ ldr(r0, src); 124 __ str(r0, Address(to(), next_stack_offset(sizeof(jlong)))); 125 } 126 } 127 128 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { 129 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 130 131 FloatRegister reg = next_fpr(); 132 if (reg != fnoreg) { 133 __ ldrs(reg, src); 134 } else { 135 __ ldrw(r0, src); 136 __ strw(r0, Address(to(), next_stack_offset(sizeof(jfloat)))); 137 } 138 } 139 140 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { 141 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); 142 143 FloatRegister reg = next_fpr(); 144 if (reg != fnoreg) { 145 __ ldrd(reg, src); 146 } else { 147 __ ldr(r0, src); 148 __ str(r0, Address(to(), next_stack_offset(sizeof(jdouble)))); 149 } 150 } 151 152 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { 153 Register reg = next_gpr(); 154 if (reg == c_rarg1) { 155 assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); 156 __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); 157 } else if (reg != noreg) { 158 __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); 159 __ mov(reg, 0); 160 __ ldr(temp(), r0); 161 Label L; 162 __ cbz(temp(), L); 163 __ mov(reg, r0); 164 __ bind(L); 165 } else { 166 __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); 167 __ ldr(temp(), r0); 168 Label L; 169 __ cbnz(temp(), L); 170 __ mov(r0, zr); 171 __ bind(L); 172 static_assert(sizeof(jobject) == wordSize, ""); 173 __ str(r0, Address(to(), next_stack_offset(sizeof(jobject)))); 174 } 175 } 176 177 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { 178 // generate code to handle arguments 179 iterate(fingerprint); 180 181 // return result handler 182 __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type()))); 183 __ ret(lr); 184 185 __ flush(); 186 } 187 188 189 // Implementation of SignatureHandlerLibrary 190 191 void SignatureHandlerLibrary::pd_set_handler(address handler) {} 192 193 194 class SlowSignatureHandler 195 : public NativeSignatureIterator { 196 private: 197 address _from; 198 char* _to; 199 intptr_t* _int_args; 200 intptr_t* _fp_args; 201 intptr_t* _fp_identifiers; 202 unsigned int _num_reg_int_args; 203 unsigned int _num_reg_fp_args; 204 205 intptr_t* single_slot_addr() { 206 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 207 _from -= Interpreter::stackElementSize; 208 return from_addr; 209 } 210 211 intptr_t* double_slot_addr() { 212 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 213 _from -= 2*Interpreter::stackElementSize; 214 return from_addr; 215 } 216 217 int pass_gpr(intptr_t value) { 218 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { 219 *_int_args++ = value; 220 return _num_reg_int_args++; 221 } 222 return -1; 223 } 224 225 int pass_fpr(intptr_t value) { 226 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { 227 *_fp_args++ = value; 228 return _num_reg_fp_args++; 229 } 230 return -1; 231 } 232 233 template<typename T> 234 void pass_stack(T value) { 235 MACOS_ONLY(_to = align_up(_to, sizeof(value))); 236 *(T *)_to = value; 237 _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value)); 238 } 239 240 virtual void pass_byte() { 241 jbyte value = *(jbyte*)single_slot_addr(); 242 if (pass_gpr(value) < 0) { 243 pass_stack<>(value); 244 } 245 } 246 247 virtual void pass_short() { 248 jshort value = *(jshort*)single_slot_addr(); 249 if (pass_gpr(value) < 0) { 250 pass_stack<>(value); 251 } 252 } 253 254 virtual void pass_int() { 255 jint value = *(jint*)single_slot_addr(); 256 if (pass_gpr(value) < 0) { 257 pass_stack<>(value); 258 } 259 } 260 261 virtual void pass_long() { 262 intptr_t value = *double_slot_addr(); 263 if (pass_gpr(value) < 0) { 264 pass_stack<>(value); 265 } 266 } 267 268 virtual void pass_object() { 269 intptr_t* addr = single_slot_addr(); 270 intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr; 271 if (pass_gpr(value) < 0) { 272 pass_stack<>(value); 273 } 274 } 275 276 virtual void pass_float() { 277 jint value = *(jint*)single_slot_addr(); 278 if (pass_fpr(value) < 0) { 279 pass_stack<>(value); 280 } 281 } 282 283 virtual void pass_double() { 284 intptr_t value = *double_slot_addr(); 285 int arg = pass_fpr(value); 286 if (0 <= arg) { 287 *_fp_identifiers |= (1ull << arg); // mark as double 288 } else { 289 pass_stack<>(value); 290 } 291 } 292 293 public: 294 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) 295 : NativeSignatureIterator(method) 296 { 297 _from = from; 298 _to = (char *)to; 299 300 _int_args = to - (method->is_static() ? 16 : 17); 301 _fp_args = to - 8; 302 _fp_identifiers = to - 9; 303 *(int*) _fp_identifiers = 0; 304 _num_reg_int_args = (method->is_static() ? 1 : 0); 305 _num_reg_fp_args = 0; 306 } 307 308 }; 309 310 311 JRT_ENTRY(address, 312 InterpreterRuntime::slow_signature_handler(JavaThread* current, 313 Method* method, 314 intptr_t* from, 315 intptr_t* to)) 316 methodHandle m(current, (Method*)method); 317 assert(m->is_native(), "sanity check"); 318 319 // handle arguments 320 SlowSignatureHandler ssh(m, (address)from, to); 321 ssh.iterate((uint64_t)CONST64(-1)); 322 323 // return result handler 324 return Interpreter::result_handler(m->result_type()); 325 JRT_END