src/share/vm/oops/constMethod.cpp

changeset 4398
ade95d680b42
parent 4302
b2dbd323c668
child 4497
16fb9f942703
     1.1 --- a/src/share/vm/oops/constMethod.cpp	Mon Jan 07 15:32:51 2013 -0500
     1.2 +++ b/src/share/vm/oops/constMethod.cpp	Tue Jan 08 14:01:36 2013 -0500
     1.3 @@ -39,18 +39,21 @@
     1.4                                     int localvariable_table_length,
     1.5                                     int exception_table_length,
     1.6                                     int checked_exceptions_length,
     1.7 +                                   int method_parameters_length,
     1.8                                     u2  generic_signature_index,
     1.9                                     MethodType method_type,
    1.10                                     TRAPS) {
    1.11    int size = ConstMethod::size(byte_code_size,
    1.12 -                                      compressed_line_number_size,
    1.13 -                                      localvariable_table_length,
    1.14 -                                      exception_table_length,
    1.15 -                                      checked_exceptions_length,
    1.16 -                                      generic_signature_index);
    1.17 +                               compressed_line_number_size,
    1.18 +                               localvariable_table_length,
    1.19 +                               exception_table_length,
    1.20 +                               checked_exceptions_length,
    1.21 +                               method_parameters_length,
    1.22 +                               generic_signature_index);
    1.23    return new (loader_data, size, true, THREAD) ConstMethod(
    1.24        byte_code_size, compressed_line_number_size, localvariable_table_length,
    1.25 -      exception_table_length, checked_exceptions_length, generic_signature_index,
    1.26 +      exception_table_length, checked_exceptions_length,
    1.27 +      method_parameters_length, generic_signature_index,
    1.28        method_type, size);
    1.29  }
    1.30  
    1.31 @@ -59,6 +62,7 @@
    1.32                           int localvariable_table_length,
    1.33                           int exception_table_length,
    1.34                           int checked_exceptions_length,
    1.35 +                         int method_parameters_length,
    1.36                           u2  generic_signature_index,
    1.37                           MethodType method_type,
    1.38                           int size) {
    1.39 @@ -74,7 +78,8 @@
    1.40                              checked_exceptions_length,
    1.41                              compressed_line_number_size,
    1.42                              localvariable_table_length,
    1.43 -                            exception_table_length);
    1.44 +                            exception_table_length,
    1.45 +                            method_parameters_length);
    1.46    set_method_type(method_type);
    1.47    assert(this->size() == size, "wrong size for object");
    1.48  }
    1.49 @@ -92,11 +97,12 @@
    1.50  // How big must this constMethodObject be?
    1.51  
    1.52  int ConstMethod::size(int code_size,
    1.53 -                                    int compressed_line_number_size,
    1.54 -                                    int local_variable_table_length,
    1.55 -                                    int exception_table_length,
    1.56 -                                    int checked_exceptions_length,
    1.57 -                                    u2  generic_signature_index) {
    1.58 +                      int compressed_line_number_size,
    1.59 +                      int local_variable_table_length,
    1.60 +                      int exception_table_length,
    1.61 +                      int checked_exceptions_length,
    1.62 +                      int method_parameters_length,
    1.63 +                      u2  generic_signature_index) {
    1.64    int extra_bytes = code_size;
    1.65    if (compressed_line_number_size > 0) {
    1.66      extra_bytes += compressed_line_number_size;
    1.67 @@ -117,6 +123,10 @@
    1.68    if (generic_signature_index != 0) {
    1.69      extra_bytes += sizeof(u2);
    1.70    }
    1.71 +  if (method_parameters_length > 0) {
    1.72 +    extra_bytes += sizeof(u2);
    1.73 +    extra_bytes += method_parameters_length * sizeof(MethodParametersElement);
    1.74 +  }
    1.75    int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
    1.76    return align_object_size(header_size() + extra_words);
    1.77  }
    1.78 @@ -143,6 +153,18 @@
    1.79  u2* ConstMethod::checked_exceptions_length_addr() const {
    1.80    // Located immediately before the generic signature index.
    1.81    assert(has_checked_exceptions(), "called only if table is present");
    1.82 +  if(has_method_parameters()) {
    1.83 +    // If method parameters present, locate immediately before them.
    1.84 +    return (u2*)method_parameters_start() - 1;
    1.85 +  } else {
    1.86 +    // Else, the exception table is at the end of the constMethod.
    1.87 +    return has_generic_signature() ? (last_u2_element() - 1) :
    1.88 +                                     last_u2_element();
    1.89 +  }
    1.90 +}
    1.91 +
    1.92 +u2* ConstMethod::method_parameters_length_addr() const {
    1.93 +  assert(has_method_parameters(), "called only if table is present");
    1.94    return has_generic_signature() ? (last_u2_element() - 1) :
    1.95                                      last_u2_element();
    1.96  }
    1.97 @@ -153,11 +175,15 @@
    1.98      // If checked_exception present, locate immediately before them.
    1.99      return (u2*) checked_exceptions_start() - 1;
   1.100    } else {
   1.101 -    // Else, the exception table is at the end of the constMethod or
   1.102 -    // immediately before the generic signature index.
   1.103 +    if(has_method_parameters()) {
   1.104 +      // If method parameters present, locate immediately before them.
   1.105 +      return (u2*)method_parameters_start() - 1;
   1.106 +    } else {
   1.107 +      // Else, the exception table is at the end of the constMethod.
   1.108      return has_generic_signature() ? (last_u2_element() - 1) :
   1.109                                        last_u2_element();
   1.110    }
   1.111 +  }
   1.112  }
   1.113  
   1.114  u2* ConstMethod::localvariable_table_length_addr() const {
   1.115 @@ -170,12 +196,16 @@
   1.116        // If checked_exception present, locate immediately before them.
   1.117        return (u2*) checked_exceptions_start() - 1;
   1.118      } else {
   1.119 -      // Else, the linenumber table is at the end of the constMethod or
   1.120 -      // immediately before the generic signature index.
   1.121 +      if(has_method_parameters()) {
   1.122 +        // If method parameters present, locate immediately before them.
   1.123 +        return (u2*)method_parameters_start() - 1;
   1.124 +      } else {
   1.125 +        // Else, the exception table is at the end of the constMethod.
   1.126        return has_generic_signature() ? (last_u2_element() - 1) :
   1.127                                          last_u2_element();
   1.128      }
   1.129    }
   1.130 +  }
   1.131  }
   1.132  
   1.133  // Update the flags to indicate the presence of these optional fields.
   1.134 @@ -183,29 +213,57 @@
   1.135                                              int checked_exceptions_len,
   1.136                                              int compressed_line_number_size,
   1.137                                              int localvariable_table_len,
   1.138 -                                            int exception_table_len) {
   1.139 -  // Must be done in the order below, otherwise length_addr accessors
   1.140 -  // will not work. Only set bit in header if length is positive.
   1.141 +                                            int exception_table_len,
   1.142 +                                            int method_parameters_len) {
   1.143    assert(_flags == 0, "Error");
   1.144 -  if (compressed_line_number_size > 0) {
   1.145 +  if (compressed_line_number_size > 0)
   1.146      _flags |= _has_linenumber_table;
   1.147 -  }
   1.148 -  if (generic_signature_index != 0) {
   1.149 +  if (generic_signature_index != 0)
   1.150      _flags |= _has_generic_signature;
   1.151 +  if (method_parameters_len > 0)
   1.152 +    _flags |= _has_method_parameters;
   1.153 +  if (checked_exceptions_len > 0)
   1.154 +    _flags |= _has_checked_exceptions;
   1.155 +  if (exception_table_len > 0)
   1.156 +    _flags |= _has_exception_table;
   1.157 +  if (localvariable_table_len > 0)
   1.158 +    _flags |= _has_localvariable_table;
   1.159 +
   1.160 +  // This code is extremely brittle and should possibly be revised.
   1.161 +  // The *_length_addr functions walk backwards through the
   1.162 +  // constMethod data, using each of the length indexes ahead of them,
   1.163 +  // as well as the flags variable.  Therefore, the indexes must be
   1.164 +  // initialized in reverse order, or else they will compute the wrong
   1.165 +  // offsets.  Moving the initialization of _flags into a separate
   1.166 +  // block solves *half* of the problem, but the following part will
   1.167 +  // still break if the order is not exactly right.
   1.168 +  //
   1.169 +  // Also, the servicability agent needs to be informed anytime
   1.170 +  // anything is added here.  It might be advisable to have some sort
   1.171 +  // of indication of this inline.
   1.172 +  if (generic_signature_index != 0)
   1.173      *(generic_signature_index_addr()) = generic_signature_index;
   1.174 -  }
   1.175 -  if (checked_exceptions_len > 0) {
   1.176 -    _flags |= _has_checked_exceptions;
   1.177 +  // New data should probably go here.
   1.178 +  if (method_parameters_len > 0)
   1.179 +    *(method_parameters_length_addr()) = method_parameters_len;
   1.180 +  if (checked_exceptions_len > 0)
   1.181      *(checked_exceptions_length_addr()) = checked_exceptions_len;
   1.182 -  }
   1.183 -  if (exception_table_len > 0) {
   1.184 -    _flags |= _has_exception_table;
   1.185 +  if (exception_table_len > 0)
   1.186      *(exception_table_length_addr()) = exception_table_len;
   1.187 -  }
   1.188 -  if (localvariable_table_len > 0) {
   1.189 -    _flags |= _has_localvariable_table;
   1.190 +  if (localvariable_table_len > 0)
   1.191      *(localvariable_table_length_addr()) = localvariable_table_len;
   1.192 -  }
   1.193 +}
   1.194 +
   1.195 +int ConstMethod::method_parameters_length() const {
   1.196 +  return has_method_parameters() ? *(method_parameters_length_addr()) : 0;
   1.197 +}
   1.198 +
   1.199 +MethodParametersElement* ConstMethod::method_parameters_start() const {
   1.200 +  u2* addr = method_parameters_length_addr();
   1.201 +  u2 length = *addr;
   1.202 +  assert(length > 0, "should only be called if table is present");
   1.203 +  addr -= length * sizeof(MethodParametersElement) / sizeof(u2);
   1.204 +  return (MethodParametersElement*) addr;
   1.205  }
   1.206  
   1.207  
   1.208 @@ -298,6 +356,10 @@
   1.209    }
   1.210    guarantee(compressed_table_end <= m_end, "invalid method layout");
   1.211    // Verify checked exceptions, exception table and local variable tables
   1.212 +  if (has_method_parameters()) {
   1.213 +    u2* addr = method_parameters_length_addr();
   1.214 +    guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   1.215 +  }
   1.216    if (has_checked_exceptions()) {
   1.217      u2* addr = checked_exceptions_length_addr();
   1.218      guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
   1.219 @@ -318,6 +380,8 @@
   1.220      uncompressed_table_start = (u2*) exception_table_start();
   1.221    } else if (has_checked_exceptions()) {
   1.222        uncompressed_table_start = (u2*) checked_exceptions_start();
   1.223 +  } else if (has_method_parameters()) {
   1.224 +      uncompressed_table_start = (u2*) method_parameters_start();
   1.225    } else {
   1.226        uncompressed_table_start = (u2*) m_end;
   1.227    }

mercurial