src/cpu/x86/vm/interpreterRT_x86_64.cpp

Mon, 13 Feb 2012 02:29:22 -0800

author
twisti
date
Mon, 13 Feb 2012 02:29:22 -0800
changeset 3566
45a1bf98f1bb
parent 2314
f95d63e2154a
child 4037
da91efe96a93
permissions
-rw-r--r--

7141329: Strange values of stack_size in -XX:+TraceMethodHandles output
Reviewed-by: kvn, never

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

mercurial