Mercurial > hg > release > icedtea7-forest-2.5 > hotspot
changeset 5843:d095415c0700
8075838: Method for typing MethodTypes
Reviewed-by: jrose, ahgross, alanb, bmoloden
author | vlivanov |
---|---|
date | Mon, 06 Jul 2015 19:41:23 +0100 |
parents | f9edc77edd3c |
children | 235355f70290 |
files | src/share/vm/classfile/systemDictionary.cpp |
diffstat | 1 files changed, 33 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/classfile/systemDictionary.cpp Fri Jul 03 21:30:02 2015 +0100 +++ b/src/share/vm/classfile/systemDictionary.cpp Mon Jul 06 19:41:23 2015 +0100 @@ -2305,9 +2305,6 @@ assert(!THREAD->is_Compiler_thread(), ""); Handle method_type = SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty)); - if (false) { // FIXME: Decide if the Java upcall should resolve signatures. - method_type = java_lang_String::create_from_symbol(signature, CHECK_(empty)); - } KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass(); int ref_kind = JVM_REF_invokeVirtual; @@ -2339,6 +2336,24 @@ return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD); } +// Decide if we can globally cache a lookup of this class, to be returned to any client that asks. +// We must ensure that all class loaders everywhere will reach this class, for any client. +// This is a safe bet for public classes in java.lang, such as Object and String. +// We also include public classes in java.lang.invoke, because they appear frequently in system-level method types. +// Out of an abundance of caution, we do not include any other classes, not even for packages like java.util. +static bool is_always_visible_class(oop mirror) { + klassOop klass = java_lang_Class::as_klassOop(mirror); + if (Klass::cast(klass)->oop_is_objArray()) { + klass = objArrayKlass::cast(klass)->bottom_klass(); // check element type + } + if (Klass::cast(klass)->oop_is_typeArray()) { + return true; // primitive array + } + assert(Klass::cast(klass)->oop_is_instance(), Klass::cast(klass)->external_name()); + return Klass::cast(klass)->is_public() && + (instanceKlass::cast(klass)->is_same_class_package(SystemDictionary::Object_klass()) || // java.lang + instanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass())); // java.lang.invoke +} // Ask Java code to find or construct a java.lang.invoke.MethodType for the given // signature, as interpreted relative to the given class loader. @@ -2361,32 +2376,33 @@ } Handle class_loader, protection_domain; - bool is_on_bcp = true; // keep this true as long as we can materialize from the boot classloader + if (accessing_klass.not_null()) { + class_loader = Handle(THREAD, instanceKlass::cast(accessing_klass())->class_loader()); + protection_domain = Handle(THREAD, instanceKlass::cast(accessing_klass())->protection_domain()); + } + bool can_be_cached = true; int npts = ArgumentCount(signature).size(); objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty)); int arg = 0; - Handle rt; // the return type from the signature + Handle rt; // the return type from the signature ResourceMark rm(THREAD); for (SignatureStream ss(signature); !ss.is_done(); ss.next()) { oop mirror = NULL; - if (is_on_bcp) { - // Note: class_loader & protection_domain are both null at this point. - mirror = ss.as_java_mirror(class_loader, protection_domain, + if (can_be_cached) { + // Use neutral class loader to lookup candidate classes to be placed in the cache. + mirror = ss.as_java_mirror(Handle(), Handle(), SignatureStream::ReturnNull, CHECK_(empty)); - if (mirror == NULL) { - // fall back from BCP to accessing_klass - if (accessing_klass.not_null()) { - class_loader = Handle(THREAD, instanceKlass::cast(accessing_klass())->class_loader()); - protection_domain = Handle(THREAD, instanceKlass::cast(accessing_klass())->protection_domain()); - } - is_on_bcp = false; + if (mirror == NULL || (ss.is_object() && !is_always_visible_class(mirror))) { + // Fall back to accessing_klass context. + can_be_cached = false; } } - if (!is_on_bcp) { + if (!can_be_cached) { // Resolve, throwing a real error if it doesn't work. mirror = ss.as_java_mirror(class_loader, protection_domain, SignatureStream::NCDFError, CHECK_(empty)); } + assert(!oopDesc::is_null(mirror), ss.as_symbol(THREAD)->as_C_string()); if (ss.at_return_type()) rt = Handle(THREAD, mirror); else @@ -2418,7 +2434,7 @@ &args, CHECK_(empty)); Handle method_type(THREAD, (oop) result.get_jobject()); - if (is_on_bcp) { + if (can_be_cached) { // We can cache this MethodType inside the JVM. MutexLocker ml(SystemDictionary_lock, THREAD); spe = invoke_method_table()->find_entry(index, hash, signature, null_iid);