diff -r 000000000000 -r a61af66fc99e src/cpu/x86/vm/interpreterRT_x86_64.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cpu/x86/vm/interpreterRT_x86_64.cpp Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,508 @@ +/* + * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_interpreterRT_x86_64.cpp.incl" + +#define __ _masm-> + +// Implementation of SignatureHandlerGenerator + +Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; } +Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; } +Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } + +void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset())); + +#ifdef _WIN64 + switch (_num_args) { + case 0: + __ movl(c_rarg1, src); + _num_args++; + break; + case 1: + __ movl(c_rarg2, src); + _num_args++; + break; + case 2: + __ movl(c_rarg3, src); + _num_args++; + break; + default: + __ movl(rax, src); + __ movl(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + break; + } +#else + switch (_num_int_args) { + case 0: + __ movl(c_rarg1, src); + _num_int_args++; + break; + case 1: + __ movl(c_rarg2, src); + _num_int_args++; + break; + case 2: + __ movl(c_rarg3, src); + _num_int_args++; + break; + case 3: + __ movl(c_rarg4, src); + _num_int_args++; + break; + case 4: + __ movl(c_rarg5, src); + _num_int_args++; + break; + default: + __ movl(rax, src); + __ movl(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + break; + } +#endif +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); + +#ifdef _WIN64 + switch (_num_args) { + case 0: + __ movq(c_rarg1, src); + _num_args++; + break; + case 1: + __ movq(c_rarg2, src); + _num_args++; + break; + case 2: + __ movq(c_rarg3, src); + _num_args++; + break; + case 3: + default: + __ movq(rax, src); + __ movq(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + break; + } +#else + switch (_num_int_args) { + case 0: + __ movq(c_rarg1, src); + _num_int_args++; + break; + case 1: + __ movq(c_rarg2, src); + _num_int_args++; + break; + case 2: + __ movq(c_rarg3, src); + _num_int_args++; + break; + case 3: + __ movq(c_rarg4, src); + _num_int_args++; + break; + case 4: + __ movq(c_rarg5, src); + _num_int_args++; + break; + default: + __ movq(rax, src); + __ movq(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + break; + } +#endif +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset())); + +#ifdef _WIN64 + if (_num_args < Argument::n_float_register_parameters_c-1) { + __ movflt(as_XMMRegister(++_num_args), src); + } else { + __ movl(rax, src); + __ movl(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + } +#else + if (_num_fp_args < Argument::n_float_register_parameters_c) { + __ movflt(as_XMMRegister(_num_fp_args++), src); + } else { + __ movl(rax, src); + __ movl(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + } +#endif +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); + +#ifdef _WIN64 + if (_num_args < Argument::n_float_register_parameters_c-1) { + __ movdbl(as_XMMRegister(++_num_args), src); + } else { + __ movq(rax, src); + __ movq(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + } +#else + if (_num_fp_args < Argument::n_float_register_parameters_c) { + __ movdbl(as_XMMRegister(_num_fp_args++), src); + } else { + __ movq(rax, src); + __ movq(Address(to(), _stack_offset), rax); + _stack_offset += wordSize; + } +#endif +} + +void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { + const Address src(from(), Interpreter::local_offset_in_bytes(offset())); + +#ifdef _WIN64 + switch (_num_args) { + case 0: + assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); + __ leaq(c_rarg1, src); + _num_args++; + break; + case 1: + __ leaq(rax, src); + __ xorl(c_rarg2, c_rarg2); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, c_rarg2, rax); + _num_args++; + break; + case 2: + __ leaq(rax, src); + __ xorl(c_rarg3, c_rarg3); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, c_rarg3, rax); + _num_args++; + break; + default: + __ leaq(rax, src); + __ xorl(temp(), temp()); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, temp(), rax); + __ movq(Address(to(), _stack_offset), temp()); + _stack_offset += wordSize; + break; + } +#else + switch (_num_int_args) { + case 0: + assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); + __ leaq(c_rarg1, src); + _num_int_args++; + break; + case 1: + __ leaq(rax, src); + __ xorl(c_rarg2, c_rarg2); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, c_rarg2, rax); + _num_int_args++; + break; + case 2: + __ leaq(rax, src); + __ xorl(c_rarg3, c_rarg3); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, c_rarg3, rax); + _num_int_args++; + break; + case 3: + __ leaq(rax, src); + __ xorl(c_rarg4, c_rarg4); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, c_rarg4, rax); + _num_int_args++; + break; + case 4: + __ leaq(rax, src); + __ xorl(c_rarg5, c_rarg5); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, c_rarg5, rax); + _num_int_args++; + break; + default: + __ leaq(rax, src); + __ xorl(temp(), temp()); + __ cmpq(src, 0); + __ cmovq(Assembler::notEqual, temp(), rax); + __ movq(Address(to(), _stack_offset), temp()); + _stack_offset += wordSize; + break; + } +#endif +} + +void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { + // generate code to handle arguments + iterate(fingerprint); + + // return result handler + __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type()))); + __ ret(0); + + __ flush(); +} + + +// Implementation of SignatureHandlerLibrary + +void SignatureHandlerLibrary::pd_set_handler(address handler) {} + + +#ifdef _WIN64 +class SlowSignatureHandler + : public NativeSignatureIterator { + private: + address _from; + intptr_t* _to; + intptr_t* _reg_args; + intptr_t* _fp_identifiers; + unsigned int _num_args; + +#ifdef ASSERT + void verify_tag(frame::Tag t) { + assert(!TaggedStackInterpreter || + *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag"); + } +#endif // ASSERT + + virtual void pass_int() + { + jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + debug_only(verify_tag(frame::TagValue)); + _from -= Interpreter::stackElementSize(); + + if (_num_args < Argument::n_int_register_parameters_c-1) { + *_reg_args++ = from_obj; + _num_args++; + } else { + *_to++ = from_obj; + } + } + + virtual void pass_long() + { + intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); + debug_only(verify_tag(frame::TagValue)); + _from -= 2*Interpreter::stackElementSize(); + + if (_num_args < Argument::n_int_register_parameters_c-1) { + *_reg_args++ = from_obj; + _num_args++; + } else { + *_to++ = from_obj; + } + } + + virtual void pass_object() + { + intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); + debug_only(verify_tag(frame::TagReference)); + _from -= Interpreter::stackElementSize(); + if (_num_args < Argument::n_int_register_parameters_c-1) { + *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; + _num_args++; + } else { + *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; + } + } + + virtual void pass_float() + { + jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + debug_only(verify_tag(frame::TagValue)); + _from -= Interpreter::stackElementSize(); + + if (_num_args < Argument::n_float_register_parameters_c-1) { + *_reg_args++ = from_obj; + *_fp_identifiers |= (0x01 << (_num_args*2)); // mark as float + _num_args++; + } else { + *_to++ = from_obj; + } + } + + virtual void pass_double() + { + intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); + debug_only(verify_tag(frame::TagValue)); + _from -= 2*Interpreter::stackElementSize(); + + if (_num_args < Argument::n_float_register_parameters_c-1) { + *_reg_args++ = from_obj; + *_fp_identifiers |= (0x3 << (_num_args*2)); // mark as double + _num_args++; + } else { + *_to++ = from_obj; + } + } + + public: + SlowSignatureHandler(methodHandle method, address from, intptr_t* to) + : NativeSignatureIterator(method) + { + _from = from; + _to = to; + + _reg_args = to - (method->is_static() ? 4 : 5); + _fp_identifiers = to - 2; + _to = _to + 4; // Windows reserves stack space for register arguments + *(int*) _fp_identifiers = 0; + _num_args = (method->is_static() ? 1 : 0); + } +}; +#else +class SlowSignatureHandler + : public NativeSignatureIterator { + private: + address _from; + intptr_t* _to; + intptr_t* _int_args; + intptr_t* _fp_args; + intptr_t* _fp_identifiers; + unsigned int _num_int_args; + unsigned int _num_fp_args; + +#ifdef ASSERT + void verify_tag(frame::Tag t) { + assert(!TaggedStackInterpreter || + *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag"); + } +#endif // ASSERT + + virtual void pass_int() + { + jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); + debug_only(verify_tag(frame::TagValue)); + _from -= Interpreter::stackElementSize(); + + if (_num_int_args < Argument::n_int_register_parameters_c-1) { + *_int_args++ = from_obj; + _num_int_args++; + } else { + *_to++ = from_obj; + } + } + + virtual void pass_long() + { + intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); + debug_only(verify_tag(frame::TagValue)); + _from -= 2*Interpreter::stackElementSize(); + + if (_num_int_args < Argument::n_int_register_parameters_c-1) { + *_int_args++ = from_obj; + _num_int_args++; + } else { + *_to++ = from_obj; + } + } + + virtual void pass_object() + { + intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); + debug_only(verify_tag(frame::TagReference)); + _from -= Interpreter::stackElementSize(); + + if (_num_int_args < Argument::n_int_register_parameters_c-1) { + *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr; + _num_int_args++; + } else { + *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; + } + } + + virtual void pass_float() + { + jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0)); + debug_only(verify_tag(frame::TagValue)); + _from -= Interpreter::stackElementSize(); + + if (_num_fp_args < Argument::n_float_register_parameters_c) { + *_fp_args++ = from_obj; + _num_fp_args++; + } else { + *_to++ = from_obj; + } + } + + virtual void pass_double() + { + intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); + _from -= 2*Interpreter::stackElementSize(); + + if (_num_fp_args < Argument::n_float_register_parameters_c) { + *_fp_args++ = from_obj; + *_fp_identifiers |= (1 << _num_fp_args); // mark as double + _num_fp_args++; + } else { + *_to++ = from_obj; + } + } + + public: + SlowSignatureHandler(methodHandle method, address from, intptr_t* to) + : NativeSignatureIterator(method) + { + _from = from; + _to = to; + + _int_args = to - (method->is_static() ? 14 : 15); + _fp_args = to - 9; + _fp_identifiers = to - 10; + *(int*) _fp_identifiers = 0; + _num_int_args = (method->is_static() ? 1 : 0); + _num_fp_args = 0; + } +}; +#endif + + +IRT_ENTRY(address, + InterpreterRuntime::slow_signature_handler(JavaThread* thread, + methodOopDesc* method, + intptr_t* from, + intptr_t* to)) + methodHandle m(thread, (methodOop)method); + assert(m->is_native(), "sanity check"); + + // handle arguments + SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1)); + + // return result handler + return Interpreter::result_handler(m->result_type()); +IRT_END