10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 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 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "memory/resourceArea.hpp"
28 #include "prims/jniFastGetField.hpp"
29 #include "prims/jvm_misc.hpp"
30 #include "runtime/safepoint.hpp"
31
32 #define __ masm->
33
34 #define BUFFER_SIZE 30*wordSize
35
36 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
37 // between loads, which is more efficient than lfence.
38
39 // Common register usage:
40 // rax/xmm0: result
41 // c_rarg0: jni env
42 // c_rarg1: obj
43 // c_rarg2: jfield id
44
45 static const Register robj = r9;
46 static const Register rcounter = r10;
47 static const Register roffset = r11;
48 static const Register rcounter_addr = r11;
49
65 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
66 CodeBuffer cbuf(blob);
67 MacroAssembler* masm = new MacroAssembler(&cbuf);
68 address fast_entry = __ pc();
69
70 Label slow;
71
72 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
73 __ mov32 (rcounter, counter);
74 __ mov (robj, c_rarg1);
75 __ testb (rcounter, 1);
76 __ jcc (Assembler::notZero, slow);
77 if (os::is_MP()) {
78 __ xorptr(robj, rcounter);
79 __ xorptr(robj, rcounter); // obj, since
80 // robj ^ rcounter ^ rcounter == robj
81 // robj is data dependent on rcounter.
82 }
83 __ movptr(robj, Address(robj, 0)); // *obj
84 __ mov (roffset, c_rarg2);
85 __ shrptr(roffset, 2); // offset
86
87 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
88 speculative_load_pclist[count] = __ pc();
89 switch (type) {
90 case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break;
91 case T_BYTE: __ movsbl (rax, Address(robj, roffset, Address::times_1)); break;
92 case T_CHAR: __ movzwl (rax, Address(robj, roffset, Address::times_1)); break;
93 case T_SHORT: __ movswl (rax, Address(robj, roffset, Address::times_1)); break;
94 case T_INT: __ movl (rax, Address(robj, roffset, Address::times_1)); break;
95 case T_LONG: __ movq (rax, Address(robj, roffset, Address::times_1)); break;
96 default: ShouldNotReachHere();
97 }
98
99 if (os::is_MP()) {
100 __ lea(rcounter_addr, counter);
101 // ca is data dependent on rax.
102 __ xorptr(rcounter_addr, rax);
103 __ xorptr(rcounter_addr, rax);
104 __ cmpl (rcounter, Address(rcounter_addr, 0));
105 } else {
163 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
164 CodeBuffer cbuf(blob);
165 MacroAssembler* masm = new MacroAssembler(&cbuf);
166 address fast_entry = __ pc();
167
168 Label slow;
169
170 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
171 __ mov32 (rcounter, counter);
172 __ mov (robj, c_rarg1);
173 __ testb (rcounter, 1);
174 __ jcc (Assembler::notZero, slow);
175 if (os::is_MP()) {
176 __ xorptr(robj, rcounter);
177 __ xorptr(robj, rcounter); // obj, since
178 // robj ^ rcounter ^ rcounter == robj
179 // robj is data dependent on rcounter.
180 }
181 __ movptr(robj, Address(robj, 0)); // *obj
182 __ mov (roffset, c_rarg2);
183 __ shrptr(roffset, 2); // offset
184
185 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
186 speculative_load_pclist[count] = __ pc();
187 switch (type) {
188 case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break;
189 case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
190 default: ShouldNotReachHere();
191 }
192
193 if (os::is_MP()) {
194 __ lea(rcounter_addr, counter);
195 __ movdq (rax, xmm0);
196 // counter address is data dependent on xmm0.
197 __ xorptr(rcounter_addr, rax);
198 __ xorptr(rcounter_addr, rax);
199 __ cmpl (rcounter, Address(rcounter_addr, 0));
200 } else {
201 __ cmp32 (rcounter, counter);
202 }
203 __ jcc (Assembler::notEqual, slow);
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 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 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "asm/macroAssembler.hpp"
27 #include "memory/resourceArea.hpp"
28 #include "prims/jniFastGetField.hpp"
29 #include "prims/jvm_misc.hpp"
30 #include "runtime/jfieldIDWorkaround.hpp"
31 #include "runtime/safepoint.hpp"
32
33 #define __ masm->
34
35 #define BUFFER_SIZE 30*wordSize
36
37 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
38 // between loads, which is more efficient than lfence.
39
40 // Common register usage:
41 // rax/xmm0: result
42 // c_rarg0: jni env
43 // c_rarg1: obj
44 // c_rarg2: jfield id
45
46 static const Register robj = r9;
47 static const Register rcounter = r10;
48 static const Register roffset = r11;
49 static const Register rcounter_addr = r11;
50
66 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
67 CodeBuffer cbuf(blob);
68 MacroAssembler* masm = new MacroAssembler(&cbuf);
69 address fast_entry = __ pc();
70
71 Label slow;
72
73 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
74 __ mov32 (rcounter, counter);
75 __ mov (robj, c_rarg1);
76 __ testb (rcounter, 1);
77 __ jcc (Assembler::notZero, slow);
78 if (os::is_MP()) {
79 __ xorptr(robj, rcounter);
80 __ xorptr(robj, rcounter); // obj, since
81 // robj ^ rcounter ^ rcounter == robj
82 // robj is data dependent on rcounter.
83 }
84 __ movptr(robj, Address(robj, 0)); // *obj
85 __ mov (roffset, c_rarg2);
86 __ shrptr(roffset, jfieldIDWorkaround::offset_shift); // offset
87
88 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
89 speculative_load_pclist[count] = __ pc();
90 switch (type) {
91 case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break;
92 case T_BYTE: __ movsbl (rax, Address(robj, roffset, Address::times_1)); break;
93 case T_CHAR: __ movzwl (rax, Address(robj, roffset, Address::times_1)); break;
94 case T_SHORT: __ movswl (rax, Address(robj, roffset, Address::times_1)); break;
95 case T_INT: __ movl (rax, Address(robj, roffset, Address::times_1)); break;
96 case T_LONG: __ movq (rax, Address(robj, roffset, Address::times_1)); break;
97 default: ShouldNotReachHere();
98 }
99
100 if (os::is_MP()) {
101 __ lea(rcounter_addr, counter);
102 // ca is data dependent on rax.
103 __ xorptr(rcounter_addr, rax);
104 __ xorptr(rcounter_addr, rax);
105 __ cmpl (rcounter, Address(rcounter_addr, 0));
106 } else {
164 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
165 CodeBuffer cbuf(blob);
166 MacroAssembler* masm = new MacroAssembler(&cbuf);
167 address fast_entry = __ pc();
168
169 Label slow;
170
171 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
172 __ mov32 (rcounter, counter);
173 __ mov (robj, c_rarg1);
174 __ testb (rcounter, 1);
175 __ jcc (Assembler::notZero, slow);
176 if (os::is_MP()) {
177 __ xorptr(robj, rcounter);
178 __ xorptr(robj, rcounter); // obj, since
179 // robj ^ rcounter ^ rcounter == robj
180 // robj is data dependent on rcounter.
181 }
182 __ movptr(robj, Address(robj, 0)); // *obj
183 __ mov (roffset, c_rarg2);
184 __ shrptr(roffset, jfieldIDWorkaround::offset_shift); // offset
185
186 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
187 speculative_load_pclist[count] = __ pc();
188 switch (type) {
189 case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break;
190 case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
191 default: ShouldNotReachHere();
192 }
193
194 if (os::is_MP()) {
195 __ lea(rcounter_addr, counter);
196 __ movdq (rax, xmm0);
197 // counter address is data dependent on xmm0.
198 __ xorptr(rcounter_addr, rax);
199 __ xorptr(rcounter_addr, rax);
200 __ cmpl (rcounter, Address(rcounter_addr, 0));
201 } else {
202 __ cmp32 (rcounter, counter);
203 }
204 __ jcc (Assembler::notEqual, slow);
|