Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/sharedRuntime.cpp @ 2491:0654ee04b214
Merge with OpenJDK.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Fri, 22 Apr 2011 15:30:53 +0200 |
parents | 0cd39a385a72 758ba0bf7bcc |
children | e88293edf07c |
comparison
equal
deleted
inserted
replaced
2490:29246b1d2d3c | 2491:0654ee04b214 |
---|---|
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 |
1705 oopDesc* actual) { | 1692 oopDesc* actual) { |
1706 if (TraceMethodHandles) { | 1693 if (TraceMethodHandles) { |
1707 tty->print_cr("WrongMethodType thread="PTR_FORMAT" req="PTR_FORMAT" act="PTR_FORMAT"", | 1694 tty->print_cr("WrongMethodType thread="PTR_FORMAT" req="PTR_FORMAT" act="PTR_FORMAT"", |
1708 thread, required, actual); | 1695 thread, required, actual); |
1709 } | 1696 } |
1710 assert(EnableMethodHandles, ""); | 1697 assert(EnableInvokeDynamic, ""); |
1711 oop singleKlass = wrong_method_type_is_for_single_argument(thread, required); | 1698 oop singleKlass = wrong_method_type_is_for_single_argument(thread, required); |
1712 char* message = NULL; | 1699 char* message = NULL; |
1713 if (singleKlass != NULL) { | 1700 if (singleKlass != NULL) { |
1714 const char* objName = "argument or return value"; | 1701 const char* objName = "argument or return value"; |
1715 if (actual != NULL) { | 1702 if (actual != NULL) { |
1723 ? (klassOop)required | 1710 ? (klassOop)required |
1724 : java_lang_Class::as_klassOop(required)); | 1711 : java_lang_Class::as_klassOop(required)); |
1725 message = generate_class_cast_message(objName, targetKlass->external_name()); | 1712 message = generate_class_cast_message(objName, targetKlass->external_name()); |
1726 } else { | 1713 } else { |
1727 // %%% need to get the MethodType string, without messing around too much | 1714 // %%% need to get the MethodType string, without messing around too much |
1715 const char* desc = NULL; | |
1728 // Get a signature from the invoke instruction | 1716 // Get a signature from the invoke instruction |
1729 const char* mhName = "method handle"; | 1717 const char* mhName = "method handle"; |
1730 const char* targetType = "the required signature"; | 1718 const char* targetType = "the required signature"; |
1719 int targetArity = -1, mhArity = -1; | |
1731 vframeStream vfst(thread, true); | 1720 vframeStream vfst(thread, true); |
1732 if (!vfst.at_end()) { | 1721 if (!vfst.at_end()) { |
1733 Bytecode_invoke call(vfst.method(), vfst.bci()); | 1722 Bytecode_invoke call(vfst.method(), vfst.bci()); |
1734 methodHandle target; | 1723 methodHandle target; |
1735 { | 1724 { |
1739 } | 1728 } |
1740 if (target.not_null() | 1729 if (target.not_null() |
1741 && target->is_method_handle_invoke() | 1730 && target->is_method_handle_invoke() |
1742 && required == target->method_handle_type()) { | 1731 && required == target->method_handle_type()) { |
1743 targetType = target->signature()->as_C_string(); | 1732 targetType = target->signature()->as_C_string(); |
1733 targetArity = ArgumentCount(target->signature()).size(); | |
1744 } | 1734 } |
1745 } | 1735 } |
1746 klassOop kignore; int fignore; | 1736 klassOop kignore; int dmf_flags = 0; |
1747 methodOop actual_method = MethodHandles::decode_method(actual, | 1737 methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); |
1748 kignore, fignore); | 1738 if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver | |
1739 MethodHandles::_dmf_does_dispatch | | |
1740 MethodHandles::_dmf_from_interface)) != 0) | |
1741 actual_method = NULL; // MH does extra binds, drops, etc. | |
1742 bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0); | |
1749 if (actual_method != NULL) { | 1743 if (actual_method != NULL) { |
1750 if (methodOopDesc::is_method_handle_invoke_name(actual_method->name())) | 1744 mhName = actual_method->signature()->as_C_string(); |
1751 mhName = "$"; | 1745 mhArity = ArgumentCount(actual_method->signature()).size(); |
1746 if (!actual_method->is_static()) mhArity += 1; | |
1747 } else if (java_lang_invoke_MethodHandle::is_instance(actual)) { | |
1748 oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual); | |
1749 mhArity = java_lang_invoke_MethodType::ptype_count(mhType); | |
1750 stringStream st; | |
1751 java_lang_invoke_MethodType::print_signature(mhType, &st); | |
1752 mhName = st.as_string(); | |
1753 } | |
1754 if (targetArity != -1 && targetArity != mhArity) { | |
1755 if (has_receiver && targetArity == mhArity-1) | |
1756 desc = " cannot be called without a receiver argument as "; | |
1752 else | 1757 else |
1753 mhName = actual_method->signature()->as_C_string(); | 1758 desc = " cannot be called with a different arity as "; |
1754 if (mhName[0] == '$') | |
1755 mhName = actual_method->signature()->as_C_string(); | |
1756 } | 1759 } |
1757 message = generate_class_cast_message(mhName, targetType, | 1760 message = generate_class_cast_message(mhName, targetType, |
1761 desc != NULL ? desc : | |
1758 " cannot be called as "); | 1762 " cannot be called as "); |
1759 } | 1763 } |
1760 if (TraceMethodHandles) { | 1764 if (TraceMethodHandles) { |
1761 tty->print_cr("WrongMethodType => message=%s", message); | 1765 tty->print_cr("WrongMethodType => message=%s", message); |
1762 } | 1766 } |
2502 | 2506 |
2503 // Create a native wrapper for this native method. The wrapper converts the | 2507 // Create a native wrapper for this native method. The wrapper converts the |
2504 // java compiled calling convention to the native convention, handlizes | 2508 // java compiled calling convention to the native convention, handlizes |
2505 // arguments, and transitions to native. On return from the native we transition | 2509 // arguments, and transitions to native. On return from the native we transition |
2506 // back to java blocking if a safepoint is in progress. | 2510 // back to java blocking if a safepoint is in progress. |
2507 nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method) { | 2511 nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) { |
2508 ResourceMark rm; | 2512 ResourceMark rm; |
2509 nmethod* nm = NULL; | 2513 nmethod* nm = NULL; |
2510 | |
2511 if (PrintCompilation) { | |
2512 ttyLocker ttyl; | |
2513 tty->print("--- n%s ", (method->is_synchronized() ? "s" : " ")); | |
2514 method->print_short_name(tty); | |
2515 if (method->is_static()) { | |
2516 tty->print(" (static)"); | |
2517 } | |
2518 tty->cr(); | |
2519 } | |
2520 | 2514 |
2521 assert(method->has_native_function(), "must have something valid to call!"); | 2515 assert(method->has_native_function(), "must have something valid to call!"); |
2522 | 2516 |
2523 { | 2517 { |
2524 // perform the work while holding the lock, but perform any printing outside the lock | 2518 // perform the work while holding the lock, but perform any printing outside the lock |
2560 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); | 2554 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); |
2561 | 2555 |
2562 // Generate the compiled-to-native wrapper code | 2556 // Generate the compiled-to-native wrapper code |
2563 nm = SharedRuntime::generate_native_wrapper(&_masm, | 2557 nm = SharedRuntime::generate_native_wrapper(&_masm, |
2564 method, | 2558 method, |
2559 compile_id, | |
2565 total_args_passed, | 2560 total_args_passed, |
2566 comp_args_on_stack, | 2561 comp_args_on_stack, |
2567 sig_bt,regs, | 2562 sig_bt,regs, |
2568 ret_type); | 2563 ret_type); |
2569 } | 2564 } |
2571 | 2566 |
2572 // Must unlock before calling set_code | 2567 // Must unlock before calling set_code |
2573 | 2568 |
2574 // Install the generated code. | 2569 // Install the generated code. |
2575 if (nm != NULL) { | 2570 if (nm != NULL) { |
2571 if (PrintCompilation) { | |
2572 ttyLocker ttyl; | |
2573 CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : ""); | |
2574 } | |
2576 method->set_code(method, nm); | 2575 method->set_code(method, nm); |
2577 nm->post_compiled_method_load_event(); | 2576 nm->post_compiled_method_load_event(); |
2578 } else { | 2577 } else { |
2579 // CodeCache is full, disable compilation | 2578 // CodeCache is full, disable compilation |
2580 CompileBroker::handle_full_code_cache(); | 2579 CompileBroker::handle_full_code_cache(); |