Mercurial > hg > truffle
comparison src/cpu/x86/vm/templateInterpreter_x86_32.cpp @ 1059:389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
Summary: Fix several crashers, remove needless paths for boxed-style bootstrap method call, refactor & simplify APIs for rewriter constantPoolOop, remove sun.dyn.CallSiteImpl
Reviewed-by: kvn
author | jrose |
---|---|
date | Fri, 30 Oct 2009 16:22:59 -0700 |
parents | 987e948ebbc8 |
children | e66fd840cb6b |
comparison
equal
deleted
inserted
replaced
1058:73a726751507 | 1059:389049f3f393 |
---|---|
153 __ dispatch_next(state); | 153 __ dispatch_next(state); |
154 return entry; | 154 return entry; |
155 } | 155 } |
156 | 156 |
157 | 157 |
158 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) { | 158 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { |
159 TosState incoming_state = state; | 159 TosState incoming_state = state; |
160 if (EnableInvokeDynamic) { | |
161 if (unbox) { | |
162 incoming_state = atos; | |
163 } | |
164 } else { | |
165 assert(!unbox, "old behavior"); | |
166 } | |
167 | 160 |
168 Label interpreter_entry; | 161 Label interpreter_entry; |
169 address compiled_entry = __ pc(); | 162 address compiled_entry = __ pc(); |
170 | 163 |
171 #ifdef COMPILER2 | 164 #ifdef COMPILER2 |
214 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); | 207 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); |
215 | 208 |
216 __ restore_bcp(); | 209 __ restore_bcp(); |
217 __ restore_locals(); | 210 __ restore_locals(); |
218 | 211 |
219 Label L_fail; | |
220 | |
221 if (unbox && state != atos) { | |
222 // cast and unbox | |
223 BasicType type = as_BasicType(state); | |
224 if (type == T_BYTE) type = T_BOOLEAN; // FIXME | |
225 KlassHandle boxk = SystemDictionaryHandles::box_klass(type); | |
226 __ mov32(rbx, ExternalAddress((address) boxk.raw_value())); | |
227 __ testl(rax, rax); | |
228 Label L_got_value, L_get_value; | |
229 // convert nulls to zeroes (avoid NPEs here) | |
230 if (!(type == T_FLOAT || type == T_DOUBLE)) { | |
231 // if rax already contains zero bits, forge ahead | |
232 __ jcc(Assembler::zero, L_got_value); | |
233 } else { | |
234 __ jcc(Assembler::notZero, L_get_value); | |
235 __ fldz(); | |
236 __ jmp(L_got_value); | |
237 } | |
238 __ bind(L_get_value); | |
239 __ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); | |
240 __ jcc(Assembler::notEqual, L_fail); | |
241 int offset = java_lang_boxing_object::value_offset_in_bytes(type); | |
242 // Cf. TemplateTable::getfield_or_static | |
243 switch (type) { | |
244 case T_BYTE: // fall through: | |
245 case T_BOOLEAN: __ load_signed_byte(rax, Address(rax, offset)); break; | |
246 case T_CHAR: __ load_unsigned_short(rax, Address(rax, offset)); break; | |
247 case T_SHORT: __ load_signed_short(rax, Address(rax, offset)); break; | |
248 case T_INT: __ movl(rax, Address(rax, offset)); break; | |
249 case T_FLOAT: __ fld_s(Address(rax, offset)); break; | |
250 case T_DOUBLE: __ fld_d(Address(rax, offset)); break; | |
251 // Access to java.lang.Double.value does not need to be atomic: | |
252 case T_LONG: { __ movl(rdx, Address(rax, offset + 4)); | |
253 __ movl(rax, Address(rax, offset + 0)); } break; | |
254 default: ShouldNotReachHere(); | |
255 } | |
256 __ bind(L_got_value); | |
257 } | |
258 | |
259 Label L_got_cache, L_giant_index; | 212 Label L_got_cache, L_giant_index; |
260 if (EnableInvokeDynamic) { | 213 if (EnableInvokeDynamic) { |
261 __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic); | 214 __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic); |
262 __ jcc(Assembler::equal, L_giant_index); | 215 __ jcc(Assembler::equal, L_giant_index); |
263 } | 216 } |
264 __ get_cache_and_index_at_bcp(rbx, rcx, 1, false); | 217 __ get_cache_and_index_at_bcp(rbx, rcx, 1, false); |
265 __ bind(L_got_cache); | 218 __ bind(L_got_cache); |
266 if (unbox && state == atos) { | |
267 // insert a casting conversion, to keep verifier sane | |
268 Label L_ok, L_ok_pops; | |
269 __ testl(rax, rax); | |
270 __ jcc(Assembler::zero, L_ok); | |
271 __ push(rax); // save the object to check | |
272 __ push(rbx); // save CP cache reference | |
273 __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); | |
274 __ movl(rbx, Address(rbx, rcx, | |
275 Address::times_4, constantPoolCacheOopDesc::base_offset() + | |
276 ConstantPoolCacheEntry::f1_offset())); | |
277 __ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx))); | |
278 __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx))); | |
279 __ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx))); | |
280 __ check_klass_subtype(rdx, rax, rbx, L_ok_pops); | |
281 __ pop(rcx); // pop and discard CP cache | |
282 __ mov(rbx, rax); // target supertype into rbx for L_fail | |
283 __ pop(rax); // failed object into rax for L_fail | |
284 __ jmp(L_fail); | |
285 | |
286 __ bind(L_ok_pops); | |
287 // restore pushed temp regs: | |
288 __ pop(rbx); | |
289 __ pop(rax); | |
290 __ bind(L_ok); | |
291 } | |
292 __ movl(rbx, Address(rbx, rcx, | 219 __ movl(rbx, Address(rbx, rcx, |
293 Address::times_ptr, constantPoolCacheOopDesc::base_offset() + | 220 Address::times_ptr, constantPoolCacheOopDesc::base_offset() + |
294 ConstantPoolCacheEntry::flags_offset())); | 221 ConstantPoolCacheEntry::flags_offset())); |
295 __ andptr(rbx, 0xFF); | 222 __ andptr(rbx, 0xFF); |
296 __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); | 223 __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); |
299 // out of the main line of code... | 226 // out of the main line of code... |
300 if (EnableInvokeDynamic) { | 227 if (EnableInvokeDynamic) { |
301 __ bind(L_giant_index); | 228 __ bind(L_giant_index); |
302 __ get_cache_and_index_at_bcp(rbx, rcx, 1, true); | 229 __ get_cache_and_index_at_bcp(rbx, rcx, 1, true); |
303 __ jmp(L_got_cache); | 230 __ jmp(L_got_cache); |
304 | |
305 if (unbox) { | |
306 __ bind(L_fail); | |
307 __ push(rbx); // missed klass (required) | |
308 __ push(rax); // bad object (actual) | |
309 __ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry)); | |
310 __ call(rdx); | |
311 } | |
312 } | 231 } |
313 | 232 |
314 return entry; | 233 return entry; |
315 } | 234 } |
316 | 235 |