1 /* 2 * Copyright (c) 2003, 2025, 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 "asm/macroAssembler.inline.hpp" 28 #include "interpreter/interp_masm.hpp" 29 #include "interpreter/interpreter.hpp" 30 #include "interpreter/interpreterRuntime.hpp" 31 #include "memory/allocation.inline.hpp" 32 #include "oops/method.hpp" 33 #include "oops/oop.inline.hpp" 34 #include "runtime/handles.inline.hpp" 35 #include "runtime/icache.hpp" 36 #include "runtime/interfaceSupport.inline.hpp" 37 #include "runtime/signature.hpp" 38 39 #define __ _masm-> 40 41 // Implementation of SignatureHandlerGenerator 42 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; } 43 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return sp; } 44 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } 45 46 Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() { 47 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { 48 return as_Register(_num_reg_int_args++ + c_rarg1->encoding()); 49 } 50 return noreg; 51 } 52 53 FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() { 54 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { 55 return as_FloatRegister(_num_reg_fp_args++); 56 } 57 return fnoreg; 58 } 59 60 // On macos/aarch64 native stack is packed, int/float are using only 4 bytes 61 // on stack. Natural alignment for types are still in place, 62 // for example double/long should be 8 bytes aligned. 63 64 int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset(unsigned elem_size) { 65 MACOS_ONLY(_stack_offset = align_up(_stack_offset, elem_size)); 66 int ret = _stack_offset; 67 _stack_offset += NOT_MACOS(wordSize) MACOS_ONLY(elem_size); 68 return ret; 69 } 70 71 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator( 72 const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) { 73 _masm = new MacroAssembler(buffer); 74 _num_reg_int_args = (method->is_static() ? 1 : 0); 75 _num_reg_fp_args = 0; 76 _stack_offset = 0; 77 } 78 79 void InterpreterRuntime::SignatureHandlerGenerator::pass_byte() { 80 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 81 82 Register reg = next_gpr(); 83 if (reg != noreg) { 84 __ ldr(reg, src); 85 } else { 86 __ ldrb(r0, src); 87 __ strb(r0, Address(to(), next_stack_offset(sizeof(jbyte)))); 88 } 89 } 90 91 void InterpreterRuntime::SignatureHandlerGenerator::pass_short() { 92 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 93 94 Register reg = next_gpr(); 95 if (reg != noreg) { 96 __ ldr(reg, src); 97 } else { 98 __ ldrh(r0, src); 99 __ strh(r0, Address(to(), next_stack_offset(sizeof(jshort)))); 100 } 101 } 102 103 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { 104 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 105 106 Register reg = next_gpr(); 107 if (reg != noreg) { 108 __ ldr(reg, src); 109 } else { 110 __ ldrw(r0, src); 111 __ strw(r0, Address(to(), next_stack_offset(sizeof(jint)))); 112 } 113 } 114 115 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { 116 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); 117 118 Register reg = next_gpr(); 119 if (reg != noreg) { 120 __ ldr(reg, src); 121 } else { 122 __ ldr(r0, src); 123 __ str(r0, Address(to(), next_stack_offset(sizeof(jlong)))); 124 } 125 } 126 127 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { 128 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); 129 130 FloatRegister reg = next_fpr(); 131 if (reg != fnoreg) { 132 __ ldrs(reg, src); 133 } else { 134 __ ldrw(r0, src); 135 __ strw(r0, Address(to(), next_stack_offset(sizeof(jfloat)))); 136 } 137 } 138 139 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { 140 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); 141 142 FloatRegister reg = next_fpr(); 143 if (reg != fnoreg) { 144 __ ldrd(reg, src); 145 } else { 146 __ ldr(r0, src); 147 __ str(r0, Address(to(), next_stack_offset(sizeof(jdouble)))); 148 } 149 } 150 151 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { 152 Register reg = next_gpr(); 153 if (reg == c_rarg1) { 154 assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); 155 __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset())); 156 } else if (reg != noreg) { 157 __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); 158 __ mov(reg, 0); 159 __ ldr(temp(), r0); 160 Label L; 161 __ cbz(temp(), L); 162 __ mov(reg, r0); 163 __ bind(L); 164 } else { 165 __ add(r0, from(), Interpreter::local_offset_in_bytes(offset())); 166 __ ldr(temp(), r0); 167 Label L; 168 __ cbnz(temp(), L); 169 __ mov(r0, zr); 170 __ bind(L); 171 static_assert(sizeof(jobject) == wordSize, ""); 172 __ str(r0, Address(to(), next_stack_offset(sizeof(jobject)))); 173 } 174 } 175 176 void InterpreterRuntime::SignatureHandlerGenerator::pass_valuetype() { 177 pass_object(); 178 } 179 180 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { 181 // generate code to handle arguments 182 iterate(fingerprint); 183 184 // return result handler 185 __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type()))); 186 __ ret(lr); 187 188 __ flush(); 189 } 190 191 192 // Implementation of SignatureHandlerLibrary 193 194 void SignatureHandlerLibrary::pd_set_handler(address handler) {} 195 196 197 class SlowSignatureHandler 198 : public NativeSignatureIterator { 199 private: 200 address _from; 201 char* _to; 202 intptr_t* _int_args; 203 intptr_t* _fp_args; 204 intptr_t* _fp_identifiers; 205 unsigned int _num_reg_int_args; 206 unsigned int _num_reg_fp_args; 207 208 intptr_t* single_slot_addr() { 209 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 210 _from -= Interpreter::stackElementSize; 211 return from_addr; 212 } 213 214 intptr_t* double_slot_addr() { 215 intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 216 _from -= 2*Interpreter::stackElementSize; 217 return from_addr; 218 } 219 220 int pass_gpr(intptr_t value) { 221 if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) { 222 *_int_args++ = value; 223 return _num_reg_int_args++; 224 } 225 return -1; 226 } 227 228 int pass_fpr(intptr_t value) { 229 if (_num_reg_fp_args < Argument::n_float_register_parameters_c) { 230 *_fp_args++ = value; 231 return _num_reg_fp_args++; 232 } 233 return -1; 234 } 235 236 template<typename T> 237 void pass_stack(T value) { 238 MACOS_ONLY(_to = align_up(_to, sizeof(value))); 239 *(T *)_to = value; 240 _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value)); 241 } 242 243 virtual void pass_byte() { 244 jbyte value = *(jbyte*)single_slot_addr(); 245 if (pass_gpr(value) < 0) { 246 pass_stack<>(value); 247 } 248 } 249 250 virtual void pass_short() { 251 jshort value = *(jshort*)single_slot_addr(); 252 if (pass_gpr(value) < 0) { 253 pass_stack<>(value); 254 } 255 } 256 257 virtual void pass_int() { 258 jint value = *(jint*)single_slot_addr(); 259 if (pass_gpr(value) < 0) { 260 pass_stack<>(value); 261 } 262 } 263 264 virtual void pass_valuetype() { 265 // values are handled with oops, like objects 266 pass_object(); 267 } 268 269 virtual void pass_long() { 270 intptr_t value = *double_slot_addr(); 271 if (pass_gpr(value) < 0) { 272 pass_stack<>(value); 273 } 274 } 275 276 virtual void pass_object() { 277 intptr_t* addr = single_slot_addr(); 278 intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr; 279 if (pass_gpr(value) < 0) { 280 pass_stack<>(value); 281 } 282 } 283 284 virtual void pass_float() { 285 jint value = *(jint*)single_slot_addr(); 286 if (pass_fpr(value) < 0) { 287 pass_stack<>(value); 288 } 289 } 290 291 virtual void pass_double() { 292 intptr_t value = *double_slot_addr(); 293 int arg = pass_fpr(value); 294 if (0 <= arg) { 295 *_fp_identifiers |= (1ull << arg); // mark as double 296 } else { 297 pass_stack<>(value); 298 } 299 } 300 301 public: 302 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) 303 : NativeSignatureIterator(method) 304 { 305 _from = from; 306 _to = (char *)to; 307 308 _int_args = to - (method->is_static() ? 16 : 17); 309 _fp_args = to - 8; 310 _fp_identifiers = to - 9; 311 *(int*) _fp_identifiers = 0; 312 _num_reg_int_args = (method->is_static() ? 1 : 0); 313 _num_reg_fp_args = 0; 314 } 315 316 }; 317 318 319 JRT_ENTRY(address, 320 InterpreterRuntime::slow_signature_handler(JavaThread* current, 321 Method* method, 322 intptr_t* from, 323 intptr_t* to)) 324 methodHandle m(current, (Method*)method); 325 assert(m->is_native(), "sanity check"); 326 327 // handle arguments 328 SlowSignatureHandler ssh(m, (address)from, to); 329 ssh.iterate((uint64_t)CONST64(-1)); 330 331 // return result handler 332 return Interpreter::result_handler(m->result_type()); 333 JRT_END