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