< prev index next >
src/hotspot/share/classfile/classFileParser.cpp
Print this page
*** 3157,3166 ****
--- 3157,3200 ----
JVM_ACC_PRIVATE | \
JVM_ACC_PROTECTED | \
JVM_ACC_STATIC \
)
+ u2 ClassFileParser::parse_value_types_attribute(const ClassFileStream* const cfs,
+ const u1* const value_types_attribute_start,
+ TRAPS) {
+ const u1* const current_mark = cfs->current();
+ u2 length = 0;
+ if (value_types_attribute_start != NULL) {
+ cfs->set_current(value_types_attribute_start);
+ cfs->guarantee_more(2, CHECK_0); // length
+ length = cfs->get_u2_fast();
+ }
+ Array<ValueTypes>* const value_types = MetadataFactory::new_array<ValueTypes>(_loader_data, length, CHECK_0);
+
+ int index = 0;
+ const int cp_size = _cp->length();
+ cfs->guarantee_more(2 *length, CHECK_0);
+ for (int n = 0; n < length; n++) {
+ // Value types class index
+ const u2 value_types_info_index = cfs->get_u2_fast();
+ check_property(
+ valid_klass_reference_at(value_types_info_index),
+ "value_types_info_index %u has bad constant type in class file %s",
+ value_types_info_index, CHECK_0);
+ ValueTypes vt;
+ vt._class_info_index = value_types_info_index;
+ vt._class_name = NULL;
+ value_types->at_put(index++, vt);
+ }
+ _value_types = value_types;
+ // Restore buffer's current position.
+ cfs->set_current(current_mark);
+
+ return length;
+ }
+
// Return number of classes in the inner classes attribute table
u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStream* const cfs,
const u1* const inner_classes_attribute_start,
bool parsed_enclosingmethod_attribute,
u2 enclosing_method_class_index,
*** 3377,3386 ****
--- 3411,3421 ----
_inner_classes = Universe::the_empty_short_array();
cfs->guarantee_more(2, CHECK); // attributes_count
u2 attributes_count = cfs->get_u2_fast();
bool parsed_sourcefile_attribute = false;
bool parsed_innerclasses_attribute = false;
+ bool parsed_value_types_attribute = false;
bool parsed_enclosingmethod_attribute = false;
bool parsed_bootstrap_methods_attribute = false;
const u1* runtime_visible_annotations = NULL;
int runtime_visible_annotations_length = 0;
const u1* runtime_invisible_annotations = NULL;
*** 3392,3401 ****
--- 3427,3438 ----
bool runtime_invisible_type_annotations_exists = false;
bool runtime_invisible_annotations_exists = false;
bool parsed_source_debug_ext_annotations_exist = false;
const u1* inner_classes_attribute_start = NULL;
u4 inner_classes_attribute_length = 0;
+ const u1* value_types_attribute_start = NULL;
+ u4 value_types_attribute_length = 0;
u2 enclosing_method_class_index = 0;
u2 enclosing_method_method_index = 0;
// Iterate over attributes
while (attributes_count--) {
cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length
*** 3433,3442 ****
--- 3470,3489 ----
parsed_innerclasses_attribute = true;
}
inner_classes_attribute_start = cfs->current();
inner_classes_attribute_length = attribute_length;
cfs->skip_u1(inner_classes_attribute_length, CHECK);
+ } else if (tag == vmSymbols::tag_value_types()) {
+ // Check for ValueTypes tag
+ if (parsed_value_types_attribute) {
+ classfile_parse_error("Multiple ValueTypes attributes in class file %s", CHECK);
+ } else {
+ parsed_value_types_attribute = true;
+ }
+ value_types_attribute_start = cfs->current();
+ value_types_attribute_length = attribute_length;
+ cfs->skip_u1(value_types_attribute_length, CHECK);
} else if (tag == vmSymbols::tag_synthetic()) {
// Check for Synthetic tag
// Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
if (attribute_length != 0) {
classfile_parse_error(
*** 3577,3586 ****
--- 3624,3637 ----
inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
"Wrong InnerClasses attribute length in class file %s", CHECK);
}
}
+ if (parsed_value_types_attribute) {
+ parse_value_types_attribute(cfs, value_types_attribute_start, CHECK);
+ }
+
if (_max_bootstrap_specifier_index >= 0) {
guarantee_property(parsed_bootstrap_methods_attribute,
"Missing BootstrapMethods attribute in class file %s", CHECK);
}
}
*** 3639,3648 ****
--- 3690,3700 ----
_cp->set_pool_holder(this_klass);
this_klass->set_constants(_cp);
this_klass->set_fields(_fields, java_fields_count);
this_klass->set_methods(_methods);
this_klass->set_inner_classes(_inner_classes);
+ this_klass->set_value_types(_value_types);
this_klass->set_local_interfaces(_local_interfaces);
this_klass->set_transitive_interfaces(_transitive_interfaces);
this_klass->set_annotations(_combined_annotations);
// Clear out these fields so they don't get deallocated by the destructor
*** 4021,4045 ****
// issues. Note that super-class circularity checks are not needed here
// because flattenable fields can only be in value types and value types
// only have java.lang.Object as their super class.
// Also, note that super-interface circularity checks are not needed
// because interfaces cannot be value types.
Klass* klass =
SystemDictionary::resolve_flattenable_field_or_fail(&fs,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
! assert(klass->access_flags().is_value_type(), "Value type expected");
static_value_type_count++;
} else if (fs.allocation_type() == NONSTATIC_FLATTENABLE) {
// Pre-resolve the flattenable field and check for value type circularity issues.
Klass* klass =
SystemDictionary::resolve_flattenable_field_or_fail(&fs,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
! assert(klass->access_flags().is_value_type(), "Value type expected");
ValueKlass* vk = ValueKlass::cast(klass);
// Conditions to apply flattening or not should be defined in a single place
if ((ValueFieldMaxFlatSize < 0) || (vk->size_helper() * HeapWordSize) <= ValueFieldMaxFlatSize) {
nonstatic_value_type_indexes[nonstatic_value_type_count] = fs.index();
nonstatic_value_type_klasses[nonstatic_value_type_count] = klass;
--- 4073,4121 ----
// issues. Note that super-class circularity checks are not needed here
// because flattenable fields can only be in value types and value types
// only have java.lang.Object as their super class.
// Also, note that super-interface circularity checks are not needed
// because interfaces cannot be value types.
+ ResourceMark rm;
+ Symbol* sig = fs.signature();
+ Symbol* name = SymbolTable::lookup(sig->as_C_string() + 1,
+ sig->utf8_length() - 2, CHECK);
+ if (!InstanceKlass::is_declared_value_type(_cp, _value_types, name)) {
+ name->decrement_refcount();
+ THROW(vmSymbols::java_lang_ClassFormatError());
+ }
+ name->decrement_refcount();
Klass* klass =
SystemDictionary::resolve_flattenable_field_or_fail(&fs,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
! if (!klass->access_flags().is_value_type()) {
! THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
! }
static_value_type_count++;
} else if (fs.allocation_type() == NONSTATIC_FLATTENABLE) {
// Pre-resolve the flattenable field and check for value type circularity issues.
+ ResourceMark rm;
+ Symbol* sig = fs.signature();
+ Symbol* name = SymbolTable::lookup(sig->as_C_string() + 1,
+ sig->utf8_length() - 2, CHECK);
+ if (!InstanceKlass::is_declared_value_type(_cp, _value_types, name)) {
+ name->decrement_refcount();
+ char* name = fs.name()->as_C_string();
+ char* signature = fs.signature()->as_C_string();
+ THROW(vmSymbols::java_lang_ClassFormatError());
+ }
+ name->decrement_refcount();
Klass* klass =
SystemDictionary::resolve_flattenable_field_or_fail(&fs,
Handle(THREAD, _loader_data->class_loader()),
_protection_domain, true, CHECK);
assert(klass != NULL, "Sanity check");
! if (!klass->access_flags().is_value_type()) {
! THROW(vmSymbols::java_lang_IncompatibleClassChangeError());
! }
ValueKlass* vk = ValueKlass::cast(klass);
// Conditions to apply flattening or not should be defined in a single place
if ((ValueFieldMaxFlatSize < 0) || (vk->size_helper() * HeapWordSize) <= ValueFieldMaxFlatSize) {
nonstatic_value_type_indexes[nonstatic_value_type_count] = fs.index();
nonstatic_value_type_klasses[nonstatic_value_type_count] = klass;
*** 5940,5949 ****
--- 6016,6026 ----
_super_klass(),
_cp(NULL),
_fields(NULL),
_methods(NULL),
_inner_classes(NULL),
+ _value_types(NULL),
_local_interfaces(NULL),
_transitive_interfaces(NULL),
_combined_annotations(NULL),
_annotations(NULL),
_type_annotations(NULL),
< prev index next >