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