Mon, 04 Feb 2013 13:51:01 -0800
Merge
1.1 --- a/src/share/vm/classfile/classFileParser.cpp Mon Feb 04 08:26:02 2013 -0500 1.2 +++ b/src/share/vm/classfile/classFileParser.cpp Mon Feb 04 13:51:01 2013 -0800 1.3 @@ -1947,6 +1947,8 @@ 1.4 u2** localvariable_type_table_start; 1.5 u2 method_parameters_length = 0; 1.6 u1* method_parameters_data = NULL; 1.7 + bool method_parameters_seen = false; 1.8 + bool method_parameters_four_byte_flags; 1.9 bool parsed_code_attribute = false; 1.10 bool parsed_checked_exceptions_attribute = false; 1.11 bool parsed_stackmap_attribute = false; 1.12 @@ -2157,21 +2159,31 @@ 1.13 method_attribute_length, 1.14 cp, CHECK_(nullHandle)); 1.15 } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { 1.16 + // reject multiple method parameters 1.17 + if (method_parameters_seen) { 1.18 + classfile_parse_error("Multiple MethodParameters attributes in class file %s", CHECK_(nullHandle)); 1.19 + } 1.20 + method_parameters_seen = true; 1.21 method_parameters_length = cfs->get_u1_fast(); 1.22 // Track the actual size (note: this is written for clarity; a 1.23 // decent compiler will CSE and constant-fold this into a single 1.24 // expression) 1.25 - u2 actual_size = 1; 1.26 + // Use the attribute length to figure out the size of flags 1.27 + if (method_attribute_length == (method_parameters_length * 6u) + 1u) { 1.28 + method_parameters_four_byte_flags = true; 1.29 + } else if (method_attribute_length == (method_parameters_length * 4u) + 1u) { 1.30 + method_parameters_four_byte_flags = false; 1.31 + } else { 1.32 + classfile_parse_error( 1.33 + "Invalid MethodParameters method attribute length %u in class file", 1.34 + method_attribute_length, CHECK_(nullHandle)); 1.35 + } 1.36 method_parameters_data = cfs->get_u1_buffer(); 1.37 - actual_size += 2 * method_parameters_length; 1.38 cfs->skip_u2_fast(method_parameters_length); 1.39 - actual_size += 4 * method_parameters_length; 1.40 - cfs->skip_u4_fast(method_parameters_length); 1.41 - // Enforce attribute length 1.42 - if (method_attribute_length != actual_size) { 1.43 - classfile_parse_error( 1.44 - "Invalid MethodParameters method attribute length %u in class file %s", 1.45 - method_attribute_length, CHECK_(nullHandle)); 1.46 + if (method_parameters_four_byte_flags) { 1.47 + cfs->skip_u4_fast(method_parameters_length); 1.48 + } else { 1.49 + cfs->skip_u2_fast(method_parameters_length); 1.50 } 1.51 // ignore this attribute if it cannot be reflected 1.52 if (!SystemDictionary::Parameter_klass_loaded()) 1.53 @@ -2316,15 +2328,16 @@ 1.54 // Copy method parameters 1.55 if (method_parameters_length > 0) { 1.56 MethodParametersElement* elem = m->constMethod()->method_parameters_start(); 1.57 - for(int i = 0; i < method_parameters_length; i++) { 1.58 - elem[i].name_cp_index = 1.59 - Bytes::get_Java_u2(method_parameters_data); 1.60 + for (int i = 0; i < method_parameters_length; i++) { 1.61 + elem[i].name_cp_index = Bytes::get_Java_u2(method_parameters_data); 1.62 method_parameters_data += 2; 1.63 - u4 flags = Bytes::get_Java_u4(method_parameters_data); 1.64 - // This caused an alignment fault on Sparc, if flags was a u4 1.65 - elem[i].flags_lo = extract_low_short_from_int(flags); 1.66 - elem[i].flags_hi = extract_high_short_from_int(flags); 1.67 - method_parameters_data += 4; 1.68 + if (method_parameters_four_byte_flags) { 1.69 + elem[i].flags = Bytes::get_Java_u4(method_parameters_data); 1.70 + method_parameters_data += 4; 1.71 + } else { 1.72 + elem[i].flags = Bytes::get_Java_u2(method_parameters_data); 1.73 + method_parameters_data += 2; 1.74 + } 1.75 } 1.76 } 1.77
2.1 --- a/src/share/vm/oops/constMethod.hpp Mon Feb 04 08:26:02 2013 -0500 2.2 +++ b/src/share/vm/oops/constMethod.hpp Mon Feb 04 13:51:01 2013 -0800 2.3 @@ -122,12 +122,7 @@ 2.4 class MethodParametersElement VALUE_OBJ_CLASS_SPEC { 2.5 public: 2.6 u2 name_cp_index; 2.7 - // This has to happen, otherwise it will cause SIGBUS from a 2.8 - // misaligned u4 on some architectures (ie SPARC) 2.9 - // because MethodParametersElements are only aligned mod 2 2.10 - // within the ConstMethod container u2 flags_hi; 2.11 - u2 flags_hi; 2.12 - u2 flags_lo; 2.13 + u2 flags; 2.14 }; 2.15 2.16 class KlassSizeStats;
3.1 --- a/src/share/vm/prims/jvm.cpp Mon Feb 04 08:26:02 2013 -0500 3.2 +++ b/src/share/vm/prims/jvm.cpp Mon Feb 04 13:51:01 2013 -0800 3.3 @@ -1620,7 +1620,7 @@ 3.4 // For a 0 index, give a NULL symbol 3.5 Symbol* const sym = 0 != params[i].name_cp_index ? 3.6 mh->constants()->symbol_at(params[i].name_cp_index) : NULL; 3.7 - int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi); 3.8 + int flags = params[i].flags; 3.9 oop param = Reflection::new_parameter(reflected_method, i, sym, 3.10 flags, CHECK_NULL); 3.11 result->obj_at_put(i, param);