src/cpu/x86/vm/interpreterRT_x86_64.cpp

Fri, 16 Aug 2019 16:50:17 +0200

author
eosterlund
date
Fri, 16 Aug 2019 16:50:17 +0200
changeset 9834
bb1da64b0492
parent 9331
21681548b712
child 9448
73d689add964
permissions
-rw-r--r--

8229345: Memory leak due to vtable stubs not being shared on SPARC
Reviewed-by: mdoerr, dholmes, kvn

     1 /*
     2  * Copyright (c) 2003, 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  */
    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/method.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       assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
   350       *_reg_args++ = from_obj;
   351       *_fp_identifiers |= ((intptr_t)0x01 << (_num_args*2)); // mark as float
   352       _num_args++;
   353     } else {
   354       *_to++ = from_obj;
   355     }
   356   }
   358   virtual void pass_double()
   359   {
   360     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
   361     _from -= 2*Interpreter::stackElementSize;
   363     if (_num_args < Argument::n_float_register_parameters_c-1) {
   364       assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
   365       *_reg_args++ = from_obj;
   366       *_fp_identifiers |= ((intptr_t)0x3 << (_num_args*2)); // mark as double
   367       _num_args++;
   368     } else {
   369       *_to++ = from_obj;
   370     }
   371   }
   373  public:
   374   SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
   375     : NativeSignatureIterator(method)
   376   {
   377     _from = from;
   378     _to   = to;
   380     _reg_args = to - (method->is_static() ? 4 : 5);
   381     _fp_identifiers = to - 2;
   382     _to = _to + 4;  // Windows reserves stack space for register arguments
   383     *(int*) _fp_identifiers = 0;
   384     _num_args = (method->is_static() ? 1 : 0);
   385   }
   386 };
   387 #else
   388 class SlowSignatureHandler
   389   : public NativeSignatureIterator {
   390  private:
   391   address   _from;
   392   intptr_t* _to;
   393   intptr_t* _int_args;
   394   intptr_t* _fp_args;
   395   intptr_t* _fp_identifiers;
   396   unsigned int _num_int_args;
   397   unsigned int _num_fp_args;
   399   virtual void pass_int()
   400   {
   401     jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
   402     _from -= Interpreter::stackElementSize;
   404     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
   405       *_int_args++ = from_obj;
   406       _num_int_args++;
   407     } else {
   408       *_to++ = from_obj;
   409     }
   410   }
   412   virtual void pass_long()
   413   {
   414     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
   415     _from -= 2*Interpreter::stackElementSize;
   417     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
   418       *_int_args++ = from_obj;
   419       _num_int_args++;
   420     } else {
   421       *_to++ = from_obj;
   422     }
   423   }
   425   virtual void pass_object()
   426   {
   427     intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
   428     _from -= Interpreter::stackElementSize;
   430     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
   431       *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
   432       _num_int_args++;
   433     } else {
   434       *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
   435     }
   436   }
   438   virtual void pass_float()
   439   {
   440     jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
   441     _from -= Interpreter::stackElementSize;
   443     if (_num_fp_args < Argument::n_float_register_parameters_c) {
   444       *_fp_args++ = from_obj;
   445       _num_fp_args++;
   446     } else {
   447       *_to++ = from_obj;
   448     }
   449   }
   451   virtual void pass_double()
   452   {
   453     intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
   454     _from -= 2*Interpreter::stackElementSize;
   456     if (_num_fp_args < Argument::n_float_register_parameters_c) {
   457       *_fp_args++ = from_obj;
   458       *_fp_identifiers |= (1 << _num_fp_args); // mark as double
   459       _num_fp_args++;
   460     } else {
   461       *_to++ = from_obj;
   462     }
   463   }
   465  public:
   466   SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
   467     : NativeSignatureIterator(method)
   468   {
   469     _from = from;
   470     _to   = to;
   472     _int_args = to - (method->is_static() ? 14 : 15);
   473     _fp_args =  to - 9;
   474     _fp_identifiers = to - 10;
   475     *(int*) _fp_identifiers = 0;
   476     _num_int_args = (method->is_static() ? 1 : 0);
   477     _num_fp_args = 0;
   478   }
   479 };
   480 #endif
   483 IRT_ENTRY(address,
   484           InterpreterRuntime::slow_signature_handler(JavaThread* thread,
   485                                                      Method* method,
   486                                                      intptr_t* from,
   487                                                      intptr_t* to))
   488   methodHandle m(thread, (Method*)method);
   489   assert(m->is_native(), "sanity check");
   491   // handle arguments
   492   SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1));
   494   // return result handler
   495   return Interpreter::result_handler(m->result_type());
   496 IRT_END

mercurial