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::pass_valuetype() { 178 pass_object(); 179 } 180 181 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { 182 // generate code to handle arguments 183 iterate(fingerprint); 184 185 // return result handler 186 __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type()))); 187 __ ret(lr); 188 189 __ flush(); 190 } 191 192 193 // Implementation of SignatureHandlerLibrary 194 195 void SignatureHandlerLibrary::pd_set_handler(address handler) {} 196 197 198 class SlowSignatureHandler 199 : public NativeSignatureIterator { 200 private: 201 address _from; 202 char* _to; 203 intptr_t* _int_args; 204 intptr_t* _fp_args; 205 intptr_t* _fp_identifiers; 206 unsigned int _num_reg_int_args; 207 unsigned int _num_reg_fp_args; 208 209 intptr_t* single_slot_addr() { 210 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 211 _from -= Interpreter::stackElementSize; 212 return from_addr; 213 } 214 215 intptr_t* double_slot_addr() { 216 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 217 _from -= 2*Interpreter::stackElementSize; 218 return from_addr; 219 } 220 221 int pass_gpr(intptr_t value) { 222 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { 223 *_int_args++ = value; 224 return _num_reg_int_args++; 225 } 226 return -1; 227 } 228 229 int pass_fpr(intptr_t value) { 230 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { 231 *_fp_args++ = value; 232 return _num_reg_fp_args++; 233 } 234 return -1; 235 } 236 237 template<typename T> 238 void pass_stack(T value) { 239 MACOS_ONLY(_to = align_up(_to, sizeof(value))); 240 *(T *)_to = value; 241 _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value)); 242 } 243 244 virtual void pass_byte() { 245 jbyte value = *(jbyte*)single_slot_addr(); 246 if (pass_gpr(value) < 0) { 247 pass_stack<>(value); 248 } 249 } 250 251 virtual void pass_short() { 252 jshort value = *(jshort*)single_slot_addr(); 253 if (pass_gpr(value) < 0) { 254 pass_stack<>(value); 255 } 256 } 257 258 virtual void pass_int() { 259 jint value = *(jint*)single_slot_addr(); 260 if (pass_gpr(value) < 0) { 261 pass_stack<>(value); 262 } 263 } 264 265 virtual void pass_valuetype() { 266 // values are handled with oops, like objects 267 pass_object(); 268 } 269 270 virtual void pass_long() { 271 intptr_t value = *double_slot_addr(); 272 if (pass_gpr(value) < 0) { 273 pass_stack<>(value); 274 } 275 } 276 277 virtual void pass_object() { 278 intptr_t* addr = single_slot_addr(); 279 intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr; 280 if (pass_gpr(value) < 0) { 281 pass_stack<>(value); 282 } 283 } 284 285 virtual void pass_float() { 286 jint value = *(jint*)single_slot_addr(); 287 if (pass_fpr(value) < 0) { 288 pass_stack<>(value); 289 } 290 } 291 292 virtual void pass_double() { 293 intptr_t value = *double_slot_addr(); 294 int arg = pass_fpr(value); 295 if (0 <= arg) { 296 *_fp_identifiers |= (1ull << arg); // mark as double 297 } else { 298 pass_stack<>(value); 299 } 300 } 301 302 public: 303 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) 304 : NativeSignatureIterator(method) 305 { 306 _from = from; 307 _to = (char *)to; 308 309 _int_args = to - (method->is_static() ? 16 : 17); 310 _fp_args = to - 8; 311 _fp_identifiers = to - 9; 312 *(int*) _fp_identifiers = 0; 313 _num_reg_int_args = (method->is_static() ? 1 : 0); 314 _num_reg_fp_args = 0; 315 } 316 317 }; 318 319 320 JRT_ENTRY(address, 321 InterpreterRuntime::slow_signature_handler(JavaThread* current, 322 Method* method, 323 intptr_t* from, 324 intptr_t* to)) 325 methodHandle m(current, (Method*)method); 326 assert(m->is_native(), "sanity check"); 327 328 // handle arguments 329 SlowSignatureHandler ssh(m, (address)from, to); 330 ssh.iterate((uint64_t)CONST64(-1)); 331 332 // return result handler 333 return Interpreter::result_handler(m->result_type()); 334 JRT_END