Path: blob/master/src/hotspot/cpu/x86/interpreterRT_x86_64.cpp
41144 views
/*1* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "interpreter/interp_masm.hpp"26#include "interpreter/interpreter.hpp"27#include "interpreter/interpreterRuntime.hpp"28#include "memory/allocation.inline.hpp"29#include "oops/method.hpp"30#include "oops/oop.inline.hpp"31#include "runtime/handles.inline.hpp"32#include "runtime/icache.hpp"33#include "runtime/interfaceSupport.inline.hpp"34#include "runtime/signature.hpp"3536#define __ _masm->3738// Implementation of SignatureHandlerGenerator3940InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) :41NativeSignatureIterator(method) {42_masm = new MacroAssembler(buffer);43#ifdef AMD6444#ifdef _WIN6445_num_args = (method->is_static() ? 1 : 0);46_stack_offset = (Argument::n_int_register_parameters_c+1)* wordSize; // don't overwrite return address47#else48_num_int_args = (method->is_static() ? 1 : 0);49_num_fp_args = 0;50_stack_offset = wordSize; // don't overwrite return address51#endif // _WIN6452#endif // AMD6453}5455Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }56Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; }57Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }5859void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {60const Address src(from(), Interpreter::local_offset_in_bytes(offset()));6162#ifdef _WIN6463switch (_num_args) {64case 0:65__ movl(c_rarg1, src);66_num_args++;67break;68case 1:69__ movl(c_rarg2, src);70_num_args++;71break;72case 2:73__ movl(c_rarg3, src);74_num_args++;75break;76default:77__ movl(rax, src);78__ movl(Address(to(), _stack_offset), rax);79_stack_offset += wordSize;80break;81}82#else83switch (_num_int_args) {84case 0:85__ movl(c_rarg1, src);86_num_int_args++;87break;88case 1:89__ movl(c_rarg2, src);90_num_int_args++;91break;92case 2:93__ movl(c_rarg3, src);94_num_int_args++;95break;96case 3:97__ movl(c_rarg4, src);98_num_int_args++;99break;100case 4:101__ movl(c_rarg5, src);102_num_int_args++;103break;104default:105__ movl(rax, src);106__ movl(Address(to(), _stack_offset), rax);107_stack_offset += wordSize;108break;109}110#endif111}112113void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {114const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));115116#ifdef _WIN64117switch (_num_args) {118case 0:119__ movptr(c_rarg1, src);120_num_args++;121break;122case 1:123__ movptr(c_rarg2, src);124_num_args++;125break;126case 2:127__ movptr(c_rarg3, src);128_num_args++;129break;130case 3:131default:132__ movptr(rax, src);133__ movptr(Address(to(), _stack_offset), rax);134_stack_offset += wordSize;135break;136}137#else138switch (_num_int_args) {139case 0:140__ movptr(c_rarg1, src);141_num_int_args++;142break;143case 1:144__ movptr(c_rarg2, src);145_num_int_args++;146break;147case 2:148__ movptr(c_rarg3, src);149_num_int_args++;150break;151case 3:152__ movptr(c_rarg4, src);153_num_int_args++;154break;155case 4:156__ movptr(c_rarg5, src);157_num_int_args++;158break;159default:160__ movptr(rax, src);161__ movptr(Address(to(), _stack_offset), rax);162_stack_offset += wordSize;163break;164}165#endif166}167168void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {169const Address src(from(), Interpreter::local_offset_in_bytes(offset()));170171#ifdef _WIN64172if (_num_args < Argument::n_float_register_parameters_c-1) {173__ movflt(as_XMMRegister(++_num_args), src);174} else {175__ movl(rax, src);176__ movl(Address(to(), _stack_offset), rax);177_stack_offset += wordSize;178}179#else180if (_num_fp_args < Argument::n_float_register_parameters_c) {181__ movflt(as_XMMRegister(_num_fp_args++), src);182} else {183__ movl(rax, src);184__ movl(Address(to(), _stack_offset), rax);185_stack_offset += wordSize;186}187#endif188}189190void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {191const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));192193#ifdef _WIN64194if (_num_args < Argument::n_float_register_parameters_c-1) {195__ movdbl(as_XMMRegister(++_num_args), src);196} else {197__ movptr(rax, src);198__ movptr(Address(to(), _stack_offset), rax);199_stack_offset += wordSize;200}201#else202if (_num_fp_args < Argument::n_float_register_parameters_c) {203__ movdbl(as_XMMRegister(_num_fp_args++), src);204} else {205__ movptr(rax, src);206__ movptr(Address(to(), _stack_offset), rax);207_stack_offset += wordSize;208}209#endif210}211212void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {213const Address src(from(), Interpreter::local_offset_in_bytes(offset()));214215#ifdef _WIN64216switch (_num_args) {217case 0:218assert(offset() == 0, "argument register 1 can only be (non-null) receiver");219__ lea(c_rarg1, src);220_num_args++;221break;222case 1:223__ lea(rax, src);224__ xorl(c_rarg2, c_rarg2);225__ cmpptr(src, 0);226__ cmov(Assembler::notEqual, c_rarg2, rax);227_num_args++;228break;229case 2:230__ lea(rax, src);231__ xorl(c_rarg3, c_rarg3);232__ cmpptr(src, 0);233__ cmov(Assembler::notEqual, c_rarg3, rax);234_num_args++;235break;236default:237__ lea(rax, src);238__ xorl(temp(), temp());239__ cmpptr(src, 0);240__ cmov(Assembler::notEqual, temp(), rax);241__ movptr(Address(to(), _stack_offset), temp());242_stack_offset += wordSize;243break;244}245#else246switch (_num_int_args) {247case 0:248assert(offset() == 0, "argument register 1 can only be (non-null) receiver");249__ lea(c_rarg1, src);250_num_int_args++;251break;252case 1:253__ lea(rax, src);254__ xorl(c_rarg2, c_rarg2);255__ cmpptr(src, 0);256__ cmov(Assembler::notEqual, c_rarg2, rax);257_num_int_args++;258break;259case 2:260__ lea(rax, src);261__ xorl(c_rarg3, c_rarg3);262__ cmpptr(src, 0);263__ cmov(Assembler::notEqual, c_rarg3, rax);264_num_int_args++;265break;266case 3:267__ lea(rax, src);268__ xorl(c_rarg4, c_rarg4);269__ cmpptr(src, 0);270__ cmov(Assembler::notEqual, c_rarg4, rax);271_num_int_args++;272break;273case 4:274__ lea(rax, src);275__ xorl(c_rarg5, c_rarg5);276__ cmpptr(src, 0);277__ cmov(Assembler::notEqual, c_rarg5, rax);278_num_int_args++;279break;280default:281__ lea(rax, src);282__ xorl(temp(), temp());283__ cmpptr(src, 0);284__ cmov(Assembler::notEqual, temp(), rax);285__ movptr(Address(to(), _stack_offset), temp());286_stack_offset += wordSize;287break;288}289#endif290}291292void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {293// generate code to handle arguments294iterate(fingerprint);295296// return result handler297__ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));298__ ret(0);299300__ flush();301}302303304// Implementation of SignatureHandlerLibrary305306void SignatureHandlerLibrary::pd_set_handler(address handler) {}307308309#ifdef _WIN64310class SlowSignatureHandler311: public NativeSignatureIterator {312private:313address _from;314intptr_t* _to;315intptr_t* _reg_args;316intptr_t* _fp_identifiers;317unsigned int _num_args;318319virtual void pass_int()320{321jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));322_from -= Interpreter::stackElementSize;323324if (_num_args < Argument::n_int_register_parameters_c-1) {325*_reg_args++ = from_obj;326_num_args++;327} else {328*_to++ = from_obj;329}330}331332virtual void pass_long()333{334intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));335_from -= 2*Interpreter::stackElementSize;336337if (_num_args < Argument::n_int_register_parameters_c-1) {338*_reg_args++ = from_obj;339_num_args++;340} else {341*_to++ = from_obj;342}343}344345virtual void pass_object()346{347intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));348_from -= Interpreter::stackElementSize;349if (_num_args < Argument::n_int_register_parameters_c-1) {350*_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;351_num_args++;352} else {353*_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;354}355}356357virtual void pass_float()358{359jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));360_from -= Interpreter::stackElementSize;361362if (_num_args < Argument::n_float_register_parameters_c-1) {363assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");364*_reg_args++ = from_obj;365*_fp_identifiers |= ((intptr_t)0x01 << (_num_args*2)); // mark as float366_num_args++;367} else {368*_to++ = from_obj;369}370}371372virtual void pass_double()373{374intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));375_from -= 2*Interpreter::stackElementSize;376377if (_num_args < Argument::n_float_register_parameters_c-1) {378assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");379*_reg_args++ = from_obj;380*_fp_identifiers |= ((intptr_t)0x3 << (_num_args*2)); // mark as double381_num_args++;382} else {383*_to++ = from_obj;384}385}386387public:388SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)389: NativeSignatureIterator(method)390{391_from = from;392_to = to;393394_reg_args = to - (method->is_static() ? 4 : 5);395_fp_identifiers = to - 2;396_to = _to + 4; // Windows reserves stack space for register arguments397*(int*) _fp_identifiers = 0;398_num_args = (method->is_static() ? 1 : 0);399}400};401#else402class SlowSignatureHandler403: public NativeSignatureIterator {404private:405address _from;406intptr_t* _to;407intptr_t* _int_args;408intptr_t* _fp_args;409intptr_t* _fp_identifiers;410unsigned int _num_int_args;411unsigned int _num_fp_args;412413virtual void pass_int()414{415jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));416_from -= Interpreter::stackElementSize;417418if (_num_int_args < Argument::n_int_register_parameters_c-1) {419*_int_args++ = from_obj;420_num_int_args++;421} else {422*_to++ = from_obj;423}424}425426virtual void pass_long()427{428intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));429_from -= 2*Interpreter::stackElementSize;430431if (_num_int_args < Argument::n_int_register_parameters_c-1) {432*_int_args++ = from_obj;433_num_int_args++;434} else {435*_to++ = from_obj;436}437}438439virtual void pass_object()440{441intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));442_from -= Interpreter::stackElementSize;443444if (_num_int_args < Argument::n_int_register_parameters_c-1) {445*_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;446_num_int_args++;447} else {448*_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;449}450}451452virtual void pass_float()453{454jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));455_from -= Interpreter::stackElementSize;456457if (_num_fp_args < Argument::n_float_register_parameters_c) {458*_fp_args++ = from_obj;459_num_fp_args++;460} else {461*_to++ = from_obj;462}463}464465virtual void pass_double()466{467intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));468_from -= 2*Interpreter::stackElementSize;469470if (_num_fp_args < Argument::n_float_register_parameters_c) {471*_fp_args++ = from_obj;472*_fp_identifiers |= (1 << _num_fp_args); // mark as double473_num_fp_args++;474} else {475*_to++ = from_obj;476}477}478479public:480SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)481: NativeSignatureIterator(method)482{483_from = from;484_to = to;485486_int_args = to - (method->is_static() ? 14 : 15);487_fp_args = to - 9;488_fp_identifiers = to - 10;489*(int*) _fp_identifiers = 0;490_num_int_args = (method->is_static() ? 1 : 0);491_num_fp_args = 0;492}493};494#endif495496497JRT_ENTRY(address,498InterpreterRuntime::slow_signature_handler(JavaThread* current,499Method* method,500intptr_t* from,501intptr_t* to))502methodHandle m(current, (Method*)method);503assert(m->is_native(), "sanity check");504505// handle arguments506SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));507508// return result handler509return Interpreter::result_handler(m->result_type());510JRT_END511512513