src/cpu/x86/vm/interpreterRT_x86_64.cpp

Fri, 30 Apr 2010 08:37:24 -0700

author
twisti
date
Fri, 30 Apr 2010 08:37:24 -0700
changeset 1861
2338d41fbd81
parent 1279
bd02caa94611
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6943304: remove tagged stack interpreter
Reviewed-by: coleenp, never, gbenson

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

mercurial