src/share/vm/prims/methodHandles.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/prims/methodHandles.cpp Thu Mar 3 02:25:24 2011
--- new/src/share/vm/prims/methodHandles.cpp Thu Mar 3 02:25:24 2011
*** 2521,2560 ****
--- 2521,2560 ----
}
}
JVM_END
JVM_ENTRY(jobject, MHI_getBootstrap(JNIEnv *env, jobject igcls, jclass caller_jh)) {
+ if (!AllowTransitionalJSR292)
+ THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "getBootstrap: transitional only");
instanceKlassHandle ik = MethodHandles::resolve_instance_klass(caller_jh, THREAD);
return JNIHandles::make_local(THREAD, ik->bootstrap_method());
}
JVM_END
JVM_ENTRY(void, MHI_setCallSiteTarget(JNIEnv *env, jobject igcls, jobject site_jh, jobject target_jh)) {
// No special action required, yet.
! oop site_oop = JNIHandles::resolve(site_jh);
if (!java_dyn_CallSite::is_instance(site_oop))
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "not a CallSite");
java_dyn_CallSite::set_target(site_oop, JNIHandles::resolve(target_jh));
+ if (!AllowTransitionalJSR292)
! THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "setCallSite: transitional only");
}
JVM_END
/// JVM_RegisterMethodHandleMethods
#define ADR "J"
#define LANG "Ljava/lang/"
! #define JDYN "Ljava/dyn/"
! #define IDYN "Lsun/dyn/"
! #define JLINV "Ljava/lang/invoke/" /* standard package */
! #define JDYN "Ljava/dyn/" /* alternative package to JLINV if AllowTransitionalJSR292 */
+ #define IDYN "Lsun/dyn/" /* alternative package to JDYN if AllowTransitionalJSR292 */
+ // FIXME: After AllowTransitionalJSR292 is removed, replace JDYN and IDYN by JLINV.
#define OBJ LANG"Object;"
#define CLS LANG"Class;"
#define STRG LANG"String;"
#define CST JDYN"CallSite;"
#define MT JDYN"MethodType;"
#define MH JDYN"MethodHandle;"
#define MHI IDYN"MethodHandleImpl;"
#define MEM IDYN"MemberName;"
#define AMH IDYN"AdapterMethodHandle;"
#define BMH IDYN"BoundMethodHandle;"
#define DMH IDYN"DirectMethodHandle;"
*** 2579,2594 ****
--- 2579,2620 ----
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
{CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHI_getMembers)}
};
// More entry points specifically for EnableInvokeDynamic.
+ // FIXME: Remove methods2 after AllowTransitionalJSR292 is removed.
static JNINativeMethod methods2[] = {
{CC"registerBootstrap", CC"("CLS MH")V", FN_PTR(MHI_registerBootstrap)},
{CC"getBootstrap", CC"("CLS")"MH, FN_PTR(MHI_getBootstrap)},
{CC"setCallSiteTarget", CC"("CST MH")V", FN_PTR(MHI_setCallSiteTarget)}
};
+ static void hack_signatures(JNINativeMethod* methods, jint num_methods, const char* from_sig, const char* to_sig) {
+ for (int i = 0; i < num_methods; i++) {
+ const char* sig = methods[i].signature;
+ if (!strstr(sig, from_sig)) continue;
+ size_t buflen = strlen(sig) + 100;
+ char* buf = NEW_C_HEAP_ARRAY(char, buflen);
+ char* bufp = buf;
+ const char* sigp = sig;
+ size_t from_len = strlen(from_sig), to_len = strlen(to_sig);
+ while (*sigp != '\0') {
+ assert(bufp < buf + buflen - to_len - 1, "oob");
+ if (strncmp(sigp, from_sig, from_len) != 0) {
+ *bufp++ = *sigp++;
+ } else {
+ strcpy(bufp, to_sig);
+ bufp += to_len;
+ sigp += from_len;
+ }
+ }
+ *bufp = '\0';
+ methods[i].signature = buf; // replace with new signature
+ if (TraceMethodHandles)
+ tty->print_cr("MethodHandleNatives: %s: change signature %s => %s", methods[i].name, sig, buf);
+ }
+ }
// This one function is exported, used by NativeLookup.
JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
*** 2598,2665 ****
--- 2624,2720 ----
if (!EnableMethodHandles) {
warning("JSR 292 method handles are disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles to enable.");
return; // bind nothing
}
+ if (SystemDictionary::MethodHandleNatives_klass() != NULL &&
+ SystemDictionary::MethodHandleNatives_klass() != java_lang_Class::as_klassOop(JNIHandles::resolve(MHN_class))) {
+ warning("multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
+ THROW_MSG(vmSymbols::java_lang_InternalError(), "multiple versions of MethodHandleNatives in boot classpath; consider using -XX:+PreferTransitionalJSR292");
+ }
+
bool enable_MH = true;
{
+ // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
+ bool registered_natives = false;
+ bool try_plain = true, try_JDYN = true, try_IDYN = true;
+ for (;;) {
ThreadToNativeFromVM ttnfv(thread);
+ if (try_plain) { try_plain = false; }
+ else if (try_JDYN) { try_JDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), IDYN, JDYN); }
+ else if (try_IDYN) { try_IDYN = false; hack_signatures(methods, sizeof(methods)/sizeof(JNINativeMethod), JDYN, JLINV); }
+ else { break; }
int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
+ env->ExceptionClear();
+ // and try again...
+ } else {
+ registered_natives = true;
+ break;
+ }
+ }
+ if (!registered_natives) {
MethodHandles::set_enabled(false);
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
env->ExceptionClear();
}
}
if (enable_MH) {
+ bool found_raise_exception = false;
+ KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
KlassHandle MHI_klass = SystemDictionaryHandles::MethodHandleImpl_klass();
if (MHI_klass.not_null()) {
+ // Loop control. FIXME: Replace by dead reckoning after AllowTransitionalJSR292 is removed.
+ bool try_MHN = true, try_MHI = AllowTransitionalJSR292;
+ for (;;) {
+ KlassHandle try_klass;
+ if (try_MHN) { try_MHN = false; try_klass = MHN_klass; }
+ else if (try_MHI) { try_MHI = false; try_klass = MHI_klass; }
+ else { break; }
+ if (try_klass.is_null()) continue;
TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK);
TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK);
! methodOop raiseException_method = instanceKlass::cast(MHI_klass->as_klassOop())
! methodOop raiseException_method = instanceKlass::cast(try_klass->as_klassOop())
->find_method(raiseException_name, raiseException_sig);
if (raiseException_method != NULL && raiseException_method->is_static()) {
MethodHandles::set_raise_exception_method(raiseException_method);
} else {
! warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
+ found_raise_exception = true;
! break;
}
} else {
+ }
+ if (!found_raise_exception) {
+ warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
}
}
if (enable_MH) {
+ if (AllowTransitionalJSR292) {
// We need to link the MethodHandleImpl klass before we generate
// the method handle adapters as the _raise_exception adapter uses
// one of its methods (and its c2i-adapter).
KlassHandle k = SystemDictionaryHandles::MethodHandleImpl_klass();
instanceKlass* ik = instanceKlass::cast(k());
ik->link_class(CHECK);
+ }
MethodHandles::generate_adapters();
MethodHandles::set_enabled(true);
}
if (!EnableInvokeDynamic) {
warning("JSR 292 invokedynamic is disabled in this JVM. Use -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic to enable.");
return; // bind nothing
}
! if (AllowTransitionalJSR292) {
ThreadToNativeFromVM ttnfv(thread);
int status = env->RegisterNatives(MHN_class, methods2, sizeof(methods2)/sizeof(JNINativeMethod));
if (env->ExceptionOccurred()) {
MethodHandles::set_enabled(false);
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
env->ExceptionClear();
} else {
MethodHandles::set_enabled(true);
}
}
}
JVM_END
src/share/vm/prims/methodHandles.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File