--- old/src/hotspot/share/classfile/systemDictionary.cpp 2019-03-11 14:25:39.858355519 +0100 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2019-03-11 14:25:39.654355522 +0100 @@ -67,6 +67,7 @@ #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" +#include "oops/valueKlass.hpp" #include "prims/jvmtiExport.hpp" #include "prims/resolvedMethodTable.hpp" #include "prims/methodHandles.hpp" @@ -78,6 +79,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/orderAccess.hpp" +#include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/signature.hpp" #include "services/classLoadingService.hpp" @@ -261,9 +263,9 @@ Handle protection_domain, TRAPS) { assert(class_name != NULL && !FieldType::is_array(class_name), "must be"); - if (FieldType::is_obj(class_name)) { + if (FieldType::is_obj(class_name) || FieldType::is_valuetype(class_name)) { ResourceMark rm(THREAD); - // Ignore wrapping L and ;. + // Ignore wrapping L and ;. (and Q and ; for value types); TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, class_name->utf8_length() - 2, CHECK_NULL); return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD); @@ -288,7 +290,7 @@ // dimension and object_key in FieldArrayInfo are assigned as a side-effect // of this call BasicType t = FieldType::get_array_info(class_name, fd, CHECK_NULL); - if (t == T_OBJECT) { + if (t == T_OBJECT || t == T_VALUETYPE) { // naked oop "k" is OK here -- we assign back into it k = SystemDictionary::resolve_instance_class_or_null(fd.object_key(), class_loader, @@ -304,7 +306,6 @@ return k; } - // Must be called for any super-class or super-interface resolution // during class definition to allow class circularity checking // super-interface callers: @@ -448,6 +449,51 @@ return superk; } +Klass* SystemDictionary::resolve_flattenable_field_or_fail(AllFieldStream* fs, + Handle class_loader, + Handle protection_domain, + bool throw_error, + TRAPS) { + Symbol* class_name = fs->signature()->fundamental_name(THREAD); + class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); + ClassLoaderData* loader_data = class_loader_data(class_loader); + unsigned int p_hash = placeholders()->compute_hash(class_name); + int p_index = placeholders()->hash_to_index(p_hash); + bool throw_circularity_error = false; + PlaceholderEntry* oldprobe; + + { + MutexLocker mu(SystemDictionary_lock, THREAD); + oldprobe = placeholders()->get_entry(p_index, p_hash, class_name, loader_data); + if (oldprobe != NULL && + oldprobe->check_seen_thread(THREAD, PlaceholderTable::FLATTENABLE_FIELD)) { + throw_circularity_error = true; + + } else { + placeholders()->find_and_add(p_index, p_hash, class_name, loader_data, + PlaceholderTable::FLATTENABLE_FIELD, NULL, THREAD); + } + } + + Klass* klass = NULL; + if (!throw_circularity_error) { + klass = SystemDictionary::resolve_or_fail(class_name, class_loader, + protection_domain, true, THREAD); + } else { + ResourceMark rm(THREAD); + THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), class_name->as_C_string()); + } + + { + MutexLocker mu(SystemDictionary_lock, THREAD); + placeholders()->find_and_remove(p_index, p_hash, class_name, loader_data, + PlaceholderTable::FLATTENABLE_FIELD, THREAD); + } + + class_name->decrement_refcount(); + return klass; +} + void SystemDictionary::validate_protection_domain(InstanceKlass* klass, Handle class_loader, Handle protection_domain, @@ -665,7 +711,7 @@ Handle protection_domain, TRAPS) { assert(name != NULL && !FieldType::is_array(name) && - !FieldType::is_obj(name), "invalid class name"); + !FieldType::is_obj(name) && !FieldType::is_valuetype(name), "invalid class name"); EventClassLoad class_load_start_event; @@ -976,7 +1022,7 @@ // side-effect of this call FieldArrayInfo fd; BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL)); - if (t != T_OBJECT) { + if (t != T_OBJECT && t != T_VALUETYPE) { k = Universe::typeArrayKlassObj(t); } else { k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD); @@ -2165,7 +2211,7 @@ // cleared if revocation occurs too often for this type // NOTE that we must only do this when the class is initally // defined, not each time it is referenced from a new class loader - if (oopDesc::equals(k->class_loader(), class_loader())) { + if (oopDesc::equals(k->class_loader(), class_loader()) && !k->is_value()) { k->set_prototype_header(markOopDesc::biased_locking_prototype()); } } @@ -2211,7 +2257,7 @@ // constraint table. The element Klass*s are. FieldArrayInfo fd; BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL)); - if (t != T_OBJECT) { + if (t != T_OBJECT && t != T_VALUETYPE) { klass = Universe::typeArrayKlassObj(t); } else { MutexLocker mu(SystemDictionary_lock, THREAD); @@ -2551,7 +2597,7 @@ assert(is_java_primitive(char2type(ch)) || ch == 'V', ""); return Handle(THREAD, find_java_mirror_for_type(ch)); - } else if (FieldType::is_obj(type) || FieldType::is_array(type)) { + } else if (FieldType::is_obj(type) || FieldType::is_valuetype(type) || FieldType::is_array(type)) { // It's a reference type. if (accessing_klass != NULL) {