1 /* |
1 /* |
2 * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
30 #include "prims/jvm_misc.hpp" |
30 #include "prims/jvm_misc.hpp" |
31 #include "runtime/safepoint.hpp" |
31 #include "runtime/safepoint.hpp" |
32 |
32 |
33 #define __ masm-> |
33 #define __ masm-> |
34 |
34 |
35 #define BUFFER_SIZE 96 |
35 #define BUFFER_SIZE 120 |
36 |
36 |
37 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { |
37 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) { |
38 const char* name = NULL; |
38 const char* name = NULL; |
39 address slow_case_addr = NULL; |
39 address slow_case_addr = NULL; |
40 switch (type) { |
40 switch (type) { |
97 ResourceMark rm; |
97 ResourceMark rm; |
98 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE); |
98 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE); |
99 CodeBuffer cbuf(blob); |
99 CodeBuffer cbuf(blob); |
100 MacroAssembler* masm = new MacroAssembler(&cbuf); |
100 MacroAssembler* masm = new MacroAssembler(&cbuf); |
101 fast_entry = __ pc(); |
101 fast_entry = __ pc(); |
|
102 Label slow_case; |
102 |
103 |
103 // Safepoint check |
104 // Safepoint check |
104 InlinedAddress safepoint_counter_addr(SafepointSynchronize::safepoint_counter_addr()); |
105 InlinedAddress safepoint_counter_addr(SafepointSynchronize::safepoint_counter_addr()); |
105 Label slow_case; |
|
106 __ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr); |
106 __ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr); |
107 |
107 |
108 __ push(RegisterSet(R0, R3)); // save incoming arguments for slow case |
108 __ push(RegisterSet(R0, R3)); // save incoming arguments for slow case |
109 |
109 |
110 __ ldr_s32(Rsafept_cnt, Address(Rsafepoint_counter_addr)); |
110 __ ldr_s32(Rsafept_cnt, Address(Rsafepoint_counter_addr)); |
111 __ tbnz(Rsafept_cnt, 0, slow_case); |
111 __ tbnz(Rsafept_cnt, 0, slow_case); |
112 |
112 |
113 __ bic(R1, R1, JNIHandles::weak_tag_mask); |
113 __ bic(R1, R1, JNIHandles::weak_tag_mask); |
114 |
114 |
115 // Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier |
115 if (JvmtiExport::can_post_field_access()) { |
116 __ andr(Rtmp1, Rsafept_cnt, (unsigned)1); |
116 // Using barrier to order wrt. JVMTI check and load of result. |
117 __ ldr(Robj, Address(R1, Rtmp1)); |
117 __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad), Rtmp1); |
|
118 |
|
119 // Check to see if a field access watch has been set before we |
|
120 // take the fast path. |
|
121 __ ldr_global_s32(Rtmp1, (address)JvmtiExport::get_field_access_count_addr()); |
|
122 __ cbnz(Rtmp1, slow_case); |
|
123 |
|
124 __ ldr(Robj, Address(R1)); |
|
125 } else { |
|
126 // Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier |
|
127 __ andr(Rtmp1, Rsafept_cnt, (unsigned)1); |
|
128 __ ldr(Robj, Address(R1, Rtmp1)); |
|
129 } |
118 |
130 |
119 Address field_addr; |
131 Address field_addr; |
120 if (type != T_BOOLEAN |
132 if (type != T_BOOLEAN |
121 && type != T_INT |
133 && type != T_INT |
122 #ifndef __ABI_HARD__ |
134 #ifndef __ABI_HARD__ |
168 #endif // __ABI_HARD__ |
180 #endif // __ABI_HARD__ |
169 default: |
181 default: |
170 ShouldNotReachHere(); |
182 ShouldNotReachHere(); |
171 } |
183 } |
172 |
184 |
173 // Address dependency restricts memory access ordering. It's cheaper than explicit LoadLoad barrier |
185 __ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr); |
174 #ifdef __ABI_HARD__ |
186 #ifdef __ABI_HARD__ |
175 if (type == T_FLOAT || type == T_DOUBLE) { |
187 if (type == T_FLOAT || type == T_DOUBLE) { |
176 __ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr); |
|
177 __ fmrrd(Rres, Rres_hi, D0); |
188 __ fmrrd(Rres, Rres_hi, D0); |
178 __ eor(Rtmp2, Rres, Rres); |
189 } |
179 __ ldr_s32(Rsafept_cnt2, Address(Rsafepoint_counter_addr, Rtmp2)); |
|
180 } else |
|
181 #endif // __ABI_HARD__ |
190 #endif // __ABI_HARD__ |
182 { |
191 |
183 __ ldr_literal(Rsafepoint_counter_addr, safepoint_counter_addr); |
192 // Order JVMTI check and load of result wrt. succeeding check |
184 __ eor(Rtmp2, Rres, Rres); |
193 // (LoadStore for volatile field). |
185 __ ldr_s32(Rsafept_cnt2, Address(Rsafepoint_counter_addr, Rtmp2)); |
194 __ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtmp2); |
186 } |
195 |
|
196 __ ldr_s32(Rsafept_cnt2, Address(Rsafepoint_counter_addr)); |
187 __ cmp(Rsafept_cnt2, Rsafept_cnt); |
197 __ cmp(Rsafept_cnt2, Rsafept_cnt); |
188 // discards saved R0 R1 R2 R3 |
198 // discards saved R0 R1 R2 R3 |
189 __ add(SP, SP, 4 * wordSize, eq); |
199 __ add(SP, SP, 4 * wordSize, eq); |
190 __ bx(LR, eq); |
200 __ bx(LR, eq); |
191 |
201 |