src/share/vm/oops/constMethod.cpp

Print this page
rev 7343 : 8058313: Mismatch of method descriptor and MethodParameters.parameters_count should cause MalformedParameterException
Summary: Allow hotspot to store and report zero-length MethodParameters attribute data
Reviewed-by: coleenp, jiangli


  99   int extra_bytes = code_size;
 100   if (sizes->compressed_linenumber_size() > 0) {
 101     extra_bytes += sizes->compressed_linenumber_size();
 102   }
 103   if (sizes->checked_exceptions_length() > 0) {
 104     extra_bytes += sizeof(u2);
 105     extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
 106   }
 107   if (sizes->localvariable_table_length() > 0) {
 108     extra_bytes += sizeof(u2);
 109     extra_bytes +=
 110               sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
 111   }
 112   if (sizes->exception_table_length() > 0) {
 113     extra_bytes += sizeof(u2);
 114     extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
 115   }
 116   if (sizes->generic_signature_index() != 0) {
 117     extra_bytes += sizeof(u2);
 118   }
 119   if (sizes->method_parameters_length() > 0) {




 120     extra_bytes += sizeof(u2);
 121     extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
 122   }
 123 
 124   // Align sizes up to a word.
 125   extra_bytes = align_size_up(extra_bytes, BytesPerWord);
 126 
 127   // One pointer per annotation array
 128   if (sizes->method_annotations_length() > 0) {
 129     extra_bytes += sizeof(AnnotationArray*);
 130   }
 131   if (sizes->parameter_annotations_length() > 0) {
 132     extra_bytes += sizeof(AnnotationArray*);
 133   }
 134   if (sizes->type_annotations_length() > 0) {
 135     extra_bytes += sizeof(AnnotationArray*);
 136   }
 137   if (sizes->default_annotations_length() > 0) {
 138     extra_bytes += sizeof(AnnotationArray*);
 139   }


 220     } else {
 221       if(has_method_parameters()) {
 222         // If method parameters present, locate immediately before them.
 223         return (u2*)method_parameters_start() - 1;
 224       } else {
 225         // Else, the exception table is at the end of the constMethod.
 226       return has_generic_signature() ? (last_u2_element() - 1) :
 227                                         last_u2_element();
 228       }
 229     }
 230   }
 231 }
 232 
 233 // Update the flags to indicate the presence of these optional fields.
 234 void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
 235   _flags = 0;
 236   if (sizes->compressed_linenumber_size() > 0)
 237     _flags |= _has_linenumber_table;
 238   if (sizes->generic_signature_index() != 0)
 239     _flags |= _has_generic_signature;
 240   if (sizes->method_parameters_length() > 0)
 241     _flags |= _has_method_parameters;
 242   if (sizes->checked_exceptions_length() > 0)
 243     _flags |= _has_checked_exceptions;
 244   if (sizes->exception_table_length() > 0)
 245     _flags |= _has_exception_table;
 246   if (sizes->localvariable_table_length() > 0)
 247     _flags |= _has_localvariable_table;
 248 
 249   // annotations, they are all pointer sized embedded objects so don't have
 250   // a length embedded also.
 251   if (sizes->method_annotations_length() > 0)
 252     _flags |= _has_method_annotations;
 253   if (sizes->parameter_annotations_length() > 0)
 254     _flags |= _has_parameter_annotations;
 255   if (sizes->type_annotations_length() > 0)
 256     _flags |= _has_type_annotations;
 257   if (sizes->default_annotations_length() > 0)
 258     _flags |= _has_default_annotations;
 259 
 260   // This code is extremely brittle and should possibly be revised.
 261   // The *_length_addr functions walk backwards through the
 262   // constMethod data, using each of the length indexes ahead of them,
 263   // as well as the flags variable.  Therefore, the indexes must be
 264   // initialized in reverse order, or else they will compute the wrong
 265   // offsets.  Moving the initialization of _flags into a separate
 266   // block solves *half* of the problem, but the following part will
 267   // still break if the order is not exactly right.
 268   //
 269   // Also, the servicability agent needs to be informed anytime
 270   // anything is added here.  It might be advisable to have some sort
 271   // of indication of this inline.
 272   if (sizes->generic_signature_index() != 0)
 273     *(generic_signature_index_addr()) = sizes->generic_signature_index();
 274   // New data should probably go here.
 275   if (sizes->method_parameters_length() > 0)
 276     *(method_parameters_length_addr()) = sizes->method_parameters_length();
 277   if (sizes->checked_exceptions_length() > 0)
 278     *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
 279   if (sizes->exception_table_length() > 0)
 280     *(exception_table_length_addr()) = sizes->exception_table_length();
 281   if (sizes->localvariable_table_length() > 0)
 282     *(localvariable_table_length_addr()) = sizes->localvariable_table_length();
 283 }
 284 
 285 int ConstMethod::method_parameters_length() const {
 286   return has_method_parameters() ? *(method_parameters_length_addr()) : 0;
 287 }
 288 
 289 MethodParametersElement* ConstMethod::method_parameters_start() const {
 290   u2* addr = method_parameters_length_addr();
 291   u2 length = *addr;
 292   assert(length > 0, "should only be called if table is present");
 293   addr -= length * sizeof(MethodParametersElement) / sizeof(u2);
 294   return (MethodParametersElement*) addr;
 295 }
 296 
 297 
 298 int ConstMethod::checked_exceptions_length() const {
 299   return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0;
 300 }
 301 
 302 
 303 CheckedExceptionElement* ConstMethod::checked_exceptions_start() const {
 304   u2* addr = checked_exceptions_length_addr();
 305   u2 length = *addr;
 306   assert(length > 0, "should only be called if table is present");




  99   int extra_bytes = code_size;
 100   if (sizes->compressed_linenumber_size() > 0) {
 101     extra_bytes += sizes->compressed_linenumber_size();
 102   }
 103   if (sizes->checked_exceptions_length() > 0) {
 104     extra_bytes += sizeof(u2);
 105     extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
 106   }
 107   if (sizes->localvariable_table_length() > 0) {
 108     extra_bytes += sizeof(u2);
 109     extra_bytes +=
 110               sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
 111   }
 112   if (sizes->exception_table_length() > 0) {
 113     extra_bytes += sizeof(u2);
 114     extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
 115   }
 116   if (sizes->generic_signature_index() != 0) {
 117     extra_bytes += sizeof(u2);
 118   }
 119   // This has to be a less-than-or-equal check, because we might be
 120   // storing information from a zero-length MethodParameters
 121   // attribute.  We have to store these, because in some cases, they
 122   // cause the reflection API to throw a MalformedParametersException.
 123   if (sizes->method_parameters_length() >= 0) {
 124     extra_bytes += sizeof(u2);
 125     extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
 126   }
 127 
 128   // Align sizes up to a word.
 129   extra_bytes = align_size_up(extra_bytes, BytesPerWord);
 130 
 131   // One pointer per annotation array
 132   if (sizes->method_annotations_length() > 0) {
 133     extra_bytes += sizeof(AnnotationArray*);
 134   }
 135   if (sizes->parameter_annotations_length() > 0) {
 136     extra_bytes += sizeof(AnnotationArray*);
 137   }
 138   if (sizes->type_annotations_length() > 0) {
 139     extra_bytes += sizeof(AnnotationArray*);
 140   }
 141   if (sizes->default_annotations_length() > 0) {
 142     extra_bytes += sizeof(AnnotationArray*);
 143   }


 224     } else {
 225       if(has_method_parameters()) {
 226         // If method parameters present, locate immediately before them.
 227         return (u2*)method_parameters_start() - 1;
 228       } else {
 229         // Else, the exception table is at the end of the constMethod.
 230       return has_generic_signature() ? (last_u2_element() - 1) :
 231                                         last_u2_element();
 232       }
 233     }
 234   }
 235 }
 236 
 237 // Update the flags to indicate the presence of these optional fields.
 238 void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
 239   _flags = 0;
 240   if (sizes->compressed_linenumber_size() > 0)
 241     _flags |= _has_linenumber_table;
 242   if (sizes->generic_signature_index() != 0)
 243     _flags |= _has_generic_signature;
 244   if (sizes->method_parameters_length() >= 0)
 245     _flags |= _has_method_parameters;
 246   if (sizes->checked_exceptions_length() > 0)
 247     _flags |= _has_checked_exceptions;
 248   if (sizes->exception_table_length() > 0)
 249     _flags |= _has_exception_table;
 250   if (sizes->localvariable_table_length() > 0)
 251     _flags |= _has_localvariable_table;
 252 
 253   // annotations, they are all pointer sized embedded objects so don't have
 254   // a length embedded also.
 255   if (sizes->method_annotations_length() > 0)
 256     _flags |= _has_method_annotations;
 257   if (sizes->parameter_annotations_length() > 0)
 258     _flags |= _has_parameter_annotations;
 259   if (sizes->type_annotations_length() > 0)
 260     _flags |= _has_type_annotations;
 261   if (sizes->default_annotations_length() > 0)
 262     _flags |= _has_default_annotations;
 263 
 264   // This code is extremely brittle and should possibly be revised.
 265   // The *_length_addr functions walk backwards through the
 266   // constMethod data, using each of the length indexes ahead of them,
 267   // as well as the flags variable.  Therefore, the indexes must be
 268   // initialized in reverse order, or else they will compute the wrong
 269   // offsets.  Moving the initialization of _flags into a separate
 270   // block solves *half* of the problem, but the following part will
 271   // still break if the order is not exactly right.
 272   //
 273   // Also, the servicability agent needs to be informed anytime
 274   // anything is added here.  It might be advisable to have some sort
 275   // of indication of this inline.
 276   if (sizes->generic_signature_index() != 0)
 277     *(generic_signature_index_addr()) = sizes->generic_signature_index();
 278   // New data should probably go here.
 279   if (sizes->method_parameters_length() >= 0)
 280     *(method_parameters_length_addr()) = sizes->method_parameters_length();
 281   if (sizes->checked_exceptions_length() > 0)
 282     *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
 283   if (sizes->exception_table_length() > 0)
 284     *(exception_table_length_addr()) = sizes->exception_table_length();
 285   if (sizes->localvariable_table_length() > 0)
 286     *(localvariable_table_length_addr()) = sizes->localvariable_table_length();
 287 }
 288 
 289 int ConstMethod::method_parameters_length() const {
 290   return has_method_parameters() ? *(method_parameters_length_addr()) : -1;
 291 }
 292 
 293 MethodParametersElement* ConstMethod::method_parameters_start() const {
 294   u2* addr = method_parameters_length_addr();
 295   u2 length = *addr;
 296   assert(length > 0, "should only be called if table is present");
 297   addr -= length * sizeof(MethodParametersElement) / sizeof(u2);
 298   return (MethodParametersElement*) addr;
 299 }
 300 
 301 
 302 int ConstMethod::checked_exceptions_length() const {
 303   return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0;
 304 }
 305 
 306 
 307 CheckedExceptionElement* ConstMethod::checked_exceptions_start() const {
 308   u2* addr = checked_exceptions_length_addr();
 309   u2 length = *addr;
 310   assert(length > 0, "should only be called if table is present");