src/share/vm/oops/constMethod.cpp

Fri, 08 Mar 2013 11:47:57 -0500

author
coleenp
date
Fri, 08 Mar 2013 11:47:57 -0500
changeset 4712
3efdfd6ddbf2
parent 4572
927a311d00f9
child 4715
5939f5953b45
permissions
-rw-r--r--

8003553: NPG: metaspace objects should be zeroed in constructors
Summary: Zero metadata in constructors, not in allocation (and some in constructors)
Reviewed-by: jmasa, sspitsyn

     1 /*
     2  * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "interpreter/interpreter.hpp"
    27 #include "memory/gcLocker.hpp"
    28 #include "memory/heapInspection.hpp"
    29 #include "memory/metadataFactory.hpp"
    30 #include "oops/constMethod.hpp"
    31 #include "oops/method.hpp"
    33 // Static initialization
    34 const u2 ConstMethod::MAX_IDNUM   = 0xFFFE;
    35 const u2 ConstMethod::UNSET_IDNUM = 0xFFFF;
    37 ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
    38                                    int byte_code_size,
    39                                    InlineTableSizes* sizes,
    40                                    MethodType method_type,
    41                                    TRAPS) {
    42   int size = ConstMethod::size(byte_code_size, sizes);
    43   return new (loader_data, size, true, THREAD) ConstMethod(
    44       byte_code_size, sizes, method_type, size);
    45 }
    47 ConstMethod::ConstMethod(int byte_code_size,
    48                          InlineTableSizes* sizes,
    49                          MethodType method_type,
    50                          int size) {
    52   No_Safepoint_Verifier no_safepoint;
    53   init_fingerprint();
    54   set_constants(NULL);
    55   set_stackmap_data(NULL);
    56   set_code_size(byte_code_size);
    57   set_constMethod_size(size);
    58   set_inlined_tables_length(sizes);
    59   set_method_type(method_type);
    60   assert(this->size() == size, "wrong size for object");
    61   set_name_index(0);
    62   set_signature_index(0);
    63   set_constants(NULL);
    64   set_max_stack(0);
    65   set_max_locals(0);
    66   set_method_idnum(0);
    67 }
    70 // Deallocate metadata fields associated with ConstMethod*
    71 void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
    72   if (stackmap_data() != NULL) {
    73     MetadataFactory::free_array<u1>(loader_data, stackmap_data());
    74   }
    75   set_stackmap_data(NULL);
    77   // deallocate annotation arrays
    78   if (has_method_annotations())
    79     MetadataFactory::free_array<u1>(loader_data, method_annotations());
    80   if (has_parameter_annotations())
    81     MetadataFactory::free_array<u1>(loader_data, parameter_annotations());
    82   if (has_type_annotations())
    83     MetadataFactory::free_array<u1>(loader_data, type_annotations());
    84   if (has_default_annotations())
    85     MetadataFactory::free_array<u1>(loader_data, default_annotations());
    86 }
    88 // How big must this constMethodObject be?
    90 int ConstMethod::size(int code_size,
    91                       InlineTableSizes* sizes) {
    92   int extra_bytes = code_size;
    93   if (sizes->compressed_linenumber_size() > 0) {
    94     extra_bytes += sizes->compressed_linenumber_size();
    95   }
    96   if (sizes->checked_exceptions_length() > 0) {
    97     extra_bytes += sizeof(u2);
    98     extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement);
    99   }
   100   if (sizes->localvariable_table_length() > 0) {
   101     extra_bytes += sizeof(u2);
   102     extra_bytes +=
   103               sizes->localvariable_table_length() * sizeof(LocalVariableTableElement);
   104   }
   105   if (sizes->exception_table_length() > 0) {
   106     extra_bytes += sizeof(u2);
   107     extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement);
   108   }
   109   if (sizes->generic_signature_index() != 0) {
   110     extra_bytes += sizeof(u2);
   111   }
   112   if (sizes->method_parameters_length() > 0) {
   113     extra_bytes += sizeof(u2);
   114     extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
   115   }
   117   // Align sizes up to a word.
   118   extra_bytes = align_size_up(extra_bytes, BytesPerWord);
   120   // One pointer per annotation array
   121   if (sizes->method_annotations_length() > 0) {
   122     extra_bytes += sizeof(AnnotationArray*);
   123   }
   124   if (sizes->parameter_annotations_length() > 0) {
   125     extra_bytes += sizeof(AnnotationArray*);
   126   }
   127   if (sizes->type_annotations_length() > 0) {
   128     extra_bytes += sizeof(AnnotationArray*);
   129   }
   130   if (sizes->default_annotations_length() > 0) {
   131     extra_bytes += sizeof(AnnotationArray*);
   132   }
   134   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
   135   assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned");
   136   return align_object_size(header_size() + extra_words);
   137 }
   139 Method* ConstMethod::method() const {
   140     return _constants->pool_holder()->method_with_idnum(_method_idnum);
   141   }
   143 // linenumber table - note that length is unknown until decompression,
   144 // see class CompressedLineNumberReadStream.
   146 u_char* ConstMethod::compressed_linenumber_table() const {
   147   // Located immediately following the bytecodes.
   148   assert(has_linenumber_table(), "called only if table is present");
   149   return code_end();
   150 }
   152 // Last short in ConstMethod* before annotations
   153 u2* ConstMethod::last_u2_element() const {
   154   int offset = 0;
   155   if (has_method_annotations()) offset++;
   156   if (has_parameter_annotations()) offset++;
   157   if (has_type_annotations()) offset++;
   158   if (has_default_annotations()) offset++;
   159   return (u2*)((AnnotationArray**)constMethod_end() - offset) - 1;
   160 }
   162 u2* ConstMethod::generic_signature_index_addr() const {
   163   // Located at the end of the constMethod.
   164   assert(has_generic_signature(), "called only if generic signature exists");
   165   return last_u2_element();
   166 }
   168 u2* ConstMethod::method_parameters_length_addr() const {
   169   assert(has_method_parameters(), "called only if table is present");
   170   return has_generic_signature() ? (last_u2_element() - 1) :
   171                                     last_u2_element();
   172 }
   174 u2* ConstMethod::checked_exceptions_length_addr() const {
   175   // Located immediately before the generic signature index.
   176   assert(has_checked_exceptions(), "called only if table is present");
   177   if(has_method_parameters()) {
   178     // If method parameters present, locate immediately before them.
   179     return (u2*)method_parameters_start() - 1;
   180   } else {
   181     // Else, the exception table is at the end of the constMethod.
   182     return has_generic_signature() ? (last_u2_element() - 1) :
   183                                      last_u2_element();
   184   }
   185 }
   187 u2* ConstMethod::exception_table_length_addr() const {
   188   assert(has_exception_handler(), "called only if table is present");
   189   if (has_checked_exceptions()) {
   190     // If checked_exception present, locate immediately before them.
   191     return (u2*) checked_exceptions_start() - 1;
   192   } else {
   193     if(has_method_parameters()) {
   194       // If method parameters present, locate immediately before them.
   195       return (u2*)method_parameters_start() - 1;
   196     } else {
   197       // Else, the exception table is at the end of the constMethod.
   198       return has_generic_signature() ? (last_u2_element() - 1) :
   199                                         last_u2_element();
   200     }
   201   }
   202 }
   204 u2* ConstMethod::localvariable_table_length_addr() const {
   205   assert(has_localvariable_table(), "called only if table is present");
   206   if (has_exception_handler()) {
   207     // If exception_table present, locate immediately before them.
   208     return (u2*) exception_table_start() - 1;
   209   } else {
   210     if (has_checked_exceptions()) {
   211       // If checked_exception present, locate immediately before them.
   212       return (u2*) checked_exceptions_start() - 1;
   213     } else {
   214       if(has_method_parameters()) {
   215         // If method parameters present, locate immediately before them.
   216         return (u2*)method_parameters_start() - 1;
   217       } else {
   218         // Else, the exception table is at the end of the constMethod.
   219       return has_generic_signature() ? (last_u2_element() - 1) :
   220                                         last_u2_element();
   221       }
   222     }
   223   }
   224 }
   226 // Update the flags to indicate the presence of these optional fields.
   227 void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
   228   _flags = 0;
   229   if (sizes->compressed_linenumber_size() > 0)
   230     _flags |= _has_linenumber_table;
   231   if (sizes->generic_signature_index() != 0)
   232     _flags |= _has_generic_signature;
   233   if (sizes->method_parameters_length() > 0)
   234     _flags |= _has_method_parameters;
   235   if (sizes->checked_exceptions_length() > 0)
   236     _flags |= _has_checked_exceptions;
   237   if (sizes->exception_table_length() > 0)
   238     _flags |= _has_exception_table;
   239   if (sizes->localvariable_table_length() > 0)
   240     _flags |= _has_localvariable_table;
   242   // annotations, they are all pointer sized embedded objects so don't have
   243   // a length embedded also.
   244   if (sizes->method_annotations_length() > 0)
   245     _flags |= _has_method_annotations;
   246   if (sizes->parameter_annotations_length() > 0)
   247     _flags |= _has_parameter_annotations;
   248   if (sizes->type_annotations_length() > 0)
   249     _flags |= _has_type_annotations;
   250   if (sizes->default_annotations_length() > 0)
   251     _flags |= _has_default_annotations;
   253   // This code is extremely brittle and should possibly be revised.
   254   // The *_length_addr functions walk backwards through the
   255   // constMethod data, using each of the length indexes ahead of them,
   256   // as well as the flags variable.  Therefore, the indexes must be
   257   // initialized in reverse order, or else they will compute the wrong
   258   // offsets.  Moving the initialization of _flags into a separate
   259   // block solves *half* of the problem, but the following part will
   260   // still break if the order is not exactly right.
   261   //
   262   // Also, the servicability agent needs to be informed anytime
   263   // anything is added here.  It might be advisable to have some sort
   264   // of indication of this inline.
   265   if (sizes->generic_signature_index() != 0)
   266     *(generic_signature_index_addr()) = sizes->generic_signature_index();
   267   // New data should probably go here.
   268   if (sizes->method_parameters_length() > 0)
   269     *(method_parameters_length_addr()) = sizes->method_parameters_length();
   270   if (sizes->checked_exceptions_length() > 0)
   271     *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
   272   if (sizes->exception_table_length() > 0)
   273     *(exception_table_length_addr()) = sizes->exception_table_length();
   274   if (sizes->localvariable_table_length() > 0)
   275     *(localvariable_table_length_addr()) = sizes->localvariable_table_length();
   276 }
   278 int ConstMethod::method_parameters_length() const {
   279   return has_method_parameters() ? *(method_parameters_length_addr()) : 0;
   280 }
   282 MethodParametersElement* ConstMethod::method_parameters_start() const {
   283   u2* addr = method_parameters_length_addr();
   284   u2 length = *addr;
   285   assert(length > 0, "should only be called if table is present");
   286   addr -= length * sizeof(MethodParametersElement) / sizeof(u2);
   287   return (MethodParametersElement*) addr;
   288 }
   291 int ConstMethod::checked_exceptions_length() const {
   292   return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0;
   293 }
   296 CheckedExceptionElement* ConstMethod::checked_exceptions_start() const {
   297   u2* addr = checked_exceptions_length_addr();
   298   u2 length = *addr;
   299   assert(length > 0, "should only be called if table is present");
   300   addr -= length * sizeof(CheckedExceptionElement) / sizeof(u2);
   301   return (CheckedExceptionElement*) addr;
   302 }
   305 int ConstMethod::localvariable_table_length() const {
   306   return has_localvariable_table() ? *(localvariable_table_length_addr()) : 0;
   307 }
   310 LocalVariableTableElement* ConstMethod::localvariable_table_start() const {
   311   u2* addr = localvariable_table_length_addr();
   312   u2 length = *addr;
   313   assert(length > 0, "should only be called if table is present");
   314   addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2);
   315   return (LocalVariableTableElement*) addr;
   316 }
   318 int ConstMethod::exception_table_length() const {
   319   return has_exception_handler() ? *(exception_table_length_addr()) : 0;
   320 }
   322 ExceptionTableElement* ConstMethod::exception_table_start() const {
   323   u2* addr = exception_table_length_addr();
   324   u2 length = *addr;
   325   assert(length > 0, "should only be called if table is present");
   326   addr -= length * sizeof(ExceptionTableElement) / sizeof(u2);
   327   return (ExceptionTableElement*)addr;
   328 }
   330 AnnotationArray** ConstMethod::method_annotations_addr() const {
   331   assert(has_method_annotations(), "should only be called if method annotations are present");
   332   return (AnnotationArray**)constMethod_end() - 1;
   333 }
   335 AnnotationArray** ConstMethod::parameter_annotations_addr() const {
   336   assert(has_parameter_annotations(), "should only be called if method parameter annotations are present");
   337   int offset = 1;
   338   if (has_method_annotations()) offset++;
   339   return (AnnotationArray**)constMethod_end() - offset;
   340 }
   342 AnnotationArray** ConstMethod::type_annotations_addr() const {
   343   assert(has_type_annotations(), "should only be called if method type annotations are present");
   344   int offset = 1;
   345   if (has_method_annotations()) offset++;
   346   if (has_parameter_annotations()) offset++;
   347   return (AnnotationArray**)constMethod_end() - offset;
   348 }
   350 AnnotationArray** ConstMethod::default_annotations_addr() const {
   351   assert(has_default_annotations(), "should only be called if method default annotations are present");
   352   int offset = 1;
   353   if (has_method_annotations()) offset++;
   354   if (has_parameter_annotations()) offset++;
   355   if (has_type_annotations()) offset++;
   356   return (AnnotationArray**)constMethod_end() - offset;
   357 }
   359 // Printing
   361 void ConstMethod::print_on(outputStream* st) const {
   362   ResourceMark rm;
   363   assert(is_constMethod(), "must be constMethod");
   364   st->print_cr(internal_name());
   365   st->print(" - method:       " INTPTR_FORMAT " ", (address)method());
   366   method()->print_value_on(st); st->cr();
   367   if (has_stackmap_table()) {
   368     st->print(" - stackmap data:       ");
   369     stackmap_data()->print_value_on(st);
   370     st->cr();
   371   }
   372 }
   374 // Short version of printing ConstMethod* - just print the name of the
   375 // method it belongs to.
   376 void ConstMethod::print_value_on(outputStream* st) const {
   377   assert(is_constMethod(), "must be constMethod");
   378   st->print(" const part of method " );
   379   method()->print_value_on(st);
   380 }
   382 #if INCLUDE_SERVICES
   383 // Size Statistics
   384 void ConstMethod::collect_statistics(KlassSizeStats *sz) const {
   385   int n1, n2, n3;
   386   sz->_const_method_bytes += (n1 = sz->count(this));
   387   sz->_bytecode_bytes     += (n2 = code_size());
   388   sz->_stackmap_bytes     += (n3 = sz->count_array(stackmap_data()));
   390   // Count method annotations
   391   int a1 = 0, a2 = 0, a3 = 0, a4 = 0;
   392   if (has_method_annotations()) {
   393     sz->_methods_annotations_bytes += (a1 = sz->count_array(method_annotations()));
   394   }
   395   if (has_parameter_annotations()) {
   396     sz->_methods_parameter_annotations_bytes += (a2 = sz->count_array(parameter_annotations()));
   397   }
   398   if (has_type_annotations()) {
   399     sz->_methods_type_annotations_bytes += (a3 = sz->count_array(type_annotations()));
   400   }
   401   if (has_default_annotations()) {
   402     sz->_methods_default_annotations_bytes += (a4 = sz->count_array(default_annotations()));
   403   }
   405   int size_annotations = a1 + a2 + a3 + a4;
   407   sz->_method_all_bytes += n1 + n3 + size_annotations; // note: n2 is part of n3
   408   sz->_ro_bytes += n1 + n3 + size_annotations;
   409 }
   410 #endif // INCLUDE_SERVICES
   412 // Verification
   414 void ConstMethod::verify_on(outputStream* st) {
   415   guarantee(is_constMethod(), "object must be constMethod");
   416   guarantee(is_metadata(), err_msg("Should be metadata " PTR_FORMAT, this));
   418   // Verification can occur during oop construction before the method or
   419   // other fields have been initialized.
   420   guarantee(method()->is_method(), "should be method");
   422   address m_end = (address)((intptr_t) this + size());
   423   address compressed_table_start = code_end();
   424   guarantee(compressed_table_start <= m_end, "invalid method layout");
   425   address compressed_table_end = compressed_table_start;
   426   // Verify line number table
   427   if (has_linenumber_table()) {
   428     CompressedLineNumberReadStream stream(compressed_linenumber_table());
   429     while (stream.read_pair()) {
   430       guarantee(stream.bci() >= 0 && stream.bci() <= code_size(), "invalid bci in line number table");
   431     }
   432     compressed_table_end += stream.position();
   433   }
   434   guarantee(compressed_table_end <= m_end, "invalid method layout");
   435   // Verify checked exceptions, exception table and local variable tables
   436   if (has_method_parameters()) {
   437     u2* addr = method_parameters_length_addr();
   438     guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   439   }
   440   if (has_checked_exceptions()) {
   441     u2* addr = checked_exceptions_length_addr();
   442     guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   443   }
   444   if (has_exception_handler()) {
   445     u2* addr = exception_table_length_addr();
   446      guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   447   }
   448   if (has_localvariable_table()) {
   449     u2* addr = localvariable_table_length_addr();
   450     guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   451   }
   452   // Check compressed_table_end relative to uncompressed_table_start
   453   u2* uncompressed_table_start;
   454   if (has_localvariable_table()) {
   455     uncompressed_table_start = (u2*) localvariable_table_start();
   456   } else if (has_exception_handler()) {
   457     uncompressed_table_start = (u2*) exception_table_start();
   458   } else if (has_checked_exceptions()) {
   459       uncompressed_table_start = (u2*) checked_exceptions_start();
   460   } else if (has_method_parameters()) {
   461       uncompressed_table_start = (u2*) method_parameters_start();
   462   } else {
   463       uncompressed_table_start = (u2*) m_end;
   464   }
   465   int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
   466   int max_gap = align_object_size(1)*BytesPerWord;
   467   guarantee(gap >= 0 && gap < max_gap, "invalid method layout");
   468 }

mercurial