< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page

        

*** 216,225 **** --- 216,276 ---- } log_trace(class, nestmates)("- class is NOT a nest member!"); return false; } + // Called to verify that k is a permitted subclass of this class + bool InstanceKlass::has_as_permitted_subclass(const InstanceKlass* k) const { + Thread* THREAD = Thread::current(); + assert(k != NULL, "sanity check"); + assert(_permitted_subclasses != NULL && _permitted_subclasses != Universe::the_empty_short_array(), + "unexpected empty _permitted_subclasses array"); + + if (log_is_enabled(Trace, class, sealed)) { + ResourceMark rm(THREAD); + log_trace(class, sealed)("Checking for permitted subclass of %s in %s", + k->external_name(), this->external_name()); + } + + // Check that the class and its super are in the same module. + if (k->module() != this->module()) { + ResourceMark rm(THREAD); + log_trace(class, sealed)("Check failed for same module of permitted subclass %s and sealed class %s", + k->external_name(), this->external_name()); + return false; + } + + if (!k->is_public() && !is_same_class_package(k)) { + ResourceMark rm(THREAD); + log_trace(class, sealed)("Check failed, subclass %s not public and not in the same package as 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_subclasses->length(); i++) { + int cp_index = _permitted_subclasses->at(i); + if (_constants->tag_at(cp_index).is_klass()) { + Klass* k2 = _constants->klass_at(cp_index, THREAD); + assert(!HAS_PENDING_EXCEPTION, "Unexpected exception"); + if (k2 == k) { + log_trace(class, sealed)("- class is listed at permitted_subclasses[%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_subclasses[%d] => cp[%d]", i, cp_index); + return true; + } + } + } + log_trace(class, sealed)("- class is NOT a permitted subclass!"); + return false; + } + // Return nest-host class, resolving, validating and saving it if needed. // In cases where this is called from a thread that cannot 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. Otherwise the _nest_host is always
*** 482,491 **** --- 533,543 ---- InstanceKlass::InstanceKlass(const ClassFileParser& parser, unsigned kind, KlassID id) : Klass(id), _nest_members(NULL), _nest_host(NULL), + _permitted_subclasses(NULL), _record_components(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()), _nest_host_index(0),
*** 663,672 **** --- 715,731 ---- !nest_members()->is_shared()) { MetadataFactory::free_array<jushort>(loader_data, nest_members()); } set_nest_members(NULL); + if (permitted_subclasses() != NULL && + permitted_subclasses() != Universe::the_empty_short_array() && + !permitted_subclasses()->is_shared()) { + MetadataFactory::free_array<jushort>(loader_data, permitted_subclasses()); + } + set_permitted_subclasses(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);
*** 674,683 **** --- 733,748 ---- if (Arguments::is_dumping_archive()) { SystemDictionaryShared::remove_dumptime_info(this); } } + bool InstanceKlass::is_sealed() const { + return _permitted_subclasses != NULL && + _permitted_subclasses != Universe::the_empty_short_array() && + _permitted_subclasses->length() > 0; + } + bool InstanceKlass::should_be_initialized() const { return !is_initialized(); } klassItable InstanceKlass::itable() const {
*** 2412,2421 **** --- 2477,2487 ---- } } } it->push(&_nest_members); + it->push(&_permitted_subclasses); it->push(&_record_components); } void InstanceKlass::remove_unshareable_info() { Klass::remove_unshareable_info();
*** 3340,3349 **** --- 3406,3416 ---- 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(); if (record_components() != NULL) { st->print(BULLET"record components: "); record_components()->print_value_on(st); st->cr(); } + st->print(BULLET"permitted subclasses: "); permitted_subclasses()->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 >