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 }