Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/aarch32/vm/jniFastGetField_aarch32.cpp
32285 views
/*1* Copyright (c) 2004, 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 "asm/macroAssembler.hpp"28#include "memory/resourceArea.hpp"29#include "prims/jniFastGetField.hpp"30#include "prims/jvm_misc.hpp"31#include "runtime/safepoint.hpp"3233#define __ masm->3435#define BUFFER_SIZE_ARMV7 31*wordSize36#define BUFFER_SIZE_ARMV6 51*wordSize3738// Instead of issuing a LoadLoad barrier we create an address39// dependency between loads; this might be more efficient.4041// Common register usage:42// r0/v0: result43// c_rarg0: jni env44// c_rarg1: obj45// c_rarg2: jfield id4647address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {48Register result = c_rarg0;49Register robj = c_rarg1;50Register rcounter = c_rarg3;51int args = RegSet::of(c_rarg0, c_rarg1, c_rarg2).bits();52int nargs = 3;5354const char *name;55switch (type) {56case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;57case T_BYTE: name = "jni_fast_GetByteField"; break;58case T_CHAR: name = "jni_fast_GetCharField"; break;59case T_SHORT: name = "jni_fast_GetShortField"; break;60case T_INT: name = "jni_fast_GetIntField"; break;61case T_LONG: name = "jni_fast_GetLongField"; break;62case T_FLOAT: name = "jni_fast_GetFloatField"; break;63case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;64default: ShouldNotReachHere();65}66ResourceMark rm;67BufferBlob* blob = BufferBlob::create(name,68VM_Version::features() & FT_ARMV7 ?69BUFFER_SIZE_ARMV7 :70BUFFER_SIZE_ARMV6 );71CodeBuffer cbuf(blob);72MacroAssembler* masm = new MacroAssembler(&cbuf);73address fast_entry = __ pc();7475Label slow;7677__ lea(rcounter, SafepointSynchronize::safepoint_counter_addr());78__ ldr(rcounter, rcounter);79__ tst(rcounter, 1);80__ b(slow, Assembler::NE);81__ stmdb(sp, args);82// doesn't change c_rarg1 but does force a dependency on rcounter before83// performing __ ldr(robj, ...84__ eor(robj, c_rarg1, rcounter);85__ eor(robj, robj, rcounter);8687__ clear_jweak_tag(robj);8889__ ldr(robj, Address(robj, 0)); // *obj9091assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");92speculative_load_pclist[count] = __ pc(); // Used by the segfault handler93// c_rarg2 * 2 is offset94// Only ldr & ldrb support shifted loads95switch (type) {96case T_FLOAT:97case T_INT: __ ldr (result, Address(robj, c_rarg2, lsr(2))); break;98case T_BOOLEAN: __ ldrb(result, Address(robj, c_rarg2, lsr(2))); break;99default: {100__ lsr(c_rarg2, c_rarg2, 2);101switch(type) {102case T_BYTE: __ ldrsb (result, Address(robj, c_rarg2)); break;103case T_CHAR: __ ldrh (result, Address(robj, c_rarg2)); break;104case T_SHORT: __ ldrsh (result, Address(robj, c_rarg2)); break;105case T_DOUBLE:106case T_LONG: __ ldrd (result, Address(robj, c_rarg2)); break;107default: ShouldNotReachHere();108}109}110}111__ lea(rscratch2, SafepointSynchronize::safepoint_counter_addr());112// rscratch2 is address dependent on result.113// TODO Do we need to force dependency on r1 too?114__ eor(rscratch2, rscratch2, result);115__ eor(rscratch2, rscratch2, result);116__ ldr(rscratch2, rscratch2);117__ cmp(rcounter, rscratch2);118119#ifdef HARD_FLOAT_CC120switch (type) {121case T_FLOAT: __ vmov_f32(d0, result, Assembler::EQ); break;122case T_DOUBLE: __ vmov_f64(d0, r0, r1, Assembler::EQ); break; // Change me if result changes123default: break;124}125#endif//HARD_FLOAT_CC126127__ add(sp, sp, nargs * wordSize, Assembler::EQ); // Pop args if we don't need them.128__ b(lr, Assembler::EQ);129130// Restore args for slowcase call into the vm131__ ldmia(sp, args);132133// Slowcase134slowcase_entry_pclist[count++] = __ pc();135__ bind(slow);136137address slow_case_addr = NULL;138switch (type) {139case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;140case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;141case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;142case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;143case T_INT: slow_case_addr = jni_GetIntField_addr(); break;144case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;145case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;146case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;147default: ShouldNotReachHere();148}149150{151__ enter();152__ lea(rscratch2, ExternalAddress(slow_case_addr));153__ bl(rscratch2);154__ maybe_isb();155__ leave();156__ b(lr);157}158__ flush ();159160return fast_entry;161}162163address JNI_FastGetField::generate_fast_get_boolean_field() {164return generate_fast_get_int_field0(T_BOOLEAN);165}166167address JNI_FastGetField::generate_fast_get_byte_field() {168return generate_fast_get_int_field0(T_BYTE);169}170171address JNI_FastGetField::generate_fast_get_char_field() {172return generate_fast_get_int_field0(T_CHAR);173}174175address JNI_FastGetField::generate_fast_get_short_field() {176return generate_fast_get_int_field0(T_SHORT);177}178179address JNI_FastGetField::generate_fast_get_int_field() {180return generate_fast_get_int_field0(T_INT);181}182183address JNI_FastGetField::generate_fast_get_long_field() {184return generate_fast_get_int_field0(T_LONG);185}186187address JNI_FastGetField::generate_fast_get_float_field() {188return generate_fast_get_int_field0(T_FLOAT);189}190191address JNI_FastGetField::generate_fast_get_double_field() {192return generate_fast_get_int_field0(T_DOUBLE);193}194195196197