1.1 --- a/src/share/vm/prims/methodHandles.cpp Fri Mar 11 21:19:15 2011 -0800 1.2 +++ b/src/share/vm/prims/methodHandles.cpp Fri Mar 11 22:33:47 2011 -0800 1.3 @@ -2523,17 +2523,16 @@ 1.4 JVM_END 1.5 1.6 JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) { 1.7 + if (!AllowTransitionalJSR292) 1.8 + THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only"); 1.9 instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD); 1.10 return JNIHandles::make_local(THREAD, ik->bootstrap_method()); 1.11 } 1.12 JVM_END 1.13 1.14 JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) { 1.15 - // No special action required, yet. 1.16 - oop site_oop = JNIHandles::resolve(site_jh); 1.17 - if (!java_dyn_CallSite::is_instance(site_oop)) 1.18 - THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite"); 1.19 - java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh)); 1.20 + if (!AllowTransitionalJSR292) 1.21 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only"); 1.22 } 1.23 JVM_END 1.24 1.25 @@ -2543,8 +2542,10 @@ 1.26 #define ADR "J" 1.27 1.28 #define LANG "Ljava/lang/" 1.29 -#define JDYN "Ljava/dyn/" 1.30 -#define IDYN "Lsun/dyn/" 1.31 +#define JLINV "Ljava/lang/invoke/" /* standard package */ 1.32 +#define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */ 1.33 +#define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */ 1.34 +// FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV. 1.35 1.36 #define OBJ LANG"Object;" 1.37 #define CLS LANG"Class;" 1.38 @@ -2552,7 +2553,6 @@ 1.39 #define CST JDYN"CallSite;" 1.40 #define MT JDYN"MethodType;" 1.41 #define MH JDYN"MethodHandle;" 1.42 -#define MHI IDYN"MethodHandleImpl;" 1.43 #define MEM IDYN"MemberName;" 1.44 #define AMH IDYN"AdapterMethodHandle;" 1.45 #define BMH IDYN"BoundMethodHandle;" 1.46 @@ -2581,12 +2581,38 @@ 1.47 }; 1.48 1.49 // More entry points specifically for EnableInvokeDynamic. 1.50 +// FIXME: Remove methods2 after AllowTransitionalJSR292 is removed. 1.51 static JNINativeMethod methods2[] = { 1.52 {CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)}, 1.53 {CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)}, 1.54 {CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)} 1.55 }; 1.56 1.57 +static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) { 1.58 + for (int i = 0; i < num_methods; i++) { 1.59 + const char* sig = methods[i].signature; 1.60 + if (!strstr(sig, from_sig)) continue; 1.61 + size_t buflen = strlen(sig) + 100; 1.62 + char* buf = NEW_C_HEAP_ARRAY(char, buflen); 1.63 + char* bufp = buf; 1.64 + const char* sigp = sig; 1.65 + size_t from_len = strlen(from_sig), to_len = strlen(to_sig); 1.66 + while (*sigp != '\0') { 1.67 + assert(bufp < buf + buflen - to_len - 1, "oob"); 1.68 + if (strncmp(sigp, from_sig, from_len) != 0) { 1.69 + *bufp++ = *sigp++; 1.70 + } else { 1.71 + strcpy(bufp, to_sig); 1.72 + bufp += to_len; 1.73 + sigp += from_len; 1.74 + } 1.75 + } 1.76 + *bufp = '\0'; 1.77 + methods[i].signature = buf; // replace with new signature 1.78 + if (TraceMethodHandles) 1.79 + tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf); 1.80 + } 1.81 +} 1.82 1.83 // This one function is exported, used by NativeLookup. 1.84 1.85 @@ -2600,45 +2626,76 @@ 1.86 return; // bind nothing 1.87 } 1.88 1.89 + if (SystemDictionary::MethodHandleNatives_klass() != NULL && 1.90 + SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) { 1.91 + warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292"); 1.92 + THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292"); 1.93 + } 1.94 + 1.95 bool enable_MH = true; 1.96 1.97 - { 1.98 + // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed. 1.99 + bool registered_natives = false; 1.100 + bool try_plain = true, try_JDYN = true, try_IDYN = true; 1.101 + for (;;) { 1.102 ThreadToNativeFromVM ttnfv(thread); 1.103 1.104 + if (try_plain) { try_plain = false; } 1.105 + else if (try_JDYN) { try_JDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); } 1.106 + else if (try_IDYN) { try_IDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); } 1.107 + else { break; } 1.108 int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod)); 1.109 if (env->ExceptionOccurred()) { 1.110 - MethodHandles::set_enabled(false); 1.111 - warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 1.112 - enable_MH = false; 1.113 env->ExceptionClear(); 1.114 + // and try again... 1.115 + } else { 1.116 + registered_natives = true; 1.117 + break; 1.118 } 1.119 } 1.120 + if (!registered_natives) { 1.121 + MethodHandles::set_enabled(false); 1.122 + warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 1.123 + enable_MH = false; 1.124 + } 1.125 1.126 if (enable_MH) { 1.127 + bool found_raise_exception = false; 1.128 + KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass(); 1.129 KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass(); 1.130 - if (MHI_klass.not_null()) { 1.131 + // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed. 1.132 + bool try_MHN = true, try_MHI = AllowTransitionalJSR292; 1.133 + for (;;) { 1.134 + KlassHandle try_klass; 1.135 + if (try_MHN) { try_MHN = false; try_klass = MHN_klass; } 1.136 + else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; } 1.137 + else { break; } 1.138 + if (try_klass.is_null()) continue; 1.139 TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK); 1.140 TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK); 1.141 - methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop()) 1.142 + methodOop raiseException_method = instanceKlass::cast(try_klass->as_klassOop()) 1.143 ->find_method(raiseException_name, raiseException_sig); 1.144 if (raiseException_method != NULL && raiseException_method->is_static()) { 1.145 MethodHandles::set_raise_exception_method(raiseException_method); 1.146 - } else { 1.147 - warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 1.148 - enable_MH = false; 1.149 + found_raise_exception = true; 1.150 + break; 1.151 } 1.152 - } else { 1.153 + } 1.154 + if (!found_raise_exception) { 1.155 + warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 1.156 enable_MH = false; 1.157 } 1.158 } 1.159 1.160 if (enable_MH) { 1.161 - // We need to link the MethodHandleImpl klass before we generate 1.162 - // the method handle adapters as the _raise_exception adapter uses 1.163 - // one of its methods (and its c2i-adapter). 1.164 - KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass(); 1.165 - instanceKlass* ik = instanceKlass::cast(k()); 1.166 - ik->link_class(CHECK); 1.167 + if (AllowTransitionalJSR292) { 1.168 + // We need to link the MethodHandleImpl klass before we generate 1.169 + // the method handle adapters as the _raise_exception adapter uses 1.170 + // one of its methods (and its c2i-adapter). 1.171 + KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass(); 1.172 + instanceKlass* ik = instanceKlass::cast(k()); 1.173 + ik->link_class(CHECK); 1.174 + } 1.175 1.176 MethodHandles::generate_adapters(); 1.177 MethodHandles::set_enabled(true); 1.178 @@ -2649,7 +2706,7 @@ 1.179 return; // bind nothing 1.180 } 1.181 1.182 - { 1.183 + if (AllowTransitionalJSR292) { 1.184 ThreadToNativeFromVM ttnfv(thread); 1.185 1.186 int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod)); 1.187 @@ -2657,8 +2714,6 @@ 1.188 MethodHandles::set_enabled(false); 1.189 warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 1.190 env->ExceptionClear(); 1.191 - } else { 1.192 - MethodHandles::set_enabled(true); 1.193 } 1.194 } 1.195 }