comparison src/cpu/x86/vm/methodHandles_x86.cpp @ 1039:987e948ebbc8

6815692: method handle code needs some cleanup (post-6655638) Summary: correctly raise exceptions, support safe bitwise "raw" conversions, fix bugs revealed by VerifyMethodHandles, remove dead code, improve debugging support Reviewed-by: never, twisti
author jrose
date Sat, 17 Oct 2009 19:51:05 -0700
parents df6caf649ff7
children 85f13cdfbc1d
comparison
equal deleted inserted replaced
1038:71fdc5052e49 1039:987e948ebbc8
269 269
270 #ifndef PRODUCT 270 #ifndef PRODUCT
271 void trace_method_handle_stub(const char* adaptername, 271 void trace_method_handle_stub(const char* adaptername,
272 oopDesc* mh, 272 oopDesc* mh,
273 intptr_t* entry_sp, 273 intptr_t* entry_sp,
274 intptr_t* saved_sp) { 274 intptr_t* saved_sp,
275 intptr_t* saved_bp) {
275 // called as a leaf from native code: do not block the JVM! 276 // called as a leaf from native code: do not block the JVM!
276 printf("MH %s "PTR_FORMAT" "PTR_FORMAT" "INTX_FORMAT"\n", adaptername, (void*)mh, entry_sp, entry_sp - saved_sp); 277 intptr_t* last_sp = (intptr_t*) saved_bp[frame::interpreter_frame_last_sp_offset];
278 intptr_t* base_sp = (intptr_t*) saved_bp[frame::interpreter_frame_monitor_block_top_offset];
279 printf("MH %s mh="INTPTR_FORMAT" sp=("INTPTR_FORMAT"+"INTX_FORMAT") stack_size="INTX_FORMAT" bp="INTPTR_FORMAT"\n",
280 adaptername, (intptr_t)mh, (intptr_t)entry_sp, (intptr_t)(saved_sp - entry_sp), (intptr_t)(base_sp - last_sp), (intptr_t)saved_bp);
281 if (last_sp != saved_sp)
282 printf("*** last_sp="INTPTR_FORMAT"\n", (intptr_t)last_sp);
277 } 283 }
278 #endif //PRODUCT 284 #endif //PRODUCT
279 285
280 // Generate an "entry" field for a method handle. 286 // Generate an "entry" field for a method handle.
281 // This determines how the method handle will respond to calls. 287 // This determines how the method handle will respond to calls.
291 Register rcx_recv = rcx; 297 Register rcx_recv = rcx;
292 Register rax_argslot = rax; 298 Register rax_argslot = rax;
293 Register rbx_temp = rbx; 299 Register rbx_temp = rbx;
294 Register rdx_temp = rdx; 300 Register rdx_temp = rdx;
295 301
302 // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
303 // and gen_c2i_adapter (from compiled calls):
304 Register saved_last_sp = LP64_ONLY(r13) NOT_LP64(rsi);
305
296 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets"); 306 guarantee(java_dyn_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
297 307
298 // some handy addresses 308 // some handy addresses
299 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() ); 309 Address rbx_method_fie( rbx, methodOopDesc::from_interpreted_offset() );
300 310
312 int tag_offset = -1; 322 int tag_offset = -1;
313 if (TaggedStackInterpreter) { 323 if (TaggedStackInterpreter) {
314 tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes(); 324 tag_offset = Interpreter::tag_offset_in_bytes() - Interpreter::value_offset_in_bytes();
315 assert(tag_offset = wordSize, "stack grows as expected"); 325 assert(tag_offset = wordSize, "stack grows as expected");
316 } 326 }
327
328 const int java_mirror_offset = klassOopDesc::klass_part_offset_in_bytes() + Klass::java_mirror_offset_in_bytes();
317 329
318 if (have_entry(ek)) { 330 if (have_entry(ek)) {
319 __ nop(); // empty stubs make SG sick 331 __ nop(); // empty stubs make SG sick
320 return; 332 return;
321 } 333 }
326 #ifndef PRODUCT 338 #ifndef PRODUCT
327 if (TraceMethodHandles) { 339 if (TraceMethodHandles) {
328 __ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi); 340 __ push(rax); __ push(rbx); __ push(rcx); __ push(rdx); __ push(rsi); __ push(rdi);
329 __ lea(rax, Address(rsp, wordSize*6)); // entry_sp 341 __ lea(rax, Address(rsp, wordSize*6)); // entry_sp
330 // arguments: 342 // arguments:
343 __ push(rbp); // interpreter frame pointer
331 __ push(rsi); // saved_sp 344 __ push(rsi); // saved_sp
332 __ push(rax); // entry_sp 345 __ push(rax); // entry_sp
333 __ push(rcx); // mh 346 __ push(rcx); // mh
334 __ push(rcx); 347 __ push(rcx);
335 __ movptr(Address(rsp, 0), (intptr_t)entry_name(ek)); 348 __ movptr(Address(rsp, 0), (intptr_t)entry_name(ek));
336 __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 4); 349 __ call_VM_leaf(CAST_FROM_FN_PTR(address, trace_method_handle_stub), 5);
337 __ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax); 350 __ pop(rdi); __ pop(rsi); __ pop(rdx); __ pop(rcx); __ pop(rbx); __ pop(rax);
338 } 351 }
339 #endif //PRODUCT 352 #endif //PRODUCT
340 353
341 switch ((int) ek) { 354 switch ((int) ek) {
342 case _check_mtype: 355 case _raise_exception:
343 { 356 {
344 // this stub is special, because it requires a live mtype argument 357 // Not a real MH entry, but rather shared code for raising an exception.
345 Register rax_mtype = rax; 358 // Extra local arguments are pushed on stack, as required type at TOS+8,
346 359 // failing object (or NULL) at TOS+4, failing bytecode type at TOS.
347 // emit WrongMethodType path first, to enable jccb back-branch 360 // Beyond those local arguments are the PC, of course.
348 Label wrong_method_type; 361 Register rdx_code = rdx_temp;
349 __ bind(wrong_method_type); 362 Register rcx_fail = rcx_recv;
350 __ movptr(rdx_temp, ExternalAddress((address) &_entries[_wrong_method_type])); 363 Register rax_want = rax_argslot;
351 __ jmp(Address(rdx_temp, MethodHandleEntry::from_interpreted_entry_offset_in_bytes())); 364 Register rdi_pc = rdi;
352 __ hlt(); 365 __ pop(rdx_code); // TOS+0
353 366 __ pop(rcx_fail); // TOS+4
354 interp_entry = __ pc(); 367 __ pop(rax_want); // TOS+8
355 __ check_method_handle_type(rax_mtype, rcx_recv, rdx_temp, wrong_method_type); 368 __ pop(rdi_pc); // caller PC
356 // now rax_mtype is dead; subsequent stubs will use it as a temp 369
357 370 __ mov(rsp, rsi); // cut the stack back to where the caller started
358 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 371
359 } 372 // Repush the arguments as if coming from the interpreter.
360 break; 373 if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_INT));
361 374 __ push(rdx_code);
362 case _wrong_method_type: 375 if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT));
363 { 376 __ push(rcx_fail);
364 // this stub is special, because it requires a live mtype argument 377 if (TaggedStackInterpreter) __ push(frame::tag_for_basic_type(T_OBJECT));
365 Register rax_mtype = rax; 378 __ push(rax_want);
366 379
367 interp_entry = __ pc(); 380 Register rbx_method = rbx_temp;
368 __ push(rax_mtype); // required mtype 381 Label no_method;
369 __ push(rcx_recv); // random mh (1st stacked argument) 382 // FIXME: fill in _raise_exception_method with a suitable sun.dyn method
383 __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
384 __ testptr(rbx_method, rbx_method);
385 __ jcc(Assembler::zero, no_method);
386 int jobject_oop_offset = 0;
387 __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset)); // dereference the jobject
388 __ testptr(rbx_method, rbx_method);
389 __ jcc(Assembler::zero, no_method);
390 __ verify_oop(rbx_method);
391 __ push(rdi_pc); // and restore caller PC
392 __ jmp(rbx_method_fie);
393
394 // If we get here, the Java runtime did not do its job of creating the exception.
395 // Do something that is at least causes a valid throw from the interpreter.
396 __ bind(no_method);
397 __ pop(rax_want);
398 if (TaggedStackInterpreter) __ pop(rcx_fail);
399 __ pop(rcx_fail);
400 __ push(rax_want);
401 __ push(rcx_fail);
370 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 402 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry()));
371 } 403 }
372 break; 404 break;
373 405
374 case _invokestatic_mh: 406 case _invokestatic_mh:
440 // get receiver klass 472 // get receiver klass
441 Register rax_klass = rax_argslot; 473 Register rax_klass = rax_argslot;
442 __ load_klass(rax_klass, rcx_recv); 474 __ load_klass(rax_klass, rcx_recv);
443 __ verify_oop(rax_klass); 475 __ verify_oop(rax_klass);
444 476
445 Register rcx_temp = rcx_recv; 477 Register rdi_temp = rdi;
446 Register rbx_method = rbx_index; 478 Register rbx_method = rbx_index;
447 479
448 // get interface klass 480 // get interface klass
449 Label no_such_interface; 481 Label no_such_interface;
450 __ verify_oop(rdx_intf); 482 __ verify_oop(rdx_intf);
451 __ lookup_interface_method(rax_klass, rdx_intf, 483 __ lookup_interface_method(rax_klass, rdx_intf,
452 // note: next two args must be the same: 484 // note: next two args must be the same:
453 rbx_index, rbx_method, 485 rbx_index, rbx_method,
454 rcx_temp, 486 rdi_temp,
455 no_such_interface); 487 no_such_interface);
456 488
457 __ verify_oop(rbx_method); 489 __ verify_oop(rbx_method);
458 __ jmp(rbx_method_fie); 490 __ jmp(rbx_method_fie);
459 __ hlt(); 491 __ hlt();
460 492
461 __ bind(no_such_interface); 493 __ bind(no_such_interface);
462 // Throw an exception. 494 // Throw an exception.
463 // For historical reasons, it will be IncompatibleClassChangeError. 495 // For historical reasons, it will be IncompatibleClassChangeError.
464 __ should_not_reach_here(); // %%% FIXME NYI 496 __ pushptr(Address(rdx_intf, java_mirror_offset)); // required interface
497 __ push(rcx_recv); // bad receiver
498 __ push((int)Bytecodes::_invokeinterface); // who is complaining?
499 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
465 } 500 }
466 break; 501 break;
467 502
468 case _bound_ref_mh: 503 case _bound_ref_mh:
469 case _bound_int_mh: 504 case _bound_int_mh:
522 } 557 }
523 } 558 }
524 break; 559 break;
525 560
526 case _adapter_retype_only: 561 case _adapter_retype_only:
562 case _adapter_retype_raw:
527 // immediately jump to the next MH layer: 563 // immediately jump to the next MH layer:
528 __ movptr(rcx_recv, rcx_mh_vmtarget); 564 __ movptr(rcx_recv, rcx_mh_vmtarget);
529 __ verify_oop(rcx_recv); 565 __ verify_oop(rcx_recv);
530 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 566 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
531 // This is OK when all parameter types widen. 567 // This is OK when all parameter types widen.
543 579
544 // What class are we casting to? 580 // What class are we casting to?
545 __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object! 581 __ movptr(rbx_klass, rcx_amh_argument); // this is a Class object!
546 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes())); 582 __ movptr(rbx_klass, Address(rbx_klass, java_lang_Class::klass_offset_in_bytes()));
547 583
548 // get the new MH:
549 __ movptr(rcx_recv, rcx_mh_vmtarget);
550 // (now we are done with the old MH)
551
552 Label done; 584 Label done;
553 __ movptr(rdx_temp, vmarg); 585 __ movptr(rdx_temp, vmarg);
554 __ testl(rdx_temp, rdx_temp); 586 __ testl(rdx_temp, rdx_temp);
555 __ jcc(Assembler::zero, done); // no cast if null 587 __ jcc(Assembler::zero, done); // no cast if null
556 __ load_klass(rdx_temp, rdx_temp); 588 __ load_klass(rdx_temp, rdx_temp);
557 589
558 // live at this point: 590 // live at this point:
559 // - rbx_klass: klass required by the target method 591 // - rbx_klass: klass required by the target method
560 // - rdx_temp: argument klass to test 592 // - rdx_temp: argument klass to test
561 // - rcx_recv: method handle to invoke (after cast succeeds) 593 // - rcx_recv: adapter method handle
562 __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done); 594 __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done);
563 595
564 // If we get here, the type check failed! 596 // If we get here, the type check failed!
565 // Call the wrong_method_type stub, passing the failing argument type in rax. 597 // Call the wrong_method_type stub, passing the failing argument type in rax.
566 Register rax_mtype = rax_argslot; 598 Register rax_mtype = rax_argslot;
567 __ push(rbx_klass); // missed klass (required type) 599 __ movl(rax_argslot, rcx_amh_vmargslot); // reload argslot field
568 __ push(rdx_temp); // bad actual type (1st stacked argument) 600 __ movptr(rdx_temp, vmarg);
569 __ jump(ExternalAddress(Interpreter::throw_WrongMethodType_entry())); 601
602 __ pushptr(rcx_amh_argument); // required class
603 __ push(rdx_temp); // bad object
604 __ push((int)Bytecodes::_checkcast); // who is complaining?
605 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
570 606
571 __ bind(done); 607 __ bind(done);
608 // get the new MH:
609 __ movptr(rcx_recv, rcx_mh_vmtarget);
572 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 610 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
573 } 611 }
574 break; 612 break;
575 613
576 case _adapter_prim_to_prim: 614 case _adapter_prim_to_prim:
1105 __ movptr(rcx_recv, rcx_mh_vmtarget); 1143 __ movptr(rcx_recv, rcx_mh_vmtarget);
1106 __ jump_to_method_handle_entry(rcx_recv, rdx_temp); 1144 __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
1107 1145
1108 __ bind(bad_array_klass); 1146 __ bind(bad_array_klass);
1109 UNPUSH_RSI_RDI; 1147 UNPUSH_RSI_RDI;
1110 __ stop("bad array klass NYI"); 1148 __ pushptr(Address(rdx_array_klass, java_mirror_offset)); // required type
1149 __ pushptr(vmarg); // bad array
1150 __ push((int)Bytecodes::_aaload); // who is complaining?
1151 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
1111 1152
1112 __ bind(bad_array_length); 1153 __ bind(bad_array_length);
1113 UNPUSH_RSI_RDI; 1154 UNPUSH_RSI_RDI;
1114 __ stop("bad array length NYI"); 1155 __ push(rcx_recv); // AMH requiring a certain length
1156 __ pushptr(vmarg); // bad array
1157 __ push((int)Bytecodes::_arraylength); // who is complaining?
1158 __ jump(ExternalAddress(from_interpreted_entry(_raise_exception)));
1115 1159
1116 #undef UNPUSH_RSI_RDI 1160 #undef UNPUSH_RSI_RDI
1117 } 1161 }
1118 break; 1162 break;
1119 1163