< 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 >