# HG changeset patch # User coleenp # Date 1360014661 28800 # Node ID 42ea5e1fad75135293fbb8d1aa40a6da9f55d28f # Parent 10d5f25a7c67f2eb2935820c6c0d73537596003d# Parent 24a91505f9d57e75c100851d35dad8cbfd5c0057 Merge diff -r 10d5f25a7c67 -r 42ea5e1fad75 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Mon Feb 04 08:26:02 2013 -0500 +++ b/src/share/vm/classfile/classFileParser.cpp Mon Feb 04 13:51:01 2013 -0800 @@ -1947,6 +1947,8 @@ u2** localvariable_type_table_start; u2 method_parameters_length = 0; u1* method_parameters_data = NULL; + bool method_parameters_seen = false; + bool method_parameters_four_byte_flags; bool parsed_code_attribute = false; bool parsed_checked_exceptions_attribute = false; bool parsed_stackmap_attribute = false; @@ -2157,21 +2159,31 @@ method_attribute_length, cp, CHECK_(nullHandle)); } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { + // reject multiple method parameters + if (method_parameters_seen) { + classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle)); + } + method_parameters_seen = true; method_parameters_length = cfs->get_u1_fast(); // Track the actual size (note: this is written for clarity; a // decent compiler will CSE and constant-fold this into a single // expression) - u2 actual_size = 1; + // Use the attribute length to figure out the size of flags + if (method_attribute_length == (method_parameters_length * 6u) + 1u) { + method_parameters_four_byte_flags = true; + } else if (method_attribute_length == (method_parameters_length * 4u) + 1u) { + method_parameters_four_byte_flags = false; + } else { + classfile_parse_error( + "Invalid MethodParameters method attribute length %u in class file", + method_attribute_length, CHECK_(nullHandle)); + } method_parameters_data = cfs->get_u1_buffer(); - actual_size += 2 * method_parameters_length; cfs->skip_u2_fast(method_parameters_length); - actual_size += 4 * method_parameters_length; - cfs->skip_u4_fast(method_parameters_length); - // Enforce attribute length - if (method_attribute_length != actual_size) { - classfile_parse_error( - "Invalid MethodParameters method attribute length %u in class file %s", - method_attribute_length, CHECK_(nullHandle)); + if (method_parameters_four_byte_flags) { + cfs->skip_u4_fast(method_parameters_length); + } else { + cfs->skip_u2_fast(method_parameters_length); } // ignore this attribute if it cannot be reflected if (!SystemDictionary::Parameter_klass_loaded()) @@ -2316,15 +2328,16 @@ // Copy method parameters if (method_parameters_length > 0) { MethodParametersElement* elem = m->constMethod()->method_parameters_start(); - for(int i = 0; i < method_parameters_length; i++) { - elem[i].name_cp_index = - Bytes::get_Java_u2(method_parameters_data); + for (int i = 0; i < method_parameters_length; i++) { + elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data); method_parameters_data += 2; - u4 flags = Bytes::get_Java_u4(method_parameters_data); - // This caused an alignment fault on Sparc, if flags was a u4 - elem[i].flags_lo = extract_low_short_from_int(flags); - elem[i].flags_hi = extract_high_short_from_int(flags); - method_parameters_data += 4; + if (method_parameters_four_byte_flags) { + elem[i].flags = Bytes::get_Java_u4(method_parameters_data); + method_parameters_data += 4; + } else { + elem[i].flags = Bytes::get_Java_u2(method_parameters_data); + method_parameters_data += 2; + } } } diff -r 10d5f25a7c67 -r 42ea5e1fad75 src/share/vm/oops/constMethod.hpp --- a/src/share/vm/oops/constMethod.hpp Mon Feb 04 08:26:02 2013 -0500 +++ b/src/share/vm/oops/constMethod.hpp Mon Feb 04 13:51:01 2013 -0800 @@ -122,12 +122,7 @@ class MethodParametersElement VALUE_OBJ_CLASS_SPEC { public: u2 name_cp_index; - // This has to happen, otherwise it will cause SIGBUS from a - // misaligned u4 on some architectures (ie SPARC) - // because MethodParametersElements are only aligned mod 2 - // within the ConstMethod container u2 flags_hi; - u2 flags_hi; - u2 flags_lo; + u2 flags; }; class KlassSizeStats; diff -r 10d5f25a7c67 -r 42ea5e1fad75 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Mon Feb 04 08:26:02 2013 -0500 +++ b/src/share/vm/prims/jvm.cpp Mon Feb 04 13:51:01 2013 -0800 @@ -1620,7 +1620,7 @@ // For a 0 index, give a NULL symbol Symbol* const sym = 0 != params[i].name_cp_index ? mh->constants()->symbol_at(params[i].name_cp_index) : NULL; - int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi); + int flags = params[i].flags; oop param = Reflection::new_parameter(reflected_method, i, sym, flags, CHECK_NULL); result->obj_at_put(i, param);