comparison src/share/vm/prims/methodHandles.cpp @ 2356:72dee110246f

6839872: remove implementation inheritance from JSR 292 APIs Summary: consolidate runtime support in java.dyn.MethodHandleNatives; include transitional compatibility logic Reviewed-by: twisti
author jrose
date Fri, 11 Mar 2011 22:33:47 -0800
parents 3582bf76420e
children 8033953d67ff
comparison
equal deleted inserted replaced
2355:799d8ccf63cf 2356:72dee110246f
2521 } 2521 }
2522 } 2522 }
2523 JVM_END 2523 JVM_END
2524 2524
2525 JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) { 2525 JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
2526 if (!AllowTransitionalJSR292)
2527 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
2526 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); 2528 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
2527 return JNIHandles::make_local(THREAD, ik->bootstrap_method()); 2529 return JNIHandles::make_local(THREAD, ik->bootstrap_method());
2528 } 2530 }
2529 JVM_END 2531 JVM_END
2530 2532
2531 JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) { 2533 JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
2532 // No special action required, yet. 2534 if (!AllowTransitionalJSR292)
2533 oop site_oop = JNIHandles::resolve(site_jh); 2535 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
2534 if (!java_dyn_CallSite::is_instance(site_oop))
2535 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite");
2536 java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
2537 } 2536 }
2538 JVM_END 2537 JVM_END
2539 2538
2540 2539
2541 /// JVM_RegisterMethodHandleMethods 2540 /// JVM_RegisterMethodHandleMethods
2542 2541
2543 #define ADR "J" 2542 #define ADR "J"
2544 2543
2545 #define LANG "Ljava/lang/" 2544 #define LANG "Ljava/lang/"
2546 #define JDYN "Ljava/dyn/" 2545 #define JLINV "Ljava/lang/invoke/" /* standard package */
2547 #define IDYN "Lsun/dyn/" 2546 #define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
2547 #define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */
2548 // FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
2548 2549
2549 #define OBJ LANG"Object;" 2550 #define OBJ LANG"Object;"
2550 #define CLS LANG"Class;" 2551 #define CLS LANG"Class;"
2551 #define STRG LANG"String;" 2552 #define STRG LANG"String;"
2552 #define CST JDYN"CallSite;" 2553 #define CST JDYN"CallSite;"
2553 #define MT JDYN"MethodType;" 2554 #define MT JDYN"MethodType;"
2554 #define MH JDYN"MethodHandle;" 2555 #define MH JDYN"MethodHandle;"
2555 #define MHI IDYN"MethodHandleImpl;"
2556 #define MEM IDYN"MemberName;" 2556 #define MEM IDYN"MemberName;"
2557 #define AMH IDYN"AdapterMethodHandle;" 2557 #define AMH IDYN"AdapterMethodHandle;"
2558 #define BMH IDYN"BoundMethodHandle;" 2558 #define BMH IDYN"BoundMethodHandle;"
2559 #define DMH IDYN"DirectMethodHandle;" 2559 #define DMH IDYN"DirectMethodHandle;"
2560 2560
2579 // int matchFlags, Class<?> caller, int skip, MemberName[] results); 2579 // int matchFlags, Class<?> caller, int skip, MemberName[] results);
2580 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHI_getMembers)} 2580 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHI_getMembers)}
2581 }; 2581 };
2582 2582
2583 // More entry points specifically for EnableInvokeDynamic. 2583 // More entry points specifically for EnableInvokeDynamic.
2584 // FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
2584 static JNINativeMethod methods2[] = { 2585 static JNINativeMethod methods2[] = {
2585 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)}, 2586 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)},
2586 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)}, 2587 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)},
2587 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)} 2588 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)}
2588 }; 2589 };
2589 2590
2591 static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
2592 for (int i = 0; i < num_methods; i++) {
2593 const char* sig = methods[i].signature;
2594 if (!strstr(sig, from_sig)) continue;
2595 size_t buflen = strlen(sig) + 100;
2596 char* buf = NEW_C_HEAP_ARRAY(char, buflen);
2597 char* bufp = buf;
2598 const char* sigp = sig;
2599 size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
2600 while (*sigp != '\0') {
2601 assert(bufp < buf + buflen - to_len - 1, "oob");
2602 if (strncmp(sigp, from_sig, from_len) != 0) {
2603 *bufp++ = *sigp++;
2604 } else {
2605 strcpy(bufp, to_sig);
2606 bufp += to_len;
2607 sigp += from_len;
2608 }
2609 }
2610 *bufp = '\0';
2611 methods[i].signature = buf; // replace with new signature
2612 if (TraceMethodHandles)
2613 tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
2614 }
2615 }
2590 2616
2591 // This one function is exported, used by NativeLookup. 2617 // This one function is exported, used by NativeLookup.
2592 2618
2593 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) { 2619 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
2594 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK"); 2620 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
2598 if (!EnableMethodHandles) { 2624 if (!EnableMethodHandles) {
2599 warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable."); 2625 warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable.");
2600 return; // bind nothing 2626 return; // bind nothing
2601 } 2627 }
2602 2628
2629 if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
2630 SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
2631 warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
2632 THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
2633 }
2634
2603 bool enable_MH = true; 2635 bool enable_MH = true;
2604 2636
2605 { 2637 // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
2638 bool registered_natives = false;
2639 bool try_plain = true, try_JDYN = true, try_IDYN = true;
2640 for (;;) {
2606 ThreadToNativeFromVM ttnfv(thread); 2641 ThreadToNativeFromVM ttnfv(thread);
2607 2642
2643 if (try_plain) { try_plain = false; }
2644 else if (try_JDYN) { try_JDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
2645 else if (try_IDYN) { try_IDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
2646 else { break; }
2608 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod)); 2647 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
2609 if (env->ExceptionOccurred()) { 2648 if (env->ExceptionOccurred()) {
2610 MethodHandles::set_enabled(false);
2611 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2612 enable_MH = false;
2613 env->ExceptionClear(); 2649 env->ExceptionClear();
2614 } 2650 // and try again...
2651 } else {
2652 registered_natives = true;
2653 break;
2654 }
2655 }
2656 if (!registered_natives) {
2657 MethodHandles::set_enabled(false);
2658 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2659 enable_MH = false;
2615 } 2660 }
2616 2661
2617 if (enable_MH) { 2662 if (enable_MH) {
2663 bool found_raise_exception = false;
2664 KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
2618 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); 2665 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
2619 if (MHI_klass.not_null()) { 2666 // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
2667 bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
2668 for (;;) {
2669 KlassHandle try_klass;
2670 if (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
2671 else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
2672 else { break; }
2673 if (try_klass.is_null()) continue;
2620 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK); 2674 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
2621 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); 2675 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
2622 methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) 2676 methodOop raiseException_method = instanceKlass::cast(try_klass->as_klassOop())
2623 ->find_method(raiseException_name, raiseException_sig); 2677 ->find_method(raiseException_name, raiseException_sig);
2624 if (raiseException_method != NULL && raiseException_method->is_static()) { 2678 if (raiseException_method != NULL && raiseException_method->is_static()) {
2625 MethodHandles::set_raise_exception_method(raiseException_method); 2679 MethodHandles::set_raise_exception_method(raiseException_method);
2626 } else { 2680 found_raise_exception = true;
2627 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2681 break;
2628 enable_MH = false; 2682 }
2629 } 2683 }
2630 } else { 2684 if (!found_raise_exception) {
2685 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2631 enable_MH = false; 2686 enable_MH = false;
2632 } 2687 }
2633 } 2688 }
2634 2689
2635 if (enable_MH) { 2690 if (enable_MH) {
2636 // We need to link the MethodHandleImpl klass before we generate 2691 if (AllowTransitionalJSR292) {
2637 // the method handle adapters as the _raise_exception adapter uses 2692 // We need to link the MethodHandleImpl klass before we generate
2638 // one of its methods (and its c2i-adapter). 2693 // the method handle adapters as the _raise_exception adapter uses
2639 KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass(); 2694 // one of its methods (and its c2i-adapter).
2640 instanceKlass* ik = instanceKlass::cast(k()); 2695 KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass();
2641 ik->link_class(CHECK); 2696 instanceKlass* ik = instanceKlass::cast(k());
2697 ik->link_class(CHECK);
2698 }
2642 2699
2643 MethodHandles::generate_adapters(); 2700 MethodHandles::generate_adapters();
2644 MethodHandles::set_enabled(true); 2701 MethodHandles::set_enabled(true);
2645 } 2702 }
2646 2703
2647 if (!EnableInvokeDynamic) { 2704 if (!EnableInvokeDynamic) {
2648 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable."); 2705 warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable.");
2649 return; // bind nothing 2706 return; // bind nothing
2650 } 2707 }
2651 2708
2652 { 2709 if (AllowTransitionalJSR292) {
2653 ThreadToNativeFromVM ttnfv(thread); 2710 ThreadToNativeFromVM ttnfv(thread);
2654 2711
2655 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod)); 2712 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
2656 if (env->ExceptionOccurred()) { 2713 if (env->ExceptionOccurred()) {
2657 MethodHandles::set_enabled(false); 2714 MethodHandles::set_enabled(false);
2658 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 2715 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2659 env->ExceptionClear(); 2716 env->ExceptionClear();
2660 } else {
2661 MethodHandles::set_enabled(true);
2662 } 2717 }
2663 } 2718 }
2664 } 2719 }
2665 JVM_END 2720 JVM_END