comparison src/share/vm/prims/methodHandles.cpp @ 2460:ed69575596ac

6981791: remove experimental code for JSR 292 Reviewed-by: twisti
author jrose
date Thu, 07 Apr 2011 17:02:30 -0700
parents 38fea01eb669
children 328926869b15
comparison
equal deleted inserted replaced
2459:55973726c600 2460:ed69575596ac
2486 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks 2486 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks
2487 return res; 2487 return res;
2488 } 2488 }
2489 JVM_END 2489 JVM_END
2490 2490
2491 JVM_ENTRY(void, MHN_registerBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh, jobject bsm_jh)) {
2492 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
2493 if (!AllowTransitionalJSR292) {
2494 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
2495 "registerBootstrapMethod is only supported in JSR 292 EDR");
2496 }
2497 ik->link_class(CHECK);
2498 if (!java_lang_invoke_MethodHandle::is_instance(JNIHandles::resolve(bsm_jh))) {
2499 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "method handle");
2500 }
2501 const char* err = NULL;
2502 if (ik->is_initialized() || ik->is_in_error_state()) {
2503 err = "too late: class is already initialized";
2504 } else {
2505 ObjectLocker ol(ik, THREAD); // note: this should be a recursive lock
2506 if (ik->is_not_initialized() ||
2507 (ik->is_being_initialized() && ik->is_reentrant_initialization(THREAD))) {
2508 if (ik->bootstrap_method() != NULL) {
2509 err = "class is already equipped with a bootstrap method";
2510 } else {
2511 ik->set_bootstrap_method(JNIHandles::resolve_non_null(bsm_jh));
2512 err = NULL;
2513 }
2514 } else {
2515 err = "class is already initialized";
2516 if (ik->is_being_initialized())
2517 err = "class is already being initialized in a different thread";
2518 }
2519 }
2520 if (err != NULL) {
2521 THROW_MSG(vmSymbols::java_lang_IllegalStateException(), err);
2522 }
2523 }
2524 JVM_END
2525
2526 JVM_ENTRY(jobject, MHN_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
2527 if (!AllowTransitionalJSR292)
2528 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
2529 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
2530 return JNIHandles::make_local(THREAD, ik->bootstrap_method());
2531 }
2532 JVM_END
2533
2534 JVM_ENTRY(void, MHN_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
2535 if (!AllowTransitionalJSR292)
2536 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
2537 }
2538 JVM_END
2539
2540 2491
2541 /// JVM_RegisterMethodHandleMethods 2492 /// JVM_RegisterMethodHandleMethods
2542 2493
2543 #define LANG "Ljava/lang/" 2494 #define LANG "Ljava/lang/"
2544 #define JLINV "Ljava/lang/invoke/" /* standard package */ 2495 #define JLINV "Ljava/lang/invoke/"
2545 #define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
2546 #define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */
2547 // FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
2548 2496
2549 #define OBJ LANG"Object;" 2497 #define OBJ LANG"Object;"
2550 #define CLS LANG"Class;" 2498 #define CLS LANG"Class;"
2551 #define STRG LANG"String;" 2499 #define STRG LANG"String;"
2552 #define CST JDYN"CallSite;" 2500 #define MT JLINV"MethodType;"
2553 #define MT JDYN"MethodType;" 2501 #define MH JLINV"MethodHandle;"
2554 #define MH JDYN"MethodHandle;" 2502 #define MEM JLINV"MemberName;"
2555 #define MEM IDYN"MemberName;" 2503 #define AMH JLINV"AdapterMethodHandle;"
2556 #define AMH IDYN"AdapterMethodHandle;" 2504 #define BMH JLINV"BoundMethodHandle;"
2557 #define BMH IDYN"BoundMethodHandle;" 2505 #define DMH JLINV"DirectMethodHandle;"
2558 #define DMH IDYN"DirectMethodHandle;"
2559 2506
2560 #define CC (char*) /*cast a literal from (const char*)*/ 2507 #define CC (char*) /*cast a literal from (const char*)*/
2561 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) 2508 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
2562 2509
2563 // These are the native methods on sun.invoke.MethodHandleNatives. 2510 // These are the native methods on sun.invoke.MethodHandleNatives.
2577 // static native int getMembers(Class<?> defc, String matchName, String matchSig, 2524 // static native int getMembers(Class<?> defc, String matchName, String matchSig,
2578 // int matchFlags, Class<?> caller, int skip, MemberName[] results); 2525 // int matchFlags, Class<?> caller, int skip, MemberName[] results);
2579 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)} 2526 {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
2580 }; 2527 };
2581 2528
2582 // FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
2583 static JNINativeMethod methods2[] = {
2584 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHN_registerBootstrap)},
2585 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHN_getBootstrap)},
2586 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHN_setCallSiteTarget)}
2587 };
2588
2589 static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
2590 for (int i = 0; i < num_methods; i++) {
2591 const char* sig = methods[i].signature;
2592 if (!strstr(sig, from_sig)) continue;
2593 size_t buflen = strlen(sig) + 100;
2594 char* buf = NEW_C_HEAP_ARRAY(char, buflen);
2595 char* bufp = buf;
2596 const char* sigp = sig;
2597 size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
2598 while (*sigp != '\0') {
2599 assert(bufp < buf + buflen - to_len - 1, "oob");
2600 if (strncmp(sigp, from_sig, from_len) != 0) {
2601 *bufp++ = *sigp++;
2602 } else {
2603 strcpy(bufp, to_sig);
2604 bufp += to_len;
2605 sigp += from_len;
2606 }
2607 }
2608 *bufp = '\0';
2609 methods[i].signature = buf; // replace with new signature
2610 if (TraceMethodHandles)
2611 tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
2612 }
2613 }
2614
2615 // This one function is exported, used by NativeLookup. 2529 // This one function is exported, used by NativeLookup.
2616 2530
2617 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) { 2531 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
2618 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK"); 2532 assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
2619 2533
2620 if (!EnableInvokeDynamic) { 2534 if (!EnableInvokeDynamic) {
2621 warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable."); 2535 warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
2622 return; // bind nothing 2536 return; // bind nothing
2623 } 2537 }
2624 2538
2625 if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
2626 SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
2627 warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
2628 THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
2629 }
2630
2631 bool enable_MH = true; 2539 bool enable_MH = true;
2632 2540
2633 // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed. 2541 {
2634 bool registered_natives = false;
2635 bool try_plain = true, try_JDYN = true, try_IDYN = true;
2636 for (;;) {
2637 ThreadToNativeFromVM ttnfv(thread); 2542 ThreadToNativeFromVM ttnfv(thread);
2638 2543
2639 if (try_plain) { try_plain = false; }
2640 else if (try_JDYN) { try_JDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
2641 else if (try_IDYN) { try_IDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
2642 else { break; }
2643 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod)); 2544 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
2644 if (env->ExceptionOccurred()) { 2545 if (env->ExceptionOccurred()) {
2546 MethodHandles::set_enabled(false);
2547 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2548 enable_MH = false;
2645 env->ExceptionClear(); 2549 env->ExceptionClear();
2646 // and try again... 2550 }
2647 } else {
2648 registered_natives = true;
2649 break;
2650 }
2651 }
2652 if (!registered_natives) {
2653 MethodHandles::set_enabled(false);
2654 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2655 enable_MH = false;
2656 } 2551 }
2657 2552
2658 if (enable_MH) { 2553 if (enable_MH) {
2659 bool found_raise_exception = false;
2660 KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass(); 2554 KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
2661 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); 2555 if (MHN_klass.not_null()) {
2662 // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
2663 bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
2664 for (;;) {
2665 KlassHandle try_klass;
2666 if (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
2667 else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
2668 else { break; }
2669 if (try_klass.is_null()) continue;
2670 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK); 2556 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
2671 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); 2557 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
2672 methodOop raiseException_method = instanceKlass::cast(try_klass->as_klassOop()) 2558 methodOop raiseException_method = instanceKlass::cast(MHN_klass->as_klassOop())
2673 ->find_method(raiseException_name, raiseException_sig); 2559 ->find_method(raiseException_name, raiseException_sig);
2674 if (raiseException_method != NULL && raiseException_method->is_static()) { 2560 if (raiseException_method != NULL && raiseException_method->is_static()) {
2675 MethodHandles::set_raise_exception_method(raiseException_method); 2561 MethodHandles::set_raise_exception_method(raiseException_method);
2676 found_raise_exception = true; 2562 } else {
2677 break; 2563 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2678 } 2564 enable_MH = false;
2679 } 2565 }
2680 if (!found_raise_exception) { 2566 } else {
2681 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
2682 enable_MH = false; 2567 enable_MH = false;
2683 } 2568 }
2684 } 2569 }
2685 2570
2686 if (enable_MH) { 2571 if (enable_MH) {
2687 if (AllowTransitionalJSR292) {
2688 // We need to link the MethodHandleImpl klass before we generate
2689 // the method handle adapters as the _raise_exception adapter uses
2690 // one of its methods (and its c2i-adapter).
2691 klassOop k = SystemDictionary::MethodHandleImpl_klass();
2692 if (k != NULL) {
2693 instanceKlass* ik = instanceKlass::cast(k);
2694 ik->link_class(CHECK);
2695 }
2696 }
2697
2698 MethodHandles::generate_adapters(); 2572 MethodHandles::generate_adapters();
2699 MethodHandles::set_enabled(true); 2573 MethodHandles::set_enabled(true);
2700 } 2574 }
2701
2702 if (AllowTransitionalJSR292) {
2703 ThreadToNativeFromVM ttnfv(thread);
2704
2705 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
2706 if (env->ExceptionOccurred()) {
2707 // Don't do this, since it's too late:
2708 // MethodHandles::set_enabled(false)
2709 env->ExceptionClear();
2710 }
2711 }
2712 } 2575 }
2713 JVM_END 2576 JVM_END