< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page

        

*** 209,218 **** --- 209,272 ---- } log_trace(class, nestmates)("- class is NOT a nest member!"); return false; } + // Called to verify that k is a permitted subtype of this class + bool InstanceKlass::has_as_permitted_subtype(InstanceKlass* k, TRAPS) const { + if (k == NULL) { + if (log_is_enabled(Trace, class, sealed)) { + ResourceMark rm(THREAD); + log_trace(class, sealed)("Checked for permitted subtype of %s with a NULL instance class", this->external_name()); + } + return false; + } + if (_permitted_subtypes == NULL || _permitted_subtypes == Universe::the_empty_short_array()) { + if (log_is_enabled(Trace, class, sealed)) { + ResourceMark rm(THREAD); + log_trace(class, sealed)("Checked for permitted subtype of %s in non-sealed class %s", + k->external_name(), this->external_name()); + } + return false; + } + + if (log_is_enabled(Trace, class, sealed)) { + ResourceMark rm(THREAD); + log_trace(class, sealed)("Checking for permitted subtype of %s in %s", + k->external_name(), this->external_name()); + } + + oop classloader1 = this->class_loader(); + oop classloader2 = k->class_loader(); + if (!oopDesc::equals(classloader1, classloader2)) { + log_trace(class, sealed)("Checked for same class loader of permitted subtype of %s and sealed class %s", + k->external_name(), this->external_name()); + return false; + } + + // Check for a resolved cp entry, else fall back to a name check. + // We don't want to resolve any class other than the one being checked. + for (int i = 0; i < _permitted_subtypes->length(); i++) { + int cp_index = _permitted_subtypes->at(i); + if (_constants->tag_at(cp_index).is_klass()) { + Klass* k2 = _constants->klass_at(cp_index, CHECK_false); + if (k2 == k) { + log_trace(class, sealed)("- class is listed at permitted_subtypes[%d] => cp[%d]", i, cp_index); + return true; + } + } else { + Symbol* name = _constants->klass_name_at(cp_index); + if (name == k->name()) { + log_trace(class, sealed)("- Found it at permitted_subtypes[%d] => cp[%d]", i, cp_index); + return true; + } + } + } + log_trace(class, sealed)("- class is NOT a permitted subtype!"); + return false; + } + // Return nest-host class, resolving, validating and saving it if needed. // In cases where this is called from a thread that can not do classloading // (such as a native JIT thread) then we simply return NULL, which in turn // causes the access check to return false. Such code will retry the access // from a more suitable environment later.
*** 433,442 **** --- 487,497 ---- InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, KlassID id) : Klass(id), _nest_members(NULL), _nest_host_index(0), _nest_host(NULL), + _permitted_subtypes(NULL), _static_field_size(parser.static_field_size()), _nonstatic_oop_map_size(nonstatic_oop_map_size(parser.total_oop_map_count())), _itable_len(parser.itable_size()), _init_thread(NULL), _init_state(allocated),
*** 595,604 **** --- 650,672 ---- !nest_members()->is_shared()) { MetadataFactory::free_array<jushort>(loader_data, nest_members()); } set_nest_members(NULL); + if (record_params() != NULL && + record_params() != Universe::the_empty_short_array()) { + MetadataFactory::free_array<jushort>(loader_data, record_params()); + } + set_record_params(NULL, 0); + + if (permitted_subtypes() != NULL && + permitted_subtypes() != Universe::the_empty_short_array() && + !permitted_subtypes()->is_shared()) { + MetadataFactory::free_array<jushort>(loader_data, permitted_subtypes()); + } + set_permitted_subtypes(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()); } set_annotations(NULL);
*** 606,615 **** --- 674,690 ---- if (DumpSharedSpaces || DynamicDumpSharedSpaces) { SystemDictionaryShared::remove_dumptime_info(this); } } + bool InstanceKlass::is_sealed() const { + return is_final() && + _permitted_subtypes != NULL && + _permitted_subtypes != Universe::the_empty_short_array() && + _permitted_subtypes->length() > 0; + } + bool InstanceKlass::should_be_initialized() const { return !is_initialized(); } klassItable InstanceKlass::itable() const {
*** 2311,2320 **** --- 2386,2397 ---- } } } it->push(&_nest_members); + it->push(&_record_params); + it->push(&_permitted_subtypes); } void InstanceKlass::remove_unshareable_info() { Klass::remove_unshareable_info();
*** 3226,3235 **** --- 3303,3313 ---- generic_signature()->print_value_on(st); st->cr(); } st->print(BULLET"inner classes: "); inner_classes()->print_value_on(st); st->cr(); st->print(BULLET"nest members: "); nest_members()->print_value_on(st); st->cr(); + st->print(BULLET"permitted subtypes: "); permitted_subtypes()->print_value_on(st); st->cr(); if (java_mirror() != NULL) { st->print(BULLET"java mirror: "); java_mirror()->print_value_on(st); st->cr(); } else {
< prev index next >