Fri, 29 Apr 2016 00:06:10 +0800
Added MIPS 64-bit port.
1 /*
2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2016, Loongson Technology. 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 */
26 #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"
33 #define __ masm->
35 #define BUFFER_SIZE 30*wordSize
37 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
38 // between loads, which is more efficient than lfence.
40 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
41 const char *name;
42 switch (type) {
43 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
44 case T_BYTE: name = "jni_fast_GetByteField"; break;
45 case T_CHAR: name = "jni_fast_GetCharField"; break;
46 case T_SHORT: name = "jni_fast_GetShortField"; break;
47 case T_INT: name = "jni_fast_GetIntField"; break;
48 case T_LONG: name = "jni_fast_GetLongField"; break;
49 default: ShouldNotReachHere();
50 }
51 ResourceMark rm;
52 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
53 CodeBuffer cbuf(blob);
54 MacroAssembler* masm = new MacroAssembler(&cbuf);
55 address fast_entry = __ pc();
57 Label slow;
59 // return pc RA
60 // jni env A0
61 // obj A1
62 // jfieldID A2
64 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
65 __ li48(AT, (long)counter_addr);
66 __ lw(T1, AT, 0);
68 /* 2012/4/28 Jin: the parameters(A0~A3) should not be modified, since
69 * they will be used in slow path. */
70 __ andi(AT, T1, 1);
71 __ bne(AT, R0, slow);
72 __ delayed()->nop();
74 __ ld(T0, A1, 0); // unbox, *obj
75 __ move(T2, A2);
76 __ shr(T2, 2); // offset
77 __ dadd(T0, T0, T2);
79 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
80 speculative_load_pclist[count] = __ pc();
81 switch (type) {
82 case T_BOOLEAN: __ lbu (V0, T0, 0); break;
83 case T_BYTE: __ lb (V0, T0, 0); break;
84 case T_CHAR: __ lhu (V0, T0, 0); break;
85 case T_SHORT: __ lh (V0, T0, 0); break;
86 case T_INT: __ lw (V0, T0, 0); break;
87 case T_LONG: __ ld (V0, T0, 0); break;
88 default: ShouldNotReachHere();
89 }
91 __ li48(AT, (long)counter_addr);
92 __ lw(AT, AT, 0);
93 __ bne(T1, AT, slow);
94 __ delayed()->nop();
96 __ jr(RA);
97 __ delayed()->nop();
99 slowcase_entry_pclist[count++] = __ pc();
100 __ bind (slow);
101 address slow_case_addr;
102 switch (type) {
103 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
104 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
105 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
106 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
107 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
108 case T_LONG: slow_case_addr = jni_GetLongField_addr();
109 }
110 __ jmp(slow_case_addr);
111 __ delayed()->nop();
113 __ flush ();
115 return fast_entry;
116 }
118 address JNI_FastGetField::generate_fast_get_boolean_field() {
119 return generate_fast_get_int_field0(T_BOOLEAN);
120 }
122 address JNI_FastGetField::generate_fast_get_byte_field() {
123 return generate_fast_get_int_field0(T_BYTE);
124 }
126 address JNI_FastGetField::generate_fast_get_char_field() {
127 return generate_fast_get_int_field0(T_CHAR);
128 }
130 address JNI_FastGetField::generate_fast_get_short_field() {
131 return generate_fast_get_int_field0(T_SHORT);
132 }
134 address JNI_FastGetField::generate_fast_get_int_field() {
135 return generate_fast_get_int_field0(T_INT);
136 }
138 address JNI_FastGetField::generate_fast_get_long_field() {
139 return generate_fast_get_int_field0(T_LONG);
140 /*
141 const char *name = "jni_fast_GetLongField";
142 ResourceMark rm;
143 BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
144 address fast_entry = b->instructions_begin();
145 // CodeBuffer* cbuf = new CodeBuffer(fast_entry, b->instructions_size());
146 CodeBuffer cbuf (fast_entry, b->instructions_size());
147 MacroAssembler* masm = new MacroAssembler(&cbuf);
149 Label slow;
151 // return pc RA
152 // jni env A0
153 // obj A1
154 // jfieldID A2
156 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
157 //__ move(AT, (int)counter_addr);
158 //__ lw(T1, AT, 0);
159 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
160 __ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
161 __ andi(AT, T1, 1);
162 __ bne(AT, R0, slow);
163 __ delayed()->nop();
165 __ ld (A1, A1, 0); // unbox, *obj
166 __ shr(A2, 2); // offset
167 __ dadd(A1, A1, A2);
169 assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
170 speculative_load_pclist[count++] = __ pc();
171 __ ld(V0, A1, 0); // eax
172 speculative_load_pclist[count] = __ pc();
173 __ ld(V1, A1, 8);
175 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
176 __ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
177 __ bne(T1, AT, slow);
178 __ delayed()->nop();
180 __ jr(RA);
181 __ delayed()->nop();
183 slowcase_entry_pclist[count-1] = __ pc();
184 slowcase_entry_pclist[count++] = __ pc();
185 __ bind (slow);
186 address slow_case_addr = jni_GetLongField_addr();;
187 // tail call
188 __ jmp(slow_case_addr);
189 __ delayed()->nop();
191 __ flush();
192 return fast_entry;
193 */
194 }
196 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
197 const char *name;
198 switch (type) {
199 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
200 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
201 default: ShouldNotReachHere();
202 }
203 ResourceMark rm;
204 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
205 CodeBuffer cbuf(blob);
206 MacroAssembler* masm = new MacroAssembler(&cbuf);
207 address fast_entry = __ pc();
209 Label slow;
211 // return pc RA
212 // jni env A0
213 // obj A1
214 // jfieldID A2
216 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
217 //__ move(AT, (int)counter_addr);
218 //__ lw(T1, AT, 0);
219 #ifdef _LP64
220 __ li48(AT, (intptr_t)counter_addr);
221 __ lw(T1, AT, 0);
222 #else
223 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
224 __ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
225 #endif
226 __ andi(AT, T1, 1);
227 __ bne(AT, R0, slow);
228 __ delayed()->nop();
230 #ifdef _LP64
231 __ ld(A1, A1, 0); // unbox, *obj
232 #else
233 __ lw(A1, A1, 0); // unbox, *obj
234 #endif
235 __ shr(A2, 2); // offset
236 __ add(A1, A1, A2);
238 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
239 speculative_load_pclist[count] = __ pc();
240 switch (type) {
241 case T_FLOAT:
242 __ lwc1(F0, A1, 0);
243 break;
244 case T_DOUBLE:
245 #ifdef _LP64
246 __ ldc1(F0, A1, 0);
247 #else
248 __ lwc1(F0, A1, 0);
249 __ lwc1(F1, A1, 4);
250 #endif
251 break;
252 default: ShouldNotReachHere();
253 }
255 #ifdef _LP64
256 __ li48(AT, (intptr_t)counter_addr);
257 __ lw(AT, AT, 0);
258 #else
259 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
260 __ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
261 #endif
262 __ bne(T1, AT, slow);
263 __ delayed()->nop();
265 __ jr(RA);
266 __ delayed()->nop();
269 slowcase_entry_pclist[count++] = __ pc();
270 __ bind (slow);
271 address slow_case_addr;
272 switch (type) {
273 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
274 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
275 default: ShouldNotReachHere();
276 }
277 __ jmp(slow_case_addr);
278 __ delayed()->nop();
280 __ flush ();
281 return fast_entry;
282 }
284 address JNI_FastGetField::generate_fast_get_float_field() {
285 return generate_fast_get_float_field0(T_FLOAT);
286 }
288 address JNI_FastGetField::generate_fast_get_double_field() {
289 return generate_fast_get_float_field0(T_DOUBLE);
290 }