< prev index next > src/hotspot/share/classfile/verificationType.cpp
Print this page
if (log_is_enabled(Debug, class, resolve)) {
Verifier::trace_class_resolution(this_class, klass);
}
}
+ // Need to do this check when called from CDS.
+ // if (this_class->access_flags().is_primitive_class()) {
+ // Klass* from_class = SystemDictionary::resolve_or_fail(
+ // from_name, Handle(THREAD, klass->class_loader()),
+ // Handle(THREAD, klass->protection_domain()), true, CHECK_false);
+ // return from_class == this_class;
+ // }
if (this_class->is_interface() && (!from_field_is_protected ||
from_name != vmSymbols::java_lang_Object())) {
// If we are not trying to access a protected field or method in
// java.lang.Object then, for arrays, we only allow assignability
- // to interfaces java.lang.Cloneable and java.io.Serializable.
+ // to interfaces java.lang.Cloneable and java.io.Serializable
// Otherwise, we treat interfaces as java.lang.Object.
return !from_is_array ||
this_class == vmClasses::Cloneable_klass() ||
this_class == vmClasses::Serializable_klass();
} else if (from_is_object) {
return resolve_and_check_assignability(klass, name(), from.name(),
from_field_is_protected, from.is_array(), from.is_object(), THREAD);
} else if (is_array() && from.is_array()) {
VerificationType comp_this = get_component(context);
VerificationType comp_from = from.get_component(context);
+
+ /*
+ // This code implements non-covariance between inline type arrays and both
+ // arrays of objects and arrays of interface types. If covariance is
+ // supported for inline type arrays then this code should be removed.
+ if (comp_from.is_inline_type() && !comp_this.is_null() && comp_this.is_reference()) {
+ // An array of inline types is not assignable to an array of java.lang.Objects.
+ if (comp_this.name() == vmSymbols::java_lang_Object()) {
+ return false;
+ }
+
+ // Need to load 'comp_this' to see if it is an interface.
+ InstanceKlass* klass = context->current_class();
+ {
+ HandleMark hm(THREAD);
+ Klass* comp_this_class = SystemDictionary::resolve_or_fail(
+ comp_this.name(), Handle(THREAD, klass->class_loader()),
+ Handle(THREAD, klass->protection_domain()), true, CHECK_false);
+ klass->class_loader_data()->record_dependency(comp_this_class);
+ if (log_is_enabled(Debug, class, resolve)) {
+ Verifier::trace_class_resolution(comp_this_class, klass);
+ }
+ // An array of inline types is not assignable to an array of interface types.
+ if (comp_this_class->is_interface()) {
+ return false;
+ }
+ }
+ }
+ */
if (!comp_this.is_bogus() && !comp_from.is_bogus()) {
return comp_this.is_component_assignable_from(comp_from, context,
from_field_is_protected, THREAD);
}
}
return false;
}
+ bool VerificationType::is_inline_type_assignable_from(const VerificationType& from) const {
+ // Check that 'from' is not null, is an inline type, and is the same inline type.
+ assert(is_inline_type(), "called with a non-inline type");
+ assert(!is_null(), "inline type is not null");
+ return (!from.is_null() && from.is_inline_type() && name() == from.name());
+ }
+
+ bool VerificationType::is_ref_assignable_from_inline_type(const VerificationType& from, ClassVerifier* context, TRAPS) const {
+ assert(!from.is_null(), "Inline type should not be null");
+ if (!is_null() && (name()->is_same_fundamental_type(from.name()) ||
+ name() == vmSymbols::java_lang_Object())) {
+ return true;
+ }
+
+ // Need to load 'this' to see if it is an interface or supertype.
+ InstanceKlass* klass = context->current_class();
+ {
+ HandleMark hm(THREAD);
+ Klass* this_class = SystemDictionary::resolve_or_fail(
+ name(), Handle(THREAD, klass->class_loader()),
+ Handle(THREAD, klass->protection_domain()), true, CHECK_false);
+ klass->class_loader_data()->record_dependency(this_class);
+ if (log_is_enabled(Debug, class, resolve)) {
+ Verifier::trace_class_resolution(this_class, klass);
+ }
+ if (this_class->is_interface()) {
+ return true;
+ } else {
+ Klass* from_class = SystemDictionary::resolve_or_fail(
+ from.name(), Handle(THREAD, klass->class_loader()),
+ Handle(THREAD, klass->protection_domain()), true, CHECK_false);
+ if (log_is_enabled(Debug, class, resolve)) {
+ Verifier::trace_class_resolution(from_class, klass);
+ }
+ return from_class->is_subclass_of(this_class);
+ }
+ }
+ }
+
VerificationType VerificationType::get_component(ClassVerifier *context) const {
assert(is_array() && name()->utf8_length() >= 2, "Must be a valid array");
SignatureStream ss(name(), false);
ss.skip_array_prefix(1);
switch (ss.type()) {
case Double: st->print("double"); break;
case Long_2nd: st->print("long_2nd"); break;
case Double_2nd: st->print("double_2nd"); break;
case Null: st->print("null"); break;
case ReferenceQuery: st->print("reference type"); break;
+ case InlineTypeQuery: st->print("inline type"); break;
+ case NonScalarQuery: st->print("reference or inline type"); break;
case Category1Query: st->print("category1 type"); break;
case Category2Query: st->print("category2 type"); break;
case Category2_2ndQuery: st->print("category2_2nd type"); break;
default:
if (is_uninitialized_this()) {
< prev index next >