1 /*
2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2012, 2019 SAP SE. 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 it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 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 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #include "precompiled.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "gc/shared/barrierSet.hpp"
29 #include "gc/shared/barrierSetAssembler.hpp"
30 #include "memory/resourceArea.hpp"
31 #include "prims/jniFastGetField.hpp"
32 #include "prims/jvm_misc.hpp"
33 #include "runtime/safepoint.hpp"
34
35 #define __ masm->
36
37 #define BUFFER_SIZE 48*BytesPerInstWord
38
39
40 // Common register usage:
41 // R3/F0: result
42 // R3_ARG1: jni env
43 // R4_ARG2: obj
44 // R5_ARG3: jfield id
45
generate_fast_get_int_field0(BasicType type)46 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
47 const char *name;
48 switch (type) {
49 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
50 case T_BYTE: name = "jni_fast_GetByteField"; break;
51 case T_CHAR: name = "jni_fast_GetCharField"; break;
52 case T_SHORT: name = "jni_fast_GetShortField"; break;
53 case T_INT: name = "jni_fast_GetIntField"; break;
54 case T_LONG: name = "jni_fast_GetLongField"; break;
55 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
56 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
57 default: ShouldNotReachHere();
58 name = NULL; // unreachable
59 }
60 ResourceMark rm;
61 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
62 CodeBuffer cbuf(blob);
63 MacroAssembler* masm = new MacroAssembler(&cbuf);
64 address fast_entry = __ function_entry();
65
66 Label slow;
67
68 const Register Rcounter_addr = R6_ARG4,
69 Rcounter = R7_ARG5,
70 Robj = R8_ARG6,
71 Rtmp = R9_ARG7;
72 const int counter_offs = __ load_const_optimized(Rcounter_addr,
73 SafepointSynchronize::safepoint_counter_addr(),
74 R0, true);
75
76 __ ld(Rcounter, counter_offs, Rcounter_addr);
77 __ andi_(R0, Rcounter, 1);
78 __ bne(CCR0, slow);
79
80 if (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 }
87
88 if (JvmtiExport::can_post_field_access()) {
89 // Check to see if a field access watch has been set before we
90 // take the fast path.
91 int fac_offs = __ load_const_optimized(Rtmp, JvmtiExport::get_field_access_count_addr(),
92 R0, true);
93 __ lwa(Rtmp, fac_offs, Rtmp);
94 __ cmpwi(CCR0, Rtmp, 0);
95 __ bne(CCR0, slow);
96 }
97
98 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
99 bs->try_resolve_jobject_in_native(masm, Robj, R3_ARG1, R4_ARG2, Rtmp, slow);
100
101 __ srwi(Rtmp, R5_ARG3, 2); // offset
102
103 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
104 speculative_load_pclist[count] = __ pc(); // Used by the segfault handler
105 bool is_fp = false;
106 switch (type) {
107 case T_BOOLEAN: __ lbzx(Rtmp, Rtmp, Robj); break;
108 case T_BYTE: __ lbzx(Rtmp, Rtmp, Robj); __ extsb(Rtmp, Rtmp); break;
109 case T_CHAR: __ lhzx(Rtmp, Rtmp, Robj); break;
110 case T_SHORT: __ lhax(Rtmp, Rtmp, Robj); break;
111 case T_INT: __ lwax(Rtmp, Rtmp, Robj); break;
112 case T_LONG: __ ldx( Rtmp, Rtmp, Robj); break;
113 case T_FLOAT: __ lfsx(F1_RET, Rtmp, Robj); is_fp = true; break;
114 case T_DOUBLE: __ lfdx(F1_RET, Rtmp, Robj); is_fp = true; break;
115 default: ShouldNotReachHere();
116 }
117
118 // Order preceding load(s) wrt. succeeding check (LoadStore for volatile field).
119 if (is_fp) {
120 Label next;
121 __ fcmpu(CCR0, F1_RET, F1_RET);
122 __ bne(CCR0, next);
123 __ bind(next);
124 } else {
125 __ twi_0(Rtmp);
126 }
127 __ isync();
128
129 __ ld(R0, counter_offs, Rcounter_addr);
130 __ cmpd(CCR0, R0, Rcounter);
131 __ bne(CCR0, slow);
132
133 if (!is_fp) {
134 __ mr(R3_RET, Rtmp);
135 }
136 __ blr();
137
138 slowcase_entry_pclist[count++] = __ pc();
139 __ bind(slow);
140 address slow_case_addr;
141 switch (type) {
142 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
143 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
144 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
145 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
146 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
147 case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;
148 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
149 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
150 default: ShouldNotReachHere();
151 slow_case_addr = NULL; // unreachable
152 }
153 __ load_const_optimized(R12, slow_case_addr, R0);
154 __ call_c_and_return_to_caller(R12); // tail call
155
156 __ flush();
157
158 return fast_entry;
159 }
160
generate_fast_get_boolean_field()161 address JNI_FastGetField::generate_fast_get_boolean_field() {
162 return generate_fast_get_int_field0(T_BOOLEAN);
163 }
164
generate_fast_get_byte_field()165 address JNI_FastGetField::generate_fast_get_byte_field() {
166 return generate_fast_get_int_field0(T_BYTE);
167 }
168
generate_fast_get_char_field()169 address JNI_FastGetField::generate_fast_get_char_field() {
170 return generate_fast_get_int_field0(T_CHAR);
171 }
172
generate_fast_get_short_field()173 address JNI_FastGetField::generate_fast_get_short_field() {
174 return generate_fast_get_int_field0(T_SHORT);
175 }
176
generate_fast_get_int_field()177 address JNI_FastGetField::generate_fast_get_int_field() {
178 return generate_fast_get_int_field0(T_INT);
179 }
180
generate_fast_get_long_field()181 address JNI_FastGetField::generate_fast_get_long_field() {
182 return generate_fast_get_int_field0(T_LONG);
183 }
184
generate_fast_get_float_field()185 address JNI_FastGetField::generate_fast_get_float_field() {
186 return generate_fast_get_int_field0(T_FLOAT);
187 }
188
generate_fast_get_double_field()189 address JNI_FastGetField::generate_fast_get_double_field() {
190 return generate_fast_get_int_field0(T_DOUBLE);
191 }
192