--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Mon Feb 04 08:26:02 2013 -0500
+++ b/hotspot/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;
+ }
}
}
--- a/hotspot/src/share/vm/oops/constMethod.hpp Mon Feb 04 08:26:02 2013 -0500
+++ b/hotspot/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;
--- a/hotspot/src/share/vm/prims/jvm.cpp Mon Feb 04 08:26:02 2013 -0500
+++ b/hotspot/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);