--- old/src/hotspot/share/oops/instanceKlass.cpp 2018-05-17 15:55:44.000000000 -0400 +++ new/src/hotspot/share/oops/instanceKlass.cpp 2018-05-17 15:55:43.000000000 -0400 @@ -403,6 +403,11 @@ } set_inner_classes(NULL); + if (value_types() != NULL && !value_types()->is_shared()) { + MetadataFactory::free_array(loader_data, value_types()); + } + set_value_types(NULL); + // We should deallocate the Annotations instance if it's not in shared spaces. if (annotations() != NULL && !annotations()->is_shared()) { MetadataFactory::free_metadata(loader_data, annotations()); @@ -626,40 +631,46 @@ ResourceMark rm(THREAD); if (fs.field_descriptor().access_flags().is_flattenable()) { Symbol* signature = fs.field_descriptor().signature(); + ResourceMark rm; + Symbol* name = SymbolTable::lookup(signature->as_C_string() + 1, + signature->utf8_length() - 2, CHECK_false); + assert(this->is_declared_value_type(name), "Verifying consistency with ValueTypes attribute"); + name->decrement_refcount(); + name = NULL; // Get current loader and protection domain first. oop loader = class_loader(); oop prot_domain = protection_domain(); Klass* klass = SystemDictionary::resolve_or_fail(signature, Handle(THREAD, loader), Handle(THREAD, prot_domain), true, - THREAD); + CHECK_false); if (klass == NULL) { THROW_(vmSymbols::java_lang_LinkageError(), false); } } } - // Second step: methods arguments and return types - // for (int i = 0; i < this_k->constants()->length(); i++) { - // if (this_k->constants()->tag_at(i).is_method()) { - // Symbol* signature = this_k->constants()->signature_ref_at(i); - // ResourceMark rm(THREAD); - // for (SignatureStream ss(signature); !ss.is_done(); ss.next()) { - // if (ss.type() == T_VALUETYPE) { - // Symbol* sig = ss.as_symbol(THREAD); - // // Get current loader and protection domain first. - // oop loader = this_k->class_loader(); - // oop protection_domain = this_k->protection_domain(); - // - // bool ok = SystemDictionary::resolve_or_fail(sig, - // Handle(THREAD, loader), Handle(THREAD, protection_domain), true, - // THREAD); - // if (!ok) { - // THROW_(vmSymbols::java_lang_LinkageError(), false); - // } - // } - // } - // } - // } + // Second step: methods arguments and return types + for (int i = 0; i < constants()->length(); i++) { + if (constants()->tag_at(i).is_method()) { + Symbol* signature = constants()->uncached_signature_ref_at(i); + ResourceMark rm(THREAD); + for (SignatureStream ss(signature); !ss.is_done(); ss.next()) { + Symbol* sig = ss.as_symbol(THREAD); + if (is_declared_value_type(sig)) { + // Get current loader and protection domain first. + oop loader = class_loader(); + oop protection_domain = this->protection_domain(); + + bool ok = SystemDictionary::resolve_or_fail(sig, + Handle(THREAD, loader), Handle(THREAD, protection_domain), true, + CHECK_false); + if (!ok) { + THROW_(vmSymbols::java_lang_LinkageError(), false); + } + } + } + } + } // in case the class is linked in the process of linking its superclasses if (is_linked()) { @@ -2342,6 +2353,14 @@ // unreference array name derived from this class name (arrays of an unloaded // class can't be referenced anymore). if (_array_name != NULL) _array_name->decrement_refcount(); + if (_value_types != NULL) { + for (int i = 0; i < _value_types->length(); i++) { + Symbol* s = _value_types->at(i)._class_name; + if (s != NULL) { + s->decrement_refcount(); + } + } + } if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension); } @@ -3219,6 +3238,48 @@ return external_name(); } +bool InstanceKlass::is_declared_value_type(int index) { + assert(constants()->is_within_bounds(index) && + constants()->tag_at(index).is_klass_or_reference(), "Invalid index"); + if (value_types() == NULL) return false; // No ValueType attribute in this class file + return InstanceKlass::is_declared_value_type(value_types(), index); +} + +bool InstanceKlass::is_declared_value_type(Array* value_types, int index) { + assert(value_types != NULL, "Sanity check"); + for(int i = 0; i < value_types->length(); i++) { + if (value_types->at(i)._class_info_index == index) { + return true; + } + } + return false; +} + +bool InstanceKlass::is_declared_value_type(Symbol* symbol) { + if (value_types() == NULL) return false; // No ValueType attribute in this class file + return InstanceKlass::is_declared_value_type(constants(), value_types(), symbol); +} + +bool InstanceKlass::is_declared_value_type(ConstantPool* constants, Array* value_types, Symbol* symbol) { + assert(symbol != NULL, "Sanity check"); + assert(value_types != NULL, "Sanity check"); + for(int i = 0; i < value_types->length(); i++) { + if (value_types->at(i)._class_name == symbol) { + return true; + } + } + // symbol not found, class name symbol might not have been + // updated yet + for(int i = 0; i < value_types->length(); i++) { + if (constants->klass_at_noresolve((int)value_types->at(i)._class_info_index) == symbol) { + value_types->adr_at(i)->_class_name = symbol; + symbol->increment_refcount(); + return true; + } + } + return false; +} + void InstanceKlass::print_class_load_logging(ClassLoaderData* loader_data, const char* module_name, const ClassFileStream* cfs) const {