Path: blob/master/src/hotspot/cpu/ppc/jniFastGetField_ppc.cpp
40930 views
/*1* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2012, 2019 SAP SE. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "asm/macroAssembler.inline.hpp"27#include "gc/shared/barrierSet.hpp"28#include "gc/shared/barrierSetAssembler.hpp"29#include "memory/resourceArea.hpp"30#include "prims/jniFastGetField.hpp"31#include "prims/jvm_misc.hpp"32#include "prims/jvmtiExport.hpp"33#include "runtime/safepoint.hpp"3435#define __ masm->3637#define BUFFER_SIZE 48*BytesPerInstWord383940// Common register usage:41// R3/F0: result42// R3_ARG1: jni env43// R4_ARG2: obj44// R5_ARG3: jfield id4546address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {47const char *name;48switch (type) {49case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;50case T_BYTE: name = "jni_fast_GetByteField"; break;51case T_CHAR: name = "jni_fast_GetCharField"; break;52case T_SHORT: name = "jni_fast_GetShortField"; break;53case T_INT: name = "jni_fast_GetIntField"; break;54case T_LONG: name = "jni_fast_GetLongField"; break;55case T_FLOAT: name = "jni_fast_GetFloatField"; break;56case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;57default: ShouldNotReachHere();58name = NULL; // unreachable59}60ResourceMark rm;61BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);62CodeBuffer cbuf(blob);63MacroAssembler* masm = new MacroAssembler(&cbuf);64address fast_entry = __ function_entry();6566Label slow;6768const Register Rcounter_addr = R6_ARG4,69Rcounter = R7_ARG5,70Robj = R8_ARG6,71Rtmp = R9_ARG7;72const int counter_offs = __ load_const_optimized(Rcounter_addr,73SafepointSynchronize::safepoint_counter_addr(),74R0, true);7576__ ld(Rcounter, counter_offs, Rcounter_addr);77__ andi_(R0, Rcounter, 1);78__ bne(CCR0, slow);7980if (support_IRIW_for_not_multiple_copy_atomic_cpu) {81// Field may be volatile.82__ fence();83} else {84// Using acquire to order wrt. JVMTI check and load of result.85__ isync(); // order wrt. to following load(s)86}8788if (JvmtiExport::can_post_field_access()) {89// Check to see if a field access watch has been set before we90// take the fast path.91int fac_offs = __ load_const_optimized(Rtmp, JvmtiExport::get_field_access_count_addr(),92R0, true);93__ lwa(Rtmp, fac_offs, Rtmp);94__ cmpwi(CCR0, Rtmp, 0);95__ bne(CCR0, slow);96}9798BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();99bs->try_resolve_jobject_in_native(masm, Robj, R3_ARG1, R4_ARG2, Rtmp, slow);100101__ srwi(Rtmp, R5_ARG3, 2); // offset102103assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");104speculative_load_pclist[count] = __ pc(); // Used by the segfault handler105bool is_fp = false;106switch (type) {107case T_BOOLEAN: __ lbzx(Rtmp, Rtmp, Robj); break;108case T_BYTE: __ lbzx(Rtmp, Rtmp, Robj); __ extsb(Rtmp, Rtmp); break;109case T_CHAR: __ lhzx(Rtmp, Rtmp, Robj); break;110case T_SHORT: __ lhax(Rtmp, Rtmp, Robj); break;111case T_INT: __ lwax(Rtmp, Rtmp, Robj); break;112case T_LONG: __ ldx( Rtmp, Rtmp, Robj); break;113case T_FLOAT: __ lfsx(F1_RET, Rtmp, Robj); is_fp = true; break;114case T_DOUBLE: __ lfdx(F1_RET, Rtmp, Robj); is_fp = true; break;115default: ShouldNotReachHere();116}117118// Order preceding load(s) wrt. succeeding check (LoadStore for volatile field).119if (is_fp) {120Label next;121__ fcmpu(CCR0, F1_RET, F1_RET);122__ bne(CCR0, next);123__ bind(next);124} else {125__ twi_0(Rtmp);126}127__ isync();128129__ ld(R0, counter_offs, Rcounter_addr);130__ cmpd(CCR0, R0, Rcounter);131__ bne(CCR0, slow);132133if (!is_fp) {134__ mr(R3_RET, Rtmp);135}136__ blr();137138slowcase_entry_pclist[count++] = __ pc();139__ bind(slow);140address slow_case_addr;141switch (type) {142case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;143case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;144case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;145case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;146case T_INT: slow_case_addr = jni_GetIntField_addr(); break;147case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;148case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;149case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;150default: ShouldNotReachHere();151slow_case_addr = NULL; // unreachable152}153__ load_const_optimized(R12, slow_case_addr, R0);154__ call_c_and_return_to_caller(R12); // tail call155156__ flush();157158return fast_entry;159}160161address JNI_FastGetField::generate_fast_get_boolean_field() {162return generate_fast_get_int_field0(T_BOOLEAN);163}164165address JNI_FastGetField::generate_fast_get_byte_field() {166return generate_fast_get_int_field0(T_BYTE);167}168169address JNI_FastGetField::generate_fast_get_char_field() {170return generate_fast_get_int_field0(T_CHAR);171}172173address JNI_FastGetField::generate_fast_get_short_field() {174return generate_fast_get_int_field0(T_SHORT);175}176177address JNI_FastGetField::generate_fast_get_int_field() {178return generate_fast_get_int_field0(T_INT);179}180181address JNI_FastGetField::generate_fast_get_long_field() {182return generate_fast_get_int_field0(T_LONG);183}184185address JNI_FastGetField::generate_fast_get_float_field() {186return generate_fast_get_int_field0(T_FLOAT);187}188189address JNI_FastGetField::generate_fast_get_double_field() {190return generate_fast_get_int_field0(T_DOUBLE);191}192193194