comparison src/share/vm/c1/c1_Runtime1.cpp @ 2321:1b4e6a5d98e0

7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc Reviewed-by: never, bdelsart
author twisti
date Mon, 28 Feb 2011 06:07:12 -0800
parents e4fee0bdaa85
children c7f3d0b4570f
comparison
equal deleted inserted replaced
2320:41d4973cf100 2321:1b4e6a5d98e0
424 // control the area where we can allow a safepoint. After we exit the safepoint area we can 424 // control the area where we can allow a safepoint. After we exit the safepoint area we can
425 // check to see if the handler we are going to return is now in a nmethod that has 425 // check to see if the handler we are going to return is now in a nmethod that has
426 // been deoptimized. If that is the case we return the deopt blob 426 // been deoptimized. If that is the case we return the deopt blob
427 // unpack_with_exception entry instead. This makes life for the exception blob easier 427 // unpack_with_exception entry instead. This makes life for the exception blob easier
428 // because making that same check and diverting is painful from assembly language. 428 // because making that same check and diverting is painful from assembly language.
429 //
430
431
432 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm)) 429 JRT_ENTRY_NO_ASYNC(static address, exception_handler_for_pc_helper(JavaThread* thread, oopDesc* ex, address pc, nmethod*& nm))
430 // Reset method handle flag.
431 thread->set_is_method_handle_return(false);
433 432
434 Handle exception(thread, ex); 433 Handle exception(thread, ex);
435 nm = CodeCache::find_nmethod(pc); 434 nm = CodeCache::find_nmethod(pc);
436 assert(nm != NULL, "this is not an nmethod"); 435 assert(nm != NULL, "this is not an nmethod");
437 // Adjust the pc as needed/ 436 // Adjust the pc as needed/
478 assert(caller_is_deopted(), "Must be deoptimized"); 477 assert(caller_is_deopted(), "Must be deoptimized");
479 478
480 return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); 479 return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
481 } 480 }
482 481
483 // ExceptionCache is used only for exceptions at call and not for implicit exceptions 482 // ExceptionCache is used only for exceptions at call sites and not for implicit exceptions
484 if (guard_pages_enabled) { 483 if (guard_pages_enabled) {
485 address fast_continuation = nm->handler_for_exception_and_pc(exception, pc); 484 address fast_continuation = nm->handler_for_exception_and_pc(exception, pc);
486 if (fast_continuation != NULL) { 485 if (fast_continuation != NULL) {
487 if (fast_continuation == ExceptionCache::unwind_handler()) fast_continuation = NULL; 486 // Set flag if return address is a method handle call site.
487 thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
488 return fast_continuation; 488 return fast_continuation;
489 } 489 }
490 } 490 }
491 491
492 // If the stack guard pages are enabled, check whether there is a handler in 492 // If the stack guard pages are enabled, check whether there is a handler in
520 // If an exception was thrown during exception dispatch, the exception oop may have changed 520 // If an exception was thrown during exception dispatch, the exception oop may have changed
521 thread->set_exception_oop(exception()); 521 thread->set_exception_oop(exception());
522 thread->set_exception_pc(pc); 522 thread->set_exception_pc(pc);
523 523
524 // the exception cache is used only by non-implicit exceptions 524 // the exception cache is used only by non-implicit exceptions
525 if (continuation == NULL) { 525 if (continuation != NULL) {
526 nm->add_handler_for_exception_and_pc(exception, pc, ExceptionCache::unwind_handler());
527 } else {
528 nm->add_handler_for_exception_and_pc(exception, pc, continuation); 526 nm->add_handler_for_exception_and_pc(exception, pc, continuation);
529 } 527 }
530 } 528 }
531 529
532 thread->set_vm_result(exception()); 530 thread->set_vm_result(exception());
531 // Set flag if return address is a method handle call site.
532 thread->set_is_method_handle_return(nm->is_method_handle_return(pc));
533 533
534 if (TraceExceptions) { 534 if (TraceExceptions) {
535 ttyLocker ttyl; 535 ttyLocker ttyl;
536 ResourceMark rm; 536 ResourceMark rm;
537 tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT, 537 tty->print_cr("Thread " PTR_FORMAT " continuing at PC " PTR_FORMAT " for exception thrown at PC " PTR_FORMAT,
540 540
541 return continuation; 541 return continuation;
542 JRT_END 542 JRT_END
543 543
544 // Enter this method from compiled code only if there is a Java exception handler 544 // Enter this method from compiled code only if there is a Java exception handler
545 // in the method handling the exception 545 // in the method handling the exception.
546 // We are entering here from exception stub. We don't do a normal VM transition here. 546 // We are entering here from exception stub. We don't do a normal VM transition here.
547 // We do it in a helper. This is so we can check to see if the nmethod we have just 547 // We do it in a helper. This is so we can check to see if the nmethod we have just
548 // searched for an exception handler has been deoptimized in the meantime. 548 // searched for an exception handler has been deoptimized in the meantime.
549 address Runtime1::exception_handler_for_pc(JavaThread* thread) { 549 address Runtime1::exception_handler_for_pc(JavaThread* thread) {
550 oop exception = thread->exception_oop(); 550 oop exception = thread->exception_oop();
551 address pc = thread->exception_pc(); 551 address pc = thread->exception_pc();
552 // Still in Java mode 552 // Still in Java mode
553 debug_only(ResetNoHandleMark rnhm); 553 DEBUG_ONLY(ResetNoHandleMark rnhm);
554 nmethod* nm = NULL; 554 nmethod* nm = NULL;
555 address continuation = NULL; 555 address continuation = NULL;
556 { 556 {
557 // Enter VM mode by calling the helper 557 // Enter VM mode by calling the helper
558
559 ResetNoHandleMark rnhm; 558 ResetNoHandleMark rnhm;
560 continuation = exception_handler_for_pc_helper(thread, exception, pc, nm); 559 continuation = exception_handler_for_pc_helper(thread, exception, pc, nm);
561 } 560 }
562 // Back in JAVA, use no oops DON'T safepoint 561 // Back in JAVA, use no oops DON'T safepoint
563 562
564 // Now check to see if the nmethod we were called from is now deoptimized. 563 // Now check to see if the nmethod we were called from is now deoptimized.
565 // If so we must return to the deopt blob and deoptimize the nmethod 564 // If so we must return to the deopt blob and deoptimize the nmethod
566
567 if (nm != NULL && caller_is_deopted()) { 565 if (nm != NULL && caller_is_deopted()) {
568 continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls(); 566 continuation = SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
569 } 567 }
570 568
569 assert(continuation != NULL, "no handler found");
571 return continuation; 570 return continuation;
572 } 571 }
573 572
574 573
575 JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index)) 574 JRT_ENTRY(void, Runtime1::throw_range_check_exception(JavaThread* thread, int index))