1 /* 2 * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "asm/macroAssembler.inline.hpp" 27 #include "interpreter/interp_masm.hpp" 28 #include "interpreter/interpreter.hpp" 29 #include "interpreter/interpreterRuntime.hpp" 30 #include "memory/allocation.inline.hpp" 31 #include "memory/universe.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 InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator( 42 const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) { 43 _masm = new MacroAssembler(buffer); 44 _abi_offset = 0; 45 _ireg = is_static() ? 2 : 1; 46 #ifdef __ABI_HARD__ 47 #ifdef AARCH64 48 _freg = 0; 49 #else 50 _fp_slot = 0; 51 _single_fpr_slot = 0; 52 #endif 53 #endif 54 } 55 56 #ifdef SHARING_FAST_NATIVE_FINGERPRINTS 57 // mapping from SignatureIterator param to (common) type of parsing 58 static const u1 shared_type[] = { 59 (u1) SignatureIterator::int_parm, // bool 60 (u1) SignatureIterator::int_parm, // byte 61 (u1) SignatureIterator::int_parm, // char 62 (u1) SignatureIterator::int_parm, // short 63 (u1) SignatureIterator::int_parm, // int 64 (u1) SignatureIterator::long_parm, // long 65 #ifndef __ABI_HARD__ 66 (u1) SignatureIterator::int_parm, // float, passed as int 67 (u1) SignatureIterator::long_parm, // double, passed as long 68 #else 69 (u1) SignatureIterator::float_parm, // float 70 (u1) SignatureIterator::double_parm, // double 71 #endif 72 (u1) SignatureIterator::obj_parm, // obj 73 (u1) SignatureIterator::done_parm // done 74 }; 75 76 uint64_t InterpreterRuntime::normalize_fast_native_fingerprint(uint64_t fingerprint) { 77 if (fingerprint == UCONST64(-1)) { 78 // special signature used when the argument list cannot be encoded in a 64 bits value 79 return fingerprint; 80 } 81 int shift = SignatureIterator::static_feature_size; 82 uint64_t result = fingerprint & ((1 << shift) - 1); 83 fingerprint >>= shift; 84 85 BasicType ret_type = (BasicType) (fingerprint & SignatureIterator::result_feature_mask); 86 // For ARM, the fast signature handler only needs to know whether 87 // the return value must be unboxed. T_OBJECT and T_ARRAY need not 88 // be distinguished from each other and all other return values 89 // behave like integers with respect to the handler except T_BOOLEAN 90 // which must be mapped to the range 0..1. 91 bool unbox = (ret_type == T_OBJECT) || (ret_type == T_ARRAY); 92 if (unbox) { 93 ret_type = T_OBJECT; 94 } else if (ret_type != T_BOOLEAN) { 95 ret_type = T_INT; 96 } 97 result |= ((uint64_t) ret_type) << shift; 98 shift += SignatureIterator::result_feature_size; 99 fingerprint >>= SignatureIterator::result_feature_size; 100 101 while (true) { 102 uint32_t type = (uint32_t) (fingerprint & SignatureIterator::parameter_feature_mask); 103 if (type == SignatureIterator::done_parm) { 104 result |= ((uint64_t) SignatureIterator::done_parm) << shift; 105 return result; 106 } 107 assert((type >= SignatureIterator::bool_parm) && (type <= SignatureIterator::obj_parm), "check fingerprint encoding"); 108 int shared = shared_type[type - SignatureIterator::bool_parm]; 109 result |= ((uint64_t) shared) << shift; 110 shift += SignatureIterator::parameter_feature_size; 111 fingerprint >>= SignatureIterator::parameter_feature_size; 112 } 113 } 114 #endif // SHARING_FAST_NATIVE_FINGERPRINTS 115 116 // Implementation of SignatureHandlerGenerator 117 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { 118 if (_ireg < GPR_PARAMS) { 119 Register dst = as_Register(_ireg); 120 __ ldr_s32(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 121 _ireg++; 122 } else { 123 __ ldr_s32(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 124 __ str_32(Rtemp, Address(SP, _abi_offset * wordSize)); 125 _abi_offset++; 126 } 127 } 128 129 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { 130 #ifdef AARCH64 131 if (_ireg < GPR_PARAMS) { 132 Register dst = as_Register(_ireg); 133 __ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1))); 134 _ireg++; 135 } else { 136 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1))); 137 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 138 _abi_offset++; 139 } 140 #else 141 if (_ireg <= 2) { 142 #if (ALIGN_WIDE_ARGUMENTS == 1) 143 if ((_ireg & 1) != 0) { 144 // 64-bit values should be 8-byte aligned 145 _ireg++; 146 } 147 #endif 148 Register dst1 = as_Register(_ireg); 149 Register dst2 = as_Register(_ireg+1); 150 __ ldr(dst1, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1))); 151 __ ldr(dst2, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 152 _ireg += 2; 153 #if (ALIGN_WIDE_ARGUMENTS == 0) 154 } else if (_ireg == 3) { 155 // uses R3 + one stack slot 156 Register dst1 = as_Register(_ireg); 157 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 158 __ ldr(dst1, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1))); 159 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 160 _ireg += 1; 161 _abi_offset += 1; 162 #endif 163 } else { 164 #if (ALIGN_WIDE_ARGUMENTS == 1) 165 if(_abi_offset & 1) _abi_offset++; 166 #endif 167 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1))); 168 __ str(Rtemp, Address(SP, (_abi_offset) * wordSize)); 169 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 170 __ str(Rtemp, Address(SP, (_abi_offset+1) * wordSize)); 171 _abi_offset += 2; 172 _ireg = 4; 173 } 174 #endif // AARCH64 175 } 176 177 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { 178 #ifdef AARCH64 179 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 180 __ cmp(Rtemp, 0); 181 __ sub(Rtemp, Rlocals, -Interpreter::local_offset_in_bytes(offset())); 182 if (_ireg < GPR_PARAMS) { 183 Register dst = as_Register(_ireg); 184 __ csel(dst, ZR, Rtemp, eq); 185 _ireg++; 186 } else { 187 __ csel(Rtemp, ZR, Rtemp, eq); 188 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 189 _abi_offset++; 190 } 191 #else 192 if (_ireg < 4) { 193 Register dst = as_Register(_ireg); 194 __ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 195 __ cmp(dst, 0); 196 __ sub(dst, Rlocals, -Interpreter::local_offset_in_bytes(offset()), ne); 197 _ireg++; 198 } else { 199 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 200 __ cmp(Rtemp, 0); 201 __ sub(Rtemp, Rlocals, -Interpreter::local_offset_in_bytes(offset()), ne); 202 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 203 _abi_offset++; 204 } 205 #endif // AARCH64 206 } 207 208 #ifndef __ABI_HARD__ 209 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { 210 if (_ireg < 4) { 211 Register dst = as_Register(_ireg); 212 __ ldr(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 213 _ireg++; 214 } else { 215 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 216 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 217 _abi_offset++; 218 } 219 } 220 221 #else 222 #ifndef __SOFTFP__ 223 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { 224 #ifdef AARCH64 225 if (_freg < FPR_PARAMS) { 226 FloatRegister dst = as_FloatRegister(_freg); 227 __ ldr_s(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 228 _freg++; 229 } else { 230 __ ldr_u32(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 231 __ str_32(Rtemp, Address(SP, _abi_offset * wordSize)); 232 _abi_offset++; 233 } 234 #else 235 if((_fp_slot < 16) || (_single_fpr_slot & 1)) { 236 if ((_single_fpr_slot & 1) == 0) { 237 _single_fpr_slot = _fp_slot; 238 _fp_slot += 2; 239 } 240 __ flds(as_FloatRegister(_single_fpr_slot), Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 241 _single_fpr_slot++; 242 } else { 243 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 244 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 245 _abi_offset++; 246 } 247 #endif // AARCH64 248 } 249 250 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { 251 #ifdef AARCH64 252 if (_freg < FPR_PARAMS) { 253 FloatRegister dst = as_FloatRegister(_freg); 254 __ ldr_d(dst, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1))); 255 _freg++; 256 } else { 257 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset() + 1))); 258 __ str(Rtemp, Address(SP, _abi_offset * wordSize)); 259 _abi_offset++; 260 } 261 #else 262 if(_fp_slot <= 14) { 263 __ fldd(as_FloatRegister(_fp_slot), Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1))); 264 _fp_slot += 2; 265 } else { 266 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()+1))); 267 __ str(Rtemp, Address(SP, (_abi_offset) * wordSize)); 268 __ ldr(Rtemp, Address(Rlocals, Interpreter::local_offset_in_bytes(offset()))); 269 __ str(Rtemp, Address(SP, (_abi_offset+1) * wordSize)); 270 _abi_offset += 2; 271 _single_fpr_slot = 16; 272 } 273 #endif // AARCH64 274 } 275 #endif // __SOFTFP__ 276 #endif // __ABI_HARD__ 277 278 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { 279 iterate(fingerprint); 280 281 BasicType result_type = SignatureIterator::return_type(fingerprint); 282 283 address result_handler = Interpreter::result_handler(result_type); 284 285 __ mov_slow(R0, (intptr_t)result_handler); 286 287 __ ret(); 288 } 289 290 291 // Implementation of SignatureHandlerLibrary 292 293 void SignatureHandlerLibrary::pd_set_handler(address handler) {} 294 295 class SlowSignatureHandler: public NativeSignatureIterator { 296 private: 297 address _from; 298 intptr_t* _to; 299 300 #ifndef __ABI_HARD__ 301 virtual void pass_int() { 302 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 303 _from -= Interpreter::stackElementSize; 304 } 305 306 virtual void pass_float() { 307 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 308 _from -= Interpreter::stackElementSize; 309 } 310 311 virtual void pass_long() { 312 #if (ALIGN_WIDE_ARGUMENTS == 1) 313 if (((intptr_t)_to & 7) != 0) { 314 // 64-bit values should be 8-byte aligned 315 _to++; 316 } 317 #endif 318 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 319 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 320 _to += 2; 321 _from -= 2*Interpreter::stackElementSize; 322 } 323 324 virtual void pass_object() { 325 intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0)); 326 *_to++ = (*(intptr_t*)from_addr == 0) ? (intptr_t)NULL : from_addr; 327 _from -= Interpreter::stackElementSize; 328 } 329 330 #else 331 332 intptr_t* _toFP; 333 intptr_t* _toGP; 334 int _last_gp; 335 int _last_fp; 336 #ifndef AARCH64 337 int _last_single_fp; 338 #endif // !AARCH64 339 340 virtual void pass_int() { 341 if(_last_gp < GPR_PARAMS) { 342 _toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 343 } else { 344 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 345 } 346 _from -= Interpreter::stackElementSize; 347 } 348 349 virtual void pass_long() { 350 #ifdef AARCH64 351 if(_last_gp < GPR_PARAMS) { 352 _toGP[_last_gp++] = *(jlong *)(_from+Interpreter::local_offset_in_bytes(1)); 353 } else { 354 *_to++ = *(jlong *)(_from+Interpreter::local_offset_in_bytes(1)); 355 } 356 #else 357 assert(ALIGN_WIDE_ARGUMENTS == 1, "ABI_HARD not supported with unaligned wide arguments"); 358 if (_last_gp <= 2) { 359 if(_last_gp & 1) _last_gp++; 360 _toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(1)); 361 _toGP[_last_gp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 362 } else { 363 if (((intptr_t)_to & 7) != 0) { 364 // 64-bit values should be 8-byte aligned 365 _to++; 366 } 367 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 368 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 369 _to += 2; 370 _last_gp = 4; 371 } 372 #endif // AARCH64 373 _from -= 2*Interpreter::stackElementSize; 374 } 375 376 virtual void pass_object() { 377 intptr_t from_addr = (intptr_t)(_from + Interpreter::local_offset_in_bytes(0)); 378 if(_last_gp < GPR_PARAMS) { 379 _toGP[_last_gp++] = (*(intptr_t*)from_addr == 0) ? NULL : from_addr; 380 } else { 381 *_to++ = (*(intptr_t*)from_addr == 0) ? NULL : from_addr; 382 } 383 _from -= Interpreter::stackElementSize; 384 } 385 386 virtual void pass_float() { 387 #ifdef AARCH64 388 if(_last_fp < FPR_PARAMS) { 389 _toFP[_last_fp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 390 } else { 391 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 392 } 393 #else 394 if((_last_fp < 16) || (_last_single_fp & 1)) { 395 if ((_last_single_fp & 1) == 0) { 396 _last_single_fp = _last_fp; 397 _last_fp += 2; 398 } 399 400 _toFP[_last_single_fp++] = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 401 } else { 402 *_to++ = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); 403 } 404 #endif // AARCH64 405 _from -= Interpreter::stackElementSize; 406 } 407 408 virtual void pass_double() { 409 #ifdef AARCH64 410 if(_last_fp < FPR_PARAMS) { 411 _toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 412 } else { 413 *_to++ = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 414 } 415 #else 416 assert(ALIGN_WIDE_ARGUMENTS == 1, "ABI_HARD not supported with unaligned wide arguments"); 417 if(_last_fp <= 14) { 418 _toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 419 _toFP[_last_fp++] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 420 } else { 421 if (((intptr_t)_to & 7) != 0) { // 64-bit values should be 8-byte aligned 422 _to++; 423 } 424 _to[0] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); 425 _to[1] = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0)); 426 _to += 2; 427 _last_single_fp = 16; 428 } 429 #endif // AARCH64 430 _from -= 2*Interpreter::stackElementSize; 431 } 432 433 #endif // !__ABI_HARD__ 434 435 public: 436 SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to) : 437 NativeSignatureIterator(method) { 438 _from = from; 439 440 #ifdef __ABI_HARD__ 441 _toGP = to; 442 _toFP = _toGP + GPR_PARAMS; 443 _to = _toFP + AARCH64_ONLY(FPR_PARAMS) NOT_AARCH64(8*2); 444 _last_gp = (is_static() ? 2 : 1); 445 _last_fp = 0; 446 #ifndef AARCH64 447 _last_single_fp = 0; 448 #endif // !AARCH64 449 #else 450 _to = to + (is_static() ? 2 : 1); 451 #endif // __ABI_HARD__ 452 } 453 }; 454 455 IRT_ENTRY(address, InterpreterRuntime::slow_signature_handler(JavaThread* thread, Method* method, intptr_t* from, intptr_t* to)) 456 methodHandle m(thread, (Method*)method); 457 assert(m->is_native(), "sanity check"); 458 SlowSignatureHandler(m, (address)from, to).iterate(UCONST64(-1)); 459 return Interpreter::result_handler(m->result_type()); 460 IRT_END