60 case T_BYTE: name = "jni_fast_GetByteField"; break;
61 case T_CHAR: name = "jni_fast_GetCharField"; break;
62 case T_SHORT: name = "jni_fast_GetShortField"; break;
63 case T_INT: name = "jni_fast_GetIntField"; break;
64 case T_LONG: name = "jni_fast_GetLongField"; break;
65 default: ShouldNotReachHere();
66 }
67 ResourceMark rm;
68 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
69 CodeBuffer cbuf(blob);
70 MacroAssembler* masm = new MacroAssembler(&cbuf);
71 address fast_entry = __ pc();
72
73 Label slow;
74
75 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
76 __ mov32 (rcounter, counter);
77 __ mov (robj, c_rarg1);
78 __ testb (rcounter, 1);
79 __ jcc (Assembler::notZero, slow);
80 if (os::is_MP()) {
81 __ xorptr(robj, rcounter);
82 __ xorptr(robj, rcounter); // obj, since
83 // robj ^ rcounter ^ rcounter == robj
84 // robj is data dependent on rcounter.
85 }
86
87 __ mov (roffset, c_rarg2);
88 __ shrptr(roffset, 2); // offset
89
90 // Both robj and rtmp are clobbered by try_resolve_jobject_in_native.
91 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
92 bs->try_resolve_jobject_in_native(masm, /* jni_env */ c_rarg0, robj, rtmp, slow);
93 DEBUG_ONLY(__ movl(rtmp, 0xDEADC0DE);)
94
95 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
96 speculative_load_pclist[count] = __ pc();
97 switch (type) {
98 case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break;
99 case T_BYTE: __ movsbl (rax, Address(robj, roffset, Address::times_1)); break;
100 case T_CHAR: __ movzwl (rax, Address(robj, roffset, Address::times_1)); break;
101 case T_SHORT: __ movswl (rax, Address(robj, roffset, Address::times_1)); break;
102 case T_INT: __ movl (rax, Address(robj, roffset, Address::times_1)); break;
103 case T_LONG: __ movq (rax, Address(robj, roffset, Address::times_1)); break;
104 default: ShouldNotReachHere();
105 }
106
107 if (os::is_MP()) {
108 __ lea(rcounter_addr, counter);
109 // ca is data dependent on rax.
110 __ xorptr(rcounter_addr, rax);
111 __ xorptr(rcounter_addr, rax);
112 __ cmpl (rcounter, Address(rcounter_addr, 0));
113 } else {
114 __ cmp32 (rcounter, counter);
115 }
116 __ jcc (Assembler::notEqual, slow);
117
118 __ ret (0);
119
120 slowcase_entry_pclist[count++] = __ pc();
121 __ bind (slow);
122 address slow_case_addr = NULL;
123 switch (type) {
124 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
125 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
126 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
127 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
128 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
129 case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;
130 default: break;
131 }
132 // tail call
133 __ jump (ExternalAddress(slow_case_addr));
134
135 __ flush ();
164 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
165 const char *name = NULL;
166 switch (type) {
167 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
168 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
169 default: ShouldNotReachHere();
170 }
171 ResourceMark rm;
172 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
173 CodeBuffer cbuf(blob);
174 MacroAssembler* masm = new MacroAssembler(&cbuf);
175 address fast_entry = __ pc();
176
177 Label slow;
178
179 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
180 __ mov32 (rcounter, counter);
181 __ mov (robj, c_rarg1);
182 __ testb (rcounter, 1);
183 __ jcc (Assembler::notZero, slow);
184 if (os::is_MP()) {
185 __ xorptr(robj, rcounter);
186 __ xorptr(robj, rcounter); // obj, since
187 // robj ^ rcounter ^ rcounter == robj
188 // robj is data dependent on rcounter.
189 }
190
191 // Both robj and rtmp are clobbered by try_resolve_jobject_in_native.
192 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
193 bs->try_resolve_jobject_in_native(masm, /* jni_env */ c_rarg0, robj, rtmp, slow);
194 DEBUG_ONLY(__ movl(rtmp, 0xDEADC0DE);)
195
196 __ mov (roffset, c_rarg2);
197 __ shrptr(roffset, 2); // offset
198
199 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
200 speculative_load_pclist[count] = __ pc();
201 switch (type) {
202 case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break;
203 case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
204 default: ShouldNotReachHere();
205 }
206
207 if (os::is_MP()) {
208 __ lea(rcounter_addr, counter);
209 __ movdq (rax, xmm0);
210 // counter address is data dependent on xmm0.
211 __ xorptr(rcounter_addr, rax);
212 __ xorptr(rcounter_addr, rax);
213 __ cmpl (rcounter, Address(rcounter_addr, 0));
214 } else {
215 __ cmp32 (rcounter, counter);
216 }
217 __ jcc (Assembler::notEqual, slow);
218
219 __ ret (0);
220
221 slowcase_entry_pclist[count++] = __ pc();
222 __ bind (slow);
223 address slow_case_addr = NULL;
224 switch (type) {
225 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
226 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
227 default: break;
228 }
229 // tail call
230 __ jump (ExternalAddress(slow_case_addr));
231
232 __ flush ();
233
234 return fast_entry;
235 }
236
|
60 case T_BYTE: name = "jni_fast_GetByteField"; break;
61 case T_CHAR: name = "jni_fast_GetCharField"; break;
62 case T_SHORT: name = "jni_fast_GetShortField"; break;
63 case T_INT: name = "jni_fast_GetIntField"; break;
64 case T_LONG: name = "jni_fast_GetLongField"; break;
65 default: ShouldNotReachHere();
66 }
67 ResourceMark rm;
68 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
69 CodeBuffer cbuf(blob);
70 MacroAssembler* masm = new MacroAssembler(&cbuf);
71 address fast_entry = __ pc();
72
73 Label slow;
74
75 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
76 __ mov32 (rcounter, counter);
77 __ mov (robj, c_rarg1);
78 __ testb (rcounter, 1);
79 __ jcc (Assembler::notZero, slow);
80
81 __ xorptr(robj, rcounter);
82 __ xorptr(robj, rcounter); // obj, since
83 // robj ^ rcounter ^ rcounter == robj
84 // robj is data dependent on rcounter.
85
86 __ mov (roffset, c_rarg2);
87 __ shrptr(roffset, 2); // offset
88
89 // Both robj and rtmp are clobbered by try_resolve_jobject_in_native.
90 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
91 bs->try_resolve_jobject_in_native(masm, /* jni_env */ c_rarg0, robj, rtmp, slow);
92 DEBUG_ONLY(__ movl(rtmp, 0xDEADC0DE);)
93
94 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
95 speculative_load_pclist[count] = __ pc();
96 switch (type) {
97 case T_BOOLEAN: __ movzbl (rax, Address(robj, roffset, Address::times_1)); break;
98 case T_BYTE: __ movsbl (rax, Address(robj, roffset, Address::times_1)); break;
99 case T_CHAR: __ movzwl (rax, Address(robj, roffset, Address::times_1)); break;
100 case T_SHORT: __ movswl (rax, Address(robj, roffset, Address::times_1)); break;
101 case T_INT: __ movl (rax, Address(robj, roffset, Address::times_1)); break;
102 case T_LONG: __ movq (rax, Address(robj, roffset, Address::times_1)); break;
103 default: ShouldNotReachHere();
104 }
105
106 // create data dependency on rax
107 __ lea(rcounter_addr, counter);
108 __ xorptr(rcounter_addr, rax);
109 __ xorptr(rcounter_addr, rax);
110 __ cmpl (rcounter, Address(rcounter_addr, 0));
111
112 __ jcc (Assembler::notEqual, slow);
113
114 __ ret (0);
115
116 slowcase_entry_pclist[count++] = __ pc();
117 __ bind (slow);
118 address slow_case_addr = NULL;
119 switch (type) {
120 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
121 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
122 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
123 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
124 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
125 case T_LONG: slow_case_addr = jni_GetLongField_addr(); break;
126 default: break;
127 }
128 // tail call
129 __ jump (ExternalAddress(slow_case_addr));
130
131 __ flush ();
160 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
161 const char *name = NULL;
162 switch (type) {
163 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
164 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
165 default: ShouldNotReachHere();
166 }
167 ResourceMark rm;
168 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
169 CodeBuffer cbuf(blob);
170 MacroAssembler* masm = new MacroAssembler(&cbuf);
171 address fast_entry = __ pc();
172
173 Label slow;
174
175 ExternalAddress counter(SafepointSynchronize::safepoint_counter_addr());
176 __ mov32 (rcounter, counter);
177 __ mov (robj, c_rarg1);
178 __ testb (rcounter, 1);
179 __ jcc (Assembler::notZero, slow);
180
181 __ xorptr(robj, rcounter);
182 __ xorptr(robj, rcounter); // obj, since
183 // robj ^ rcounter ^ rcounter == robj
184 // robj is data dependent on rcounter.
185
186 // Both robj and rtmp are clobbered by try_resolve_jobject_in_native.
187 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
188 bs->try_resolve_jobject_in_native(masm, /* jni_env */ c_rarg0, robj, rtmp, slow);
189 DEBUG_ONLY(__ movl(rtmp, 0xDEADC0DE);)
190
191 __ mov (roffset, c_rarg2);
192 __ shrptr(roffset, 2); // offset
193
194 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
195 speculative_load_pclist[count] = __ pc();
196 switch (type) {
197 case T_FLOAT: __ movflt (xmm0, Address(robj, roffset, Address::times_1)); break;
198 case T_DOUBLE: __ movdbl (xmm0, Address(robj, roffset, Address::times_1)); break;
199 default: ShouldNotReachHere();
200 }
201
202 __ lea(rcounter_addr, counter);
203 __ movdq (rax, xmm0);
204 // counter address is data dependent on xmm0.
205 __ xorptr(rcounter_addr, rax);
206 __ xorptr(rcounter_addr, rax);
207 __ cmpl (rcounter, Address(rcounter_addr, 0));
208 __ jcc (Assembler::notEqual, slow);
209
210 __ ret (0);
211
212 slowcase_entry_pclist[count++] = __ pc();
213 __ bind (slow);
214 address slow_case_addr = NULL;
215 switch (type) {
216 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
217 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
218 default: break;
219 }
220 // tail call
221 __ jump (ExternalAddress(slow_case_addr));
222
223 __ flush ();
224
225 return fast_entry;
226 }
227
|