Mercurial > hg > truffle
comparison src/share/vm/runtime/sharedRuntime.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 | b92c45f2bc75 |
children | 3d58a4983660 |
comparison
equal
deleted
inserted
replaced
2320:41d4973cf100 | 2321:1b4e6a5d98e0 |
---|---|
429 // exception_handler_for_return_address(...) returns the continuation address. | 429 // exception_handler_for_return_address(...) returns the continuation address. |
430 // The continuation address is the entry point of the exception handler of the | 430 // The continuation address is the entry point of the exception handler of the |
431 // previous frame depending on the return address. | 431 // previous frame depending on the return address. |
432 | 432 |
433 address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { | 433 address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { |
434 assert(frame::verify_return_pc(return_address), "must be a return pc"); | 434 assert(frame::verify_return_pc(return_address), err_msg("must be a return address: " INTPTR_FORMAT, return_address)); |
435 | 435 |
436 // Reset MethodHandle flag. | 436 // Reset method handle flag. |
437 thread->set_is_method_handle_return(false); | 437 thread->set_is_method_handle_return(false); |
438 | 438 |
439 // the fastest case first | 439 // The fastest case first |
440 CodeBlob* blob = CodeCache::find_blob(return_address); | 440 CodeBlob* blob = CodeCache::find_blob(return_address); |
441 if (blob != NULL && blob->is_nmethod()) { | 441 nmethod* nm = (blob != NULL) ? blob->as_nmethod_or_null() : NULL; |
442 nmethod* code = (nmethod*)blob; | 442 if (nm != NULL) { |
443 assert(code != NULL, "nmethod must be present"); | 443 // Set flag if return address is a method handle call site. |
444 // Check if the return address is a MethodHandle call site. | 444 thread->set_is_method_handle_return(nm->is_method_handle_return(return_address)); |
445 thread->set_is_method_handle_return(code->is_method_handle_return(return_address)); | |
446 // native nmethods don't have exception handlers | 445 // native nmethods don't have exception handlers |
447 assert(!code->is_native_method(), "no exception handler"); | 446 assert(!nm->is_native_method(), "no exception handler"); |
448 assert(code->header_begin() != code->exception_begin(), "no exception handler"); | 447 assert(nm->header_begin() != nm->exception_begin(), "no exception handler"); |
449 if (code->is_deopt_pc(return_address)) { | 448 if (nm->is_deopt_pc(return_address)) { |
450 return SharedRuntime::deopt_blob()->unpack_with_exception(); | 449 return SharedRuntime::deopt_blob()->unpack_with_exception(); |
451 } else { | 450 } else { |
452 return code->exception_begin(); | 451 return nm->exception_begin(); |
453 } | 452 } |
454 } | 453 } |
455 | 454 |
456 // Entry code | 455 // Entry code |
457 if (StubRoutines::returns_to_call_stub(return_address)) { | 456 if (StubRoutines::returns_to_call_stub(return_address)) { |
460 // Interpreted code | 459 // Interpreted code |
461 if (Interpreter::contains(return_address)) { | 460 if (Interpreter::contains(return_address)) { |
462 return Interpreter::rethrow_exception_entry(); | 461 return Interpreter::rethrow_exception_entry(); |
463 } | 462 } |
464 | 463 |
465 // Compiled code | 464 guarantee(blob == NULL || !blob->is_runtime_stub(), "caller should have skipped stub"); |
466 if (CodeCache::contains(return_address)) { | |
467 CodeBlob* blob = CodeCache::find_blob(return_address); | |
468 if (blob->is_nmethod()) { | |
469 nmethod* code = (nmethod*)blob; | |
470 assert(code != NULL, "nmethod must be present"); | |
471 // Check if the return address is a MethodHandle call site. | |
472 thread->set_is_method_handle_return(code->is_method_handle_return(return_address)); | |
473 assert(code->header_begin() != code->exception_begin(), "no exception handler"); | |
474 return code->exception_begin(); | |
475 } | |
476 if (blob->is_runtime_stub()) { | |
477 ShouldNotReachHere(); // callers are responsible for skipping runtime stub frames | |
478 } | |
479 } | |
480 guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!"); | 465 guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!"); |
466 | |
481 #ifndef PRODUCT | 467 #ifndef PRODUCT |
482 { ResourceMark rm; | 468 { ResourceMark rm; |
483 tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", return_address); | 469 tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", return_address); |
484 tty->print_cr("a) exception happened in (new?) code stubs/buffers that is not handled here"); | 470 tty->print_cr("a) exception happened in (new?) code stubs/buffers that is not handled here"); |
485 tty->print_cr("b) other problem"); | 471 tty->print_cr("b) other problem"); |
486 } | 472 } |
487 #endif // PRODUCT | 473 #endif // PRODUCT |
474 | |
488 ShouldNotReachHere(); | 475 ShouldNotReachHere(); |
489 return NULL; | 476 return NULL; |
490 } | 477 } |
491 | 478 |
492 | 479 |