src/share/vm/oops/constMethod.cpp

Tue, 06 Nov 2012 15:09:37 -0500

author
coleenp
date
Tue, 06 Nov 2012 15:09:37 -0500
changeset 4251
18fb7da42534
parent 4245
4735d2c84362
child 4302
b2dbd323c668
permissions
-rw-r--r--

8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
Summary: Change types of above methods and field to InstanceKlass and remove unneeded casts from the source files.
Reviewed-by: dholmes, coleenp, zgu
Contributed-by: harold.seigel@oracle.com

     1 /*
     2  * Copyright (c) 2003, 2012, 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/metadataFactory.hpp"
    29 #include "oops/constMethod.hpp"
    30 #include "oops/method.hpp"
    32 // Static initialization
    33 const u2 ConstMethod::MAX_IDNUM   = 0xFFFE;
    34 const u2 ConstMethod::UNSET_IDNUM = 0xFFFF;
    36 ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
    37                                    int byte_code_size,
    38                                    int compressed_line_number_size,
    39                                    int localvariable_table_length,
    40                                    int exception_table_length,
    41                                    int checked_exceptions_length,
    42                                    MethodType method_type,
    43                                    TRAPS) {
    44   int size = ConstMethod::size(byte_code_size,
    45                                       compressed_line_number_size,
    46                                       localvariable_table_length,
    47                                       exception_table_length,
    48                                       checked_exceptions_length);
    49   return new (loader_data, size, true, THREAD) ConstMethod(
    50       byte_code_size, compressed_line_number_size, localvariable_table_length,
    51       exception_table_length, checked_exceptions_length, method_type, size);
    52 }
    54 ConstMethod::ConstMethod(int byte_code_size,
    55                          int compressed_line_number_size,
    56                          int localvariable_table_length,
    57                          int exception_table_length,
    58                          int checked_exceptions_length,
    59                          MethodType method_type,
    60                          int size) {
    62   No_Safepoint_Verifier no_safepoint;
    63   set_interpreter_kind(Interpreter::invalid);
    64   init_fingerprint();
    65   set_constants(NULL);
    66   set_stackmap_data(NULL);
    67   set_code_size(byte_code_size);
    68   set_constMethod_size(size);
    69   set_inlined_tables_length(checked_exceptions_length,
    70                             compressed_line_number_size,
    71                             localvariable_table_length,
    72                             exception_table_length);
    73   set_method_type(method_type);
    74   assert(this->size() == size, "wrong size for object");
    75 }
    78 // Deallocate metadata fields associated with ConstMethod*
    79 void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) {
    80   set_interpreter_kind(Interpreter::invalid);
    81   if (stackmap_data() != NULL) {
    82     MetadataFactory::free_array<u1>(loader_data, stackmap_data());
    83   }
    84   set_stackmap_data(NULL);
    85 }
    87 // How big must this constMethodObject be?
    89 int ConstMethod::size(int code_size,
    90                                     int compressed_line_number_size,
    91                                     int local_variable_table_length,
    92                                     int exception_table_length,
    93                                     int checked_exceptions_length) {
    94   int extra_bytes = code_size;
    95   if (compressed_line_number_size > 0) {
    96     extra_bytes += compressed_line_number_size;
    97   }
    98   if (checked_exceptions_length > 0) {
    99     extra_bytes += sizeof(u2);
   100     extra_bytes += checked_exceptions_length * sizeof(CheckedExceptionElement);
   101   }
   102   if (local_variable_table_length > 0) {
   103     extra_bytes += sizeof(u2);
   104     extra_bytes +=
   105               local_variable_table_length * sizeof(LocalVariableTableElement);
   106   }
   107   if (exception_table_length > 0) {
   108     extra_bytes += sizeof(u2);
   109     extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
   110   }
   111   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
   112   return align_object_size(header_size() + extra_words);
   113 }
   115 Method* ConstMethod::method() const {
   116     return _constants->pool_holder()->method_with_idnum(_method_idnum);
   117   }
   119 // linenumber table - note that length is unknown until decompression,
   120 // see class CompressedLineNumberReadStream.
   122 u_char* ConstMethod::compressed_linenumber_table() const {
   123   // Located immediately following the bytecodes.
   124   assert(has_linenumber_table(), "called only if table is present");
   125   return code_end();
   126 }
   128 u2* ConstMethod::checked_exceptions_length_addr() const {
   129   // Located at the end of the constMethod.
   130   assert(has_checked_exceptions(), "called only if table is present");
   131   return last_u2_element();
   132 }
   134 u2* ConstMethod::exception_table_length_addr() const {
   135   assert(has_exception_handler(), "called only if table is present");
   136   if (has_checked_exceptions()) {
   137     // If checked_exception present, locate immediately before them.
   138     return (u2*) checked_exceptions_start() - 1;
   139   } else {
   140     // Else, the exception table is at the end of the constMethod.
   141     return last_u2_element();
   142   }
   143 }
   145 u2* ConstMethod::localvariable_table_length_addr() const {
   146   assert(has_localvariable_table(), "called only if table is present");
   147   if (has_exception_handler()) {
   148     // If exception_table present, locate immediately before them.
   149     return (u2*) exception_table_start() - 1;
   150   } else {
   151     if (has_checked_exceptions()) {
   152       // If checked_exception present, locate immediately before them.
   153       return (u2*) checked_exceptions_start() - 1;
   154     } else {
   155       // Else, the linenumber table is at the end of the constMethod.
   156       return last_u2_element();
   157     }
   158   }
   159 }
   162 // Update the flags to indicate the presence of these optional fields.
   163 void ConstMethod::set_inlined_tables_length(
   164                                               int checked_exceptions_len,
   165                                               int compressed_line_number_size,
   166                                               int localvariable_table_len,
   167                                               int exception_table_len) {
   168   // Must be done in the order below, otherwise length_addr accessors
   169   // will not work. Only set bit in header if length is positive.
   170   assert(_flags == 0, "Error");
   171   if (compressed_line_number_size > 0) {
   172     _flags |= _has_linenumber_table;
   173   }
   174   if (checked_exceptions_len > 0) {
   175     _flags |= _has_checked_exceptions;
   176     *(checked_exceptions_length_addr()) = checked_exceptions_len;
   177   }
   178   if (exception_table_len > 0) {
   179     _flags |= _has_exception_table;
   180     *(exception_table_length_addr()) = exception_table_len;
   181   }
   182   if (localvariable_table_len > 0) {
   183     _flags |= _has_localvariable_table;
   184     *(localvariable_table_length_addr()) = localvariable_table_len;
   185   }
   186 }
   189 int ConstMethod::checked_exceptions_length() const {
   190   return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0;
   191 }
   194 CheckedExceptionElement* ConstMethod::checked_exceptions_start() const {
   195   u2* addr = checked_exceptions_length_addr();
   196   u2 length = *addr;
   197   assert(length > 0, "should only be called if table is present");
   198   addr -= length * sizeof(CheckedExceptionElement) / sizeof(u2);
   199   return (CheckedExceptionElement*) addr;
   200 }
   203 int ConstMethod::localvariable_table_length() const {
   204   return has_localvariable_table() ? *(localvariable_table_length_addr()) : 0;
   205 }
   208 LocalVariableTableElement* ConstMethod::localvariable_table_start() const {
   209   u2* addr = localvariable_table_length_addr();
   210   u2 length = *addr;
   211   assert(length > 0, "should only be called if table is present");
   212   addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2);
   213   return (LocalVariableTableElement*) addr;
   214 }
   216 int ConstMethod::exception_table_length() const {
   217   return has_exception_handler() ? *(exception_table_length_addr()) : 0;
   218 }
   220 ExceptionTableElement* ConstMethod::exception_table_start() const {
   221   u2* addr = exception_table_length_addr();
   222   u2 length = *addr;
   223   assert(length > 0, "should only be called if table is present");
   224   addr -= length * sizeof(ExceptionTableElement) / sizeof(u2);
   225   return (ExceptionTableElement*)addr;
   226 }
   229 // Printing
   231 void ConstMethod::print_on(outputStream* st) const {
   232   ResourceMark rm;
   233   assert(is_constMethod(), "must be constMethod");
   234   st->print_cr(internal_name());
   235   st->print(" - method:       " INTPTR_FORMAT " ", (address)method());
   236   method()->print_value_on(st); st->cr();
   237   if (has_stackmap_table()) {
   238     st->print(" - stackmap data:       ");
   239     stackmap_data()->print_value_on(st);
   240     st->cr();
   241   }
   242 }
   244 // Short version of printing ConstMethod* - just print the name of the
   245 // method it belongs to.
   246 void ConstMethod::print_value_on(outputStream* st) const {
   247   assert(is_constMethod(), "must be constMethod");
   248   st->print(" const part of method " );
   249   method()->print_value_on(st);
   250 }
   253 // Verification
   255 void ConstMethod::verify_on(outputStream* st) {
   256   guarantee(is_constMethod(), "object must be constMethod");
   257   guarantee(is_metadata(), err_msg("Should be metadata " PTR_FORMAT, this));
   259   // Verification can occur during oop construction before the method or
   260   // other fields have been initialized.
   261   guarantee(is_metadata(), err_msg("Should be metadata " PTR_FORMAT, this));
   262   guarantee(method()->is_method(), "should be method");
   264   address m_end = (address)((oop*) this + size());
   265   address compressed_table_start = code_end();
   266   guarantee(compressed_table_start <= m_end, "invalid method layout");
   267   address compressed_table_end = compressed_table_start;
   268   // Verify line number table
   269   if (has_linenumber_table()) {
   270     CompressedLineNumberReadStream stream(compressed_linenumber_table());
   271     while (stream.read_pair()) {
   272       guarantee(stream.bci() >= 0 && stream.bci() <= code_size(), "invalid bci in line number table");
   273     }
   274     compressed_table_end += stream.position();
   275   }
   276   guarantee(compressed_table_end <= m_end, "invalid method layout");
   277   // Verify checked exceptions, exception table and local variable tables
   278   if (has_checked_exceptions()) {
   279     u2* addr = checked_exceptions_length_addr();
   280     guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   281   }
   282   if (has_exception_handler()) {
   283     u2* addr = exception_table_length_addr();
   284      guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   285   }
   286   if (has_localvariable_table()) {
   287     u2* addr = localvariable_table_length_addr();
   288     guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   289   }
   290   // Check compressed_table_end relative to uncompressed_table_start
   291   u2* uncompressed_table_start;
   292   if (has_localvariable_table()) {
   293     uncompressed_table_start = (u2*) localvariable_table_start();
   294   } else if (has_exception_handler()) {
   295     uncompressed_table_start = (u2*) exception_table_start();
   296   } else if (has_checked_exceptions()) {
   297       uncompressed_table_start = (u2*) checked_exceptions_start();
   298   } else {
   299       uncompressed_table_start = (u2*) m_end;
   300   }
   301   int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
   302   int max_gap = align_object_size(1)*BytesPerWord;
   303   guarantee(gap >= 0 && gap < max_gap, "invalid method layout");
   304 }

mercurial