src/cpu/x86/vm/interpreterRT_x86_64.cpp

Wed, 17 Jun 2015 17:48:25 -0700

author
ascarpino
date
Wed, 17 Jun 2015 17:48:25 -0700
changeset 9788
44ef77ad417c
parent 9331
21681548b712
child 9448
73d689add964
permissions
-rw-r--r--

8073108: Use x86 and SPARC CPU instructions for GHASH acceleration
Reviewed-by: kvn, jrose, phh

duke@435 1 /*
kevinw@9331 2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "interpreter/interpreter.hpp"
stefank@2314 27 #include "interpreter/interpreterRuntime.hpp"
stefank@2314 28 #include "memory/allocation.inline.hpp"
stefank@2314 29 #include "memory/universe.inline.hpp"
coleenp@4037 30 #include "oops/method.hpp"
stefank@2314 31 #include "oops/oop.inline.hpp"
stefank@2314 32 #include "runtime/handles.inline.hpp"
stefank@2314 33 #include "runtime/icache.hpp"
stefank@2314 34 #include "runtime/interfaceSupport.hpp"
stefank@2314 35 #include "runtime/signature.hpp"
duke@435 36
duke@435 37 #define __ _masm->
duke@435 38
duke@435 39 // Implementation of SignatureHandlerGenerator
duke@435 40
duke@435 41 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
duke@435 42 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; }
duke@435 43 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
duke@435 44
duke@435 45 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
duke@435 46 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
duke@435 47
duke@435 48 #ifdef _WIN64
duke@435 49 switch (_num_args) {
duke@435 50 case 0:
duke@435 51 __ movl(c_rarg1, src);
duke@435 52 _num_args++;
duke@435 53 break;
duke@435 54 case 1:
duke@435 55 __ movl(c_rarg2, src);
duke@435 56 _num_args++;
duke@435 57 break;
duke@435 58 case 2:
duke@435 59 __ movl(c_rarg3, src);
duke@435 60 _num_args++;
duke@435 61 break;
duke@435 62 default:
duke@435 63 __ movl(rax, src);
duke@435 64 __ movl(Address(to(), _stack_offset), rax);
duke@435 65 _stack_offset += wordSize;
duke@435 66 break;
duke@435 67 }
duke@435 68 #else
duke@435 69 switch (_num_int_args) {
duke@435 70 case 0:
duke@435 71 __ movl(c_rarg1, src);
duke@435 72 _num_int_args++;
duke@435 73 break;
duke@435 74 case 1:
duke@435 75 __ movl(c_rarg2, src);
duke@435 76 _num_int_args++;
duke@435 77 break;
duke@435 78 case 2:
duke@435 79 __ movl(c_rarg3, src);
duke@435 80 _num_int_args++;
duke@435 81 break;
duke@435 82 case 3:
duke@435 83 __ movl(c_rarg4, src);
duke@435 84 _num_int_args++;
duke@435 85 break;
duke@435 86 case 4:
duke@435 87 __ movl(c_rarg5, src);
duke@435 88 _num_int_args++;
duke@435 89 break;
duke@435 90 default:
duke@435 91 __ movl(rax, src);
duke@435 92 __ movl(Address(to(), _stack_offset), rax);
duke@435 93 _stack_offset += wordSize;
duke@435 94 break;
duke@435 95 }
duke@435 96 #endif
duke@435 97 }
duke@435 98
duke@435 99 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
duke@435 100 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
duke@435 101
duke@435 102 #ifdef _WIN64
duke@435 103 switch (_num_args) {
duke@435 104 case 0:
never@739 105 __ movptr(c_rarg1, src);
duke@435 106 _num_args++;
duke@435 107 break;
duke@435 108 case 1:
never@739 109 __ movptr(c_rarg2, src);
duke@435 110 _num_args++;
duke@435 111 break;
duke@435 112 case 2:
never@739 113 __ movptr(c_rarg3, src);
duke@435 114 _num_args++;
duke@435 115 break;
duke@435 116 case 3:
duke@435 117 default:
never@739 118 __ movptr(rax, src);
never@739 119 __ movptr(Address(to(), _stack_offset), rax);
duke@435 120 _stack_offset += wordSize;
duke@435 121 break;
duke@435 122 }
duke@435 123 #else
duke@435 124 switch (_num_int_args) {
duke@435 125 case 0:
never@739 126 __ movptr(c_rarg1, src);
duke@435 127 _num_int_args++;
duke@435 128 break;
duke@435 129 case 1:
never@739 130 __ movptr(c_rarg2, src);
duke@435 131 _num_int_args++;
duke@435 132 break;
duke@435 133 case 2:
never@739 134 __ movptr(c_rarg3, src);
duke@435 135 _num_int_args++;
duke@435 136 break;
duke@435 137 case 3:
never@739 138 __ movptr(c_rarg4, src);
duke@435 139 _num_int_args++;
duke@435 140 break;
duke@435 141 case 4:
never@739 142 __ movptr(c_rarg5, src);
duke@435 143 _num_int_args++;
duke@435 144 break;
duke@435 145 default:
never@739 146 __ movptr(rax, src);
never@739 147 __ movptr(Address(to(), _stack_offset), rax);
duke@435 148 _stack_offset += wordSize;
duke@435 149 break;
duke@435 150 }
duke@435 151 #endif
duke@435 152 }
duke@435 153
duke@435 154 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
duke@435 155 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
duke@435 156
duke@435 157 #ifdef _WIN64
duke@435 158 if (_num_args < Argument::n_float_register_parameters_c-1) {
duke@435 159 __ movflt(as_XMMRegister(++_num_args), src);
duke@435 160 } else {
duke@435 161 __ movl(rax, src);
duke@435 162 __ movl(Address(to(), _stack_offset), rax);
duke@435 163 _stack_offset += wordSize;
duke@435 164 }
duke@435 165 #else
duke@435 166 if (_num_fp_args < Argument::n_float_register_parameters_c) {
duke@435 167 __ movflt(as_XMMRegister(_num_fp_args++), src);
duke@435 168 } else {
duke@435 169 __ movl(rax, src);
duke@435 170 __ movl(Address(to(), _stack_offset), rax);
duke@435 171 _stack_offset += wordSize;
duke@435 172 }
duke@435 173 #endif
duke@435 174 }
duke@435 175
duke@435 176 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
duke@435 177 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
duke@435 178
duke@435 179 #ifdef _WIN64
duke@435 180 if (_num_args < Argument::n_float_register_parameters_c-1) {
duke@435 181 __ movdbl(as_XMMRegister(++_num_args), src);
duke@435 182 } else {
never@739 183 __ movptr(rax, src);
never@739 184 __ movptr(Address(to(), _stack_offset), rax);
duke@435 185 _stack_offset += wordSize;
duke@435 186 }
duke@435 187 #else
duke@435 188 if (_num_fp_args < Argument::n_float_register_parameters_c) {
duke@435 189 __ movdbl(as_XMMRegister(_num_fp_args++), src);
duke@435 190 } else {
never@739 191 __ movptr(rax, src);
never@739 192 __ movptr(Address(to(), _stack_offset), rax);
duke@435 193 _stack_offset += wordSize;
duke@435 194 }
duke@435 195 #endif
duke@435 196 }
duke@435 197
duke@435 198 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
duke@435 199 const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
duke@435 200
duke@435 201 #ifdef _WIN64
duke@435 202 switch (_num_args) {
duke@435 203 case 0:
duke@435 204 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
never@739 205 __ lea(c_rarg1, src);
duke@435 206 _num_args++;
duke@435 207 break;
duke@435 208 case 1:
never@739 209 __ lea(rax, src);
duke@435 210 __ xorl(c_rarg2, c_rarg2);
never@739 211 __ cmpptr(src, 0);
never@739 212 __ cmov(Assembler::notEqual, c_rarg2, rax);
duke@435 213 _num_args++;
duke@435 214 break;
duke@435 215 case 2:
never@739 216 __ lea(rax, src);
duke@435 217 __ xorl(c_rarg3, c_rarg3);
never@739 218 __ cmpptr(src, 0);
never@739 219 __ cmov(Assembler::notEqual, c_rarg3, rax);
duke@435 220 _num_args++;
duke@435 221 break;
duke@435 222 default:
never@739 223 __ lea(rax, src);
duke@435 224 __ xorl(temp(), temp());
never@739 225 __ cmpptr(src, 0);
never@739 226 __ cmov(Assembler::notEqual, temp(), rax);
never@739 227 __ movptr(Address(to(), _stack_offset), temp());
duke@435 228 _stack_offset += wordSize;
duke@435 229 break;
duke@435 230 }
duke@435 231 #else
duke@435 232 switch (_num_int_args) {
duke@435 233 case 0:
duke@435 234 assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
never@739 235 __ lea(c_rarg1, src);
duke@435 236 _num_int_args++;
duke@435 237 break;
duke@435 238 case 1:
never@739 239 __ lea(rax, src);
duke@435 240 __ xorl(c_rarg2, c_rarg2);
never@739 241 __ cmpptr(src, 0);
never@739 242 __ cmov(Assembler::notEqual, c_rarg2, rax);
duke@435 243 _num_int_args++;
duke@435 244 break;
duke@435 245 case 2:
never@739 246 __ lea(rax, src);
duke@435 247 __ xorl(c_rarg3, c_rarg3);
never@739 248 __ cmpptr(src, 0);
never@739 249 __ cmov(Assembler::notEqual, c_rarg3, rax);
duke@435 250 _num_int_args++;
duke@435 251 break;
duke@435 252 case 3:
never@739 253 __ lea(rax, src);
duke@435 254 __ xorl(c_rarg4, c_rarg4);
never@739 255 __ cmpptr(src, 0);
never@739 256 __ cmov(Assembler::notEqual, c_rarg4, rax);
duke@435 257 _num_int_args++;
duke@435 258 break;
duke@435 259 case 4:
never@739 260 __ lea(rax, src);
duke@435 261 __ xorl(c_rarg5, c_rarg5);
never@739 262 __ cmpptr(src, 0);
never@739 263 __ cmov(Assembler::notEqual, c_rarg5, rax);
duke@435 264 _num_int_args++;
duke@435 265 break;
duke@435 266 default:
never@739 267 __ lea(rax, src);
duke@435 268 __ xorl(temp(), temp());
never@739 269 __ cmpptr(src, 0);
never@739 270 __ cmov(Assembler::notEqual, temp(), rax);
never@739 271 __ movptr(Address(to(), _stack_offset), temp());
duke@435 272 _stack_offset += wordSize;
duke@435 273 break;
duke@435 274 }
duke@435 275 #endif
duke@435 276 }
duke@435 277
duke@435 278 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
duke@435 279 // generate code to handle arguments
duke@435 280 iterate(fingerprint);
duke@435 281
duke@435 282 // return result handler
duke@435 283 __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));
duke@435 284 __ ret(0);
duke@435 285
duke@435 286 __ flush();
duke@435 287 }
duke@435 288
duke@435 289
duke@435 290 // Implementation of SignatureHandlerLibrary
duke@435 291
duke@435 292 void SignatureHandlerLibrary::pd_set_handler(address handler) {}
duke@435 293
duke@435 294
duke@435 295 #ifdef _WIN64
duke@435 296 class SlowSignatureHandler
duke@435 297 : public NativeSignatureIterator {
duke@435 298 private:
duke@435 299 address _from;
duke@435 300 intptr_t* _to;
duke@435 301 intptr_t* _reg_args;
duke@435 302 intptr_t* _fp_identifiers;
duke@435 303 unsigned int _num_args;
duke@435 304
duke@435 305 virtual void pass_int()
duke@435 306 {
duke@435 307 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
twisti@1861 308 _from -= Interpreter::stackElementSize;
duke@435 309
duke@435 310 if (_num_args < Argument::n_int_register_parameters_c-1) {
duke@435 311 *_reg_args++ = from_obj;
duke@435 312 _num_args++;
duke@435 313 } else {
duke@435 314 *_to++ = from_obj;
duke@435 315 }
duke@435 316 }
duke@435 317
duke@435 318 virtual void pass_long()
duke@435 319 {
duke@435 320 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
twisti@1861 321 _from -= 2*Interpreter::stackElementSize;
duke@435 322
duke@435 323 if (_num_args < Argument::n_int_register_parameters_c-1) {
duke@435 324 *_reg_args++ = from_obj;
duke@435 325 _num_args++;
duke@435 326 } else {
duke@435 327 *_to++ = from_obj;
duke@435 328 }
duke@435 329 }
duke@435 330
duke@435 331 virtual void pass_object()
duke@435 332 {
duke@435 333 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
twisti@1861 334 _from -= Interpreter::stackElementSize;
duke@435 335 if (_num_args < Argument::n_int_register_parameters_c-1) {
duke@435 336 *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
duke@435 337 _num_args++;
duke@435 338 } else {
duke@435 339 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
duke@435 340 }
duke@435 341 }
duke@435 342
duke@435 343 virtual void pass_float()
duke@435 344 {
duke@435 345 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
twisti@1861 346 _from -= Interpreter::stackElementSize;
duke@435 347
duke@435 348 if (_num_args < Argument::n_float_register_parameters_c-1) {
kevinw@9331 349 assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
duke@435 350 *_reg_args++ = from_obj;
kevinw@9331 351 *_fp_identifiers |= ((intptr_t)0x01 << (_num_args*2)); // mark as float
duke@435 352 _num_args++;
duke@435 353 } else {
duke@435 354 *_to++ = from_obj;
duke@435 355 }
duke@435 356 }
duke@435 357
duke@435 358 virtual void pass_double()
duke@435 359 {
duke@435 360 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
twisti@1861 361 _from -= 2*Interpreter::stackElementSize;
duke@435 362
duke@435 363 if (_num_args < Argument::n_float_register_parameters_c-1) {
kevinw@9331 364 assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
duke@435 365 *_reg_args++ = from_obj;
kevinw@9331 366 *_fp_identifiers |= ((intptr_t)0x3 << (_num_args*2)); // mark as double
duke@435 367 _num_args++;
duke@435 368 } else {
duke@435 369 *_to++ = from_obj;
duke@435 370 }
duke@435 371 }
duke@435 372
duke@435 373 public:
duke@435 374 SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
duke@435 375 : NativeSignatureIterator(method)
duke@435 376 {
duke@435 377 _from = from;
duke@435 378 _to = to;
duke@435 379
duke@435 380 _reg_args = to - (method->is_static() ? 4 : 5);
duke@435 381 _fp_identifiers = to - 2;
duke@435 382 _to = _to + 4; // Windows reserves stack space for register arguments
duke@435 383 *(int*) _fp_identifiers = 0;
duke@435 384 _num_args = (method->is_static() ? 1 : 0);
duke@435 385 }
duke@435 386 };
duke@435 387 #else
duke@435 388 class SlowSignatureHandler
duke@435 389 : public NativeSignatureIterator {
duke@435 390 private:
duke@435 391 address _from;
duke@435 392 intptr_t* _to;
duke@435 393 intptr_t* _int_args;
duke@435 394 intptr_t* _fp_args;
duke@435 395 intptr_t* _fp_identifiers;
duke@435 396 unsigned int _num_int_args;
duke@435 397 unsigned int _num_fp_args;
duke@435 398
duke@435 399 virtual void pass_int()
duke@435 400 {
duke@435 401 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
twisti@1861 402 _from -= Interpreter::stackElementSize;
duke@435 403
duke@435 404 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
duke@435 405 *_int_args++ = from_obj;
duke@435 406 _num_int_args++;
duke@435 407 } else {
duke@435 408 *_to++ = from_obj;
duke@435 409 }
duke@435 410 }
duke@435 411
duke@435 412 virtual void pass_long()
duke@435 413 {
duke@435 414 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
twisti@1861 415 _from -= 2*Interpreter::stackElementSize;
duke@435 416
duke@435 417 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
duke@435 418 *_int_args++ = from_obj;
duke@435 419 _num_int_args++;
duke@435 420 } else {
duke@435 421 *_to++ = from_obj;
duke@435 422 }
duke@435 423 }
duke@435 424
duke@435 425 virtual void pass_object()
duke@435 426 {
duke@435 427 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
twisti@1861 428 _from -= Interpreter::stackElementSize;
duke@435 429
duke@435 430 if (_num_int_args < Argument::n_int_register_parameters_c-1) {
duke@435 431 *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
duke@435 432 _num_int_args++;
duke@435 433 } else {
duke@435 434 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
duke@435 435 }
duke@435 436 }
duke@435 437
duke@435 438 virtual void pass_float()
duke@435 439 {
duke@435 440 jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
twisti@1861 441 _from -= Interpreter::stackElementSize;
duke@435 442
duke@435 443 if (_num_fp_args < Argument::n_float_register_parameters_c) {
duke@435 444 *_fp_args++ = from_obj;
duke@435 445 _num_fp_args++;
duke@435 446 } else {
duke@435 447 *_to++ = from_obj;
duke@435 448 }
duke@435 449 }
duke@435 450
duke@435 451 virtual void pass_double()
duke@435 452 {
duke@435 453 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
twisti@1861 454 _from -= 2*Interpreter::stackElementSize;
duke@435 455
duke@435 456 if (_num_fp_args < Argument::n_float_register_parameters_c) {
duke@435 457 *_fp_args++ = from_obj;
duke@435 458 *_fp_identifiers |= (1 << _num_fp_args); // mark as double
duke@435 459 _num_fp_args++;
duke@435 460 } else {
duke@435 461 *_to++ = from_obj;
duke@435 462 }
duke@435 463 }
duke@435 464
duke@435 465 public:
duke@435 466 SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
duke@435 467 : NativeSignatureIterator(method)
duke@435 468 {
duke@435 469 _from = from;
duke@435 470 _to = to;
duke@435 471
duke@435 472 _int_args = to - (method->is_static() ? 14 : 15);
duke@435 473 _fp_args = to - 9;
duke@435 474 _fp_identifiers = to - 10;
duke@435 475 *(int*) _fp_identifiers = 0;
duke@435 476 _num_int_args = (method->is_static() ? 1 : 0);
duke@435 477 _num_fp_args = 0;
duke@435 478 }
duke@435 479 };
duke@435 480 #endif
duke@435 481
duke@435 482
duke@435 483 IRT_ENTRY(address,
duke@435 484 InterpreterRuntime::slow_signature_handler(JavaThread* thread,
coleenp@4037 485 Method* method,
duke@435 486 intptr_t* from,
duke@435 487 intptr_t* to))
coleenp@4037 488 methodHandle m(thread, (Method*)method);
duke@435 489 assert(m->is_native(), "sanity check");
duke@435 490
duke@435 491 // handle arguments
duke@435 492 SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
duke@435 493
duke@435 494 // return result handler
duke@435 495 return Interpreter::result_handler(m->result_type());
duke@435 496 IRT_END

mercurial