Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/aarch32/vm/interpreterRT_aarch32.cpp
32285 views
/*1* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2014, Red Hat Inc. All rights reserved.3* Copyright (c) 2015, Linaro Ltd. All rights reserved.4* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.5*6* This code is free software; you can redistribute it and/or modify it7* under the terms of the GNU General Public License version 2 only, as8* published by the Free Software Foundation.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*24*/2526#include "precompiled.hpp"27#include "interpreter/interpreter.hpp"28#include "interpreter/interpreterRuntime.hpp"29#include "memory/allocation.inline.hpp"30#include "memory/universe.inline.hpp"31#include "oops/method.hpp"32#include "oops/oop.inline.hpp"33#include "runtime/handles.inline.hpp"34#include "runtime/icache.hpp"35#include "runtime/interfaceSupport.hpp"36#include "runtime/signature.hpp"3738#define __ _masm->3940/*#define print_copy(name, off) \41__ mov(rscratch1, (address)name);\42__ mov(rscratch2, off);\43__ reg_printf("%s copied from offset %p + %d\n", rscratch1, from(), rscratch2);*/4445#define print_copy(name, off)4647// Implementation of SignatureHandlerGenerator48Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }49Register InterpreterRuntime::SignatureHandlerGenerator::to() { return r4; }50Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }5152void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {53print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));54const Address src(from(), Interpreter::local_offset_in_bytes(offset()));5556switch (_num_int_args) {57case 0:58__ ldr(c_rarg1, src);59_num_int_args++;60break;61case 1:62__ ldr(c_rarg2, src);63_num_int_args++;64break;65case 2:66__ ldr(c_rarg3, src);67_num_int_args++;68break;69default:70__ ldr(r0, src);71__ str(r0, Address(to(), _stack_offset));72_stack_offset += wordSize;73_num_int_args++;74break;75}76}7778void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {79print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset() + 1));80const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));81// Needs to be aligned to even registers. Means also won't be split across82// registers and stack.8384switch (_num_int_args) {85case 0:86case 1:87__ ldrd(c_rarg2, c_rarg3, src);88_num_int_args = 3; // force next args onto stack89break;90default:91__ ldrd(r0, temp(), src);92_stack_offset = (_stack_offset + 7) & ~7; // Align on 8-byte boundary93__ strd(r0, temp(), Address(to(), _stack_offset));94_stack_offset += 2 * wordSize;95_num_int_args += 2;96break;97}98}99100#ifdef HARD_FLOAT_CC101void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {102print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));103const Address src(from(), Interpreter::local_offset_in_bytes(offset()));104105if (_fp_arg_mask & ((1 << Argument::n_float_register_parameters_c*2)-1)) {106unsigned index = __builtin_ctz(_fp_arg_mask);107__ vldr_f32(as_FloatRegister(index), src);108_fp_arg_mask &= ~(1 << index);109_next_double_dex += (~index) & 1;110} else {111__ ldr(r0, src);112__ str(r0, Address(to(), _stack_offset));113_stack_offset += wordSize;114}115}116117void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {118print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset() + 1));119const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));120121if (_next_double_dex < Argument::n_float_register_parameters_c) {122_fp_arg_mask &= ~((3 << _next_double_dex*2) | ((1 << _next_double_dex+16)));123__ vldr_f64(as_DoubleFloatRegister(_next_double_dex++), src);124} else {125// make future floats allocate on stack too126_fp_arg_mask &= ~((1 << Argument::n_float_register_parameters_c*2)-1);127128__ ldrd(r0, temp(), src);129_stack_offset = (_stack_offset + 7) & ~7;130__ strd(r0, temp(), Address(to(), _stack_offset));131_stack_offset += 2 * wordSize;132}133}134#else135// Just pass them in integer registers and on the stack as we would136// any other argument137void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {138pass_int();139}140141void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {142pass_long();143}144#endif //HARD_FLOAT_CC145146void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {147print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));148149switch (_num_int_args) {150case 0:151assert(offset() == 0, "argument register 1 can only be (non-null) receiver");152__ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));153_num_int_args++;154break;155case 1:156{157__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));158__ mov(c_rarg2, 0);159__ ldr(temp(), r0);160Label L;161__ cbz(temp(), L);162__ mov(c_rarg2, r0);163__ bind(L);164_num_int_args++;165break;166}167case 2:168{169__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));170__ mov(c_rarg3, 0);171__ ldr(temp(), r0);172Label L;173__ cbz(temp(), L);174__ mov(c_rarg3, r0);175__ bind(L);176_num_int_args++;177break;178}179default:180{181__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));182__ ldr(temp(), r0);183Label L;184__ cbnz(temp(), L);185__ mov(r0, 0);186__ bind(L);187__ str(r0, Address(to(), _stack_offset));188_stack_offset += wordSize;189_num_int_args++;190break;191}192}193}194195void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {196// generate code to handle arguments197iterate(fingerprint);198199// return result handler200__ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));201__ b(lr);202203__ flush();204}205206207// Implementation of SignatureHandlerLibrary208209void SignatureHandlerLibrary::pd_set_handler(address handler) {}210211212class SlowSignatureHandler : public NativeSignatureIterator {213private:214address _from;215intptr_t* _to;216intptr_t* _int_args;217intptr_t* _fp_args;218intptr_t* _fp_identifiers;219220int _num_int_reg_args;221int _next_double_dex;222223virtual void pass_int()224{225jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));226_from -= Interpreter::stackElementSize;227228if (_num_int_reg_args < Argument::n_int_register_parameters_c-1) {229*_int_args++ = from_obj;230_num_int_reg_args++;231} else {232*_to++ = from_obj;233}234}235236virtual void pass_long()237{238intptr_t high_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));239intptr_t low_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));240_from -= 2*Interpreter::stackElementSize;241242if (_num_int_reg_args < Argument::n_int_register_parameters_c-2) {243// Passing longs. As c_rarg0 is always reserved for jni_env we could only244// possibly stash a long in r3:r2 due to alignment so we can only enter here245// with either zero or one parameters.246// Align to two247_int_args += 1 - _num_int_reg_args; // 0 or 1248*_int_args++ = low_obj;249*_int_args++ = high_obj;250_num_int_reg_args = 3;251} else {252_to = (intptr_t*)(((intptr_t)_to + 7) & ~7); // Align to eight bytes253*_to++ = low_obj;254*_to++ = high_obj;255_num_int_reg_args = 3;256}257}258259virtual void pass_object()260{261intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));262_from -= Interpreter::stackElementSize;263264if (_num_int_reg_args < Argument::n_int_register_parameters_c-1) {265*_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;266_num_int_reg_args++;267} else {268*_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;269}270}271#ifdef HARD_FLOAT_CC272virtual void pass_float()273{274jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));275_from -= Interpreter::stackElementSize;276277if ((*_fp_identifiers) & 0xffff) {278unsigned index = __builtin_ctz(*_fp_identifiers);279_fp_args[index] = from_obj;280*_fp_identifiers ^= 1 << index;281_next_double_dex += (~index) & 1;282} else {283*_to++ = from_obj;284}285}286287virtual void pass_double()288{289intptr_t high_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));290intptr_t low_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));291_from -= 2*Interpreter::stackElementSize;292293if (_next_double_dex < Argument::n_float_register_parameters_c) {294//We can allocate to a register.295int index = _next_double_dex++;296*_fp_identifiers &= ~((3 << index*2) | (1 << index+16));297_fp_args[index*2] = low_obj;298_fp_args[index*2 + 1] = high_obj;299} else {300*_fp_identifiers &= ~0xffff; // make future floats allocate on stack too301_to = (intptr_t*)(((intptr_t)_to + 7) & ~7); // Align to eight bytes302*_to++ = low_obj;303*_to++ = high_obj;304}305}306#else307virtual void pass_float() { pass_int(); }308virtual void pass_double() { pass_long(); }309#endif // HARD_FLOAT_CC310311public:312SlowSignatureHandler(methodHandle method, address from, intptr_t* to)313: NativeSignatureIterator(method)314{315_from = from;316_to = to;317// See layout in interpreter_aarch32.cpp318_int_args = to - (method->is_static() ? 19 : 20);319_fp_args = to - 16; //each slot is for a double320_fp_identifiers = to - 21;321*_fp_identifiers = (1 <<(Argument::n_float_register_parameters_c * 3)) - 1;322323_num_int_reg_args = (method->is_static() ? 1 : 0);324_next_double_dex = 0;325}326};327328329IRT_ENTRY(address,330InterpreterRuntime::slow_signature_handler(JavaThread* thread,331Method* method,332intptr_t* from,333intptr_t* to))334methodHandle m(thread, (Method*)method);335assert(m->is_native(), "sanity check");336337// handle arguments338SlowSignatureHandler ssh(m, (address)from, to);339ssh.iterate(UCONST64(-1));340341// return result handler342return Interpreter::result_handler(m->result_type());343IRT_END344345346