comparison src/share/vm/oops/constMethod.cpp @ 7482:989155e2d07a

Merge with hs25-b15.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Wed, 16 Jan 2013 01:34:24 +0100
parents ade95d680b42
children 16fb9f942703
comparison
equal deleted inserted replaced
7381:6761a8f854a4 7482:989155e2d07a
37 int byte_code_size, 37 int byte_code_size,
38 int compressed_line_number_size, 38 int compressed_line_number_size,
39 int localvariable_table_length, 39 int localvariable_table_length,
40 int exception_table_length, 40 int exception_table_length,
41 int checked_exceptions_length, 41 int checked_exceptions_length,
42 int method_parameters_length,
42 u2 generic_signature_index, 43 u2 generic_signature_index,
43 MethodType method_type, 44 MethodType method_type,
44 TRAPS) { 45 TRAPS) {
45 int size = ConstMethod::size(byte_code_size, 46 int size = ConstMethod::size(byte_code_size,
46 compressed_line_number_size, 47 compressed_line_number_size,
47 localvariable_table_length, 48 localvariable_table_length,
48 exception_table_length, 49 exception_table_length,
49 checked_exceptions_length, 50 checked_exceptions_length,
50 generic_signature_index); 51 method_parameters_length,
52 generic_signature_index);
51 return new (loader_data, size, true, THREAD) ConstMethod( 53 return new (loader_data, size, true, THREAD) ConstMethod(
52 byte_code_size, compressed_line_number_size, localvariable_table_length, 54 byte_code_size, compressed_line_number_size, localvariable_table_length,
53 exception_table_length, checked_exceptions_length, generic_signature_index, 55 exception_table_length, checked_exceptions_length,
56 method_parameters_length, generic_signature_index,
54 method_type, size); 57 method_type, size);
55 } 58 }
56 59
57 ConstMethod::ConstMethod(int byte_code_size, 60 ConstMethod::ConstMethod(int byte_code_size,
58 int compressed_line_number_size, 61 int compressed_line_number_size,
59 int localvariable_table_length, 62 int localvariable_table_length,
60 int exception_table_length, 63 int exception_table_length,
61 int checked_exceptions_length, 64 int checked_exceptions_length,
65 int method_parameters_length,
62 u2 generic_signature_index, 66 u2 generic_signature_index,
63 MethodType method_type, 67 MethodType method_type,
64 int size) { 68 int size) {
65 69
66 No_Safepoint_Verifier no_safepoint; 70 No_Safepoint_Verifier no_safepoint;
72 set_constMethod_size(size); 76 set_constMethod_size(size);
73 set_inlined_tables_length(generic_signature_index, 77 set_inlined_tables_length(generic_signature_index,
74 checked_exceptions_length, 78 checked_exceptions_length,
75 compressed_line_number_size, 79 compressed_line_number_size,
76 localvariable_table_length, 80 localvariable_table_length,
77 exception_table_length); 81 exception_table_length,
82 method_parameters_length);
78 set_method_type(method_type); 83 set_method_type(method_type);
79 assert(this->size() == size, "wrong size for object"); 84 assert(this->size() == size, "wrong size for object");
80 } 85 }
81 86
82 87
90 } 95 }
91 96
92 // How big must this constMethodObject be? 97 // How big must this constMethodObject be?
93 98
94 int ConstMethod::size(int code_size, 99 int ConstMethod::size(int code_size,
95 int compressed_line_number_size, 100 int compressed_line_number_size,
96 int local_variable_table_length, 101 int local_variable_table_length,
97 int exception_table_length, 102 int exception_table_length,
98 int checked_exceptions_length, 103 int checked_exceptions_length,
99 u2 generic_signature_index) { 104 int method_parameters_length,
105 u2 generic_signature_index) {
100 int extra_bytes = code_size; 106 int extra_bytes = code_size;
101 if (compressed_line_number_size > 0) { 107 if (compressed_line_number_size > 0) {
102 extra_bytes += compressed_line_number_size; 108 extra_bytes += compressed_line_number_size;
103 } 109 }
104 if (checked_exceptions_length > 0) { 110 if (checked_exceptions_length > 0) {
114 extra_bytes += sizeof(u2); 120 extra_bytes += sizeof(u2);
115 extra_bytes += exception_table_length * sizeof(ExceptionTableElement); 121 extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
116 } 122 }
117 if (generic_signature_index != 0) { 123 if (generic_signature_index != 0) {
118 extra_bytes += sizeof(u2); 124 extra_bytes += sizeof(u2);
125 }
126 if (method_parameters_length > 0) {
127 extra_bytes += sizeof(u2);
128 extra_bytes += method_parameters_length * sizeof(MethodParametersElement);
119 } 129 }
120 int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; 130 int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
121 return align_object_size(header_size() + extra_words); 131 return align_object_size(header_size() + extra_words);
122 } 132 }
123 133
141 } 151 }
142 152
143 u2* ConstMethod::checked_exceptions_length_addr() const { 153 u2* ConstMethod::checked_exceptions_length_addr() const {
144 // Located immediately before the generic signature index. 154 // Located immediately before the generic signature index.
145 assert(has_checked_exceptions(), "called only if table is present"); 155 assert(has_checked_exceptions(), "called only if table is present");
156 if(has_method_parameters()) {
157 // If method parameters present, locate immediately before them.
158 return (u2*)method_parameters_start() - 1;
159 } else {
160 // Else, the exception table is at the end of the constMethod.
161 return has_generic_signature() ? (last_u2_element() - 1) :
162 last_u2_element();
163 }
164 }
165
166 u2* ConstMethod::method_parameters_length_addr() const {
167 assert(has_method_parameters(), "called only if table is present");
146 return has_generic_signature() ? (last_u2_element() - 1) : 168 return has_generic_signature() ? (last_u2_element() - 1) :
147 last_u2_element(); 169 last_u2_element();
148 } 170 }
149 171
150 u2* ConstMethod::exception_table_length_addr() const { 172 u2* ConstMethod::exception_table_length_addr() const {
151 assert(has_exception_handler(), "called only if table is present"); 173 assert(has_exception_handler(), "called only if table is present");
152 if (has_checked_exceptions()) { 174 if (has_checked_exceptions()) {
153 // If checked_exception present, locate immediately before them. 175 // If checked_exception present, locate immediately before them.
154 return (u2*) checked_exceptions_start() - 1; 176 return (u2*) checked_exceptions_start() - 1;
155 } else { 177 } else {
156 // Else, the exception table is at the end of the constMethod or 178 if(has_method_parameters()) {
157 // immediately before the generic signature index. 179 // If method parameters present, locate immediately before them.
180 return (u2*)method_parameters_start() - 1;
181 } else {
182 // Else, the exception table is at the end of the constMethod.
158 return has_generic_signature() ? (last_u2_element() - 1) : 183 return has_generic_signature() ? (last_u2_element() - 1) :
159 last_u2_element(); 184 last_u2_element();
185 }
160 } 186 }
161 } 187 }
162 188
163 u2* ConstMethod::localvariable_table_length_addr() const { 189 u2* ConstMethod::localvariable_table_length_addr() const {
164 assert(has_localvariable_table(), "called only if table is present"); 190 assert(has_localvariable_table(), "called only if table is present");
168 } else { 194 } else {
169 if (has_checked_exceptions()) { 195 if (has_checked_exceptions()) {
170 // If checked_exception present, locate immediately before them. 196 // If checked_exception present, locate immediately before them.
171 return (u2*) checked_exceptions_start() - 1; 197 return (u2*) checked_exceptions_start() - 1;
172 } else { 198 } else {
173 // Else, the linenumber table is at the end of the constMethod or 199 if(has_method_parameters()) {
174 // immediately before the generic signature index. 200 // If method parameters present, locate immediately before them.
201 return (u2*)method_parameters_start() - 1;
202 } else {
203 // Else, the exception table is at the end of the constMethod.
175 return has_generic_signature() ? (last_u2_element() - 1) : 204 return has_generic_signature() ? (last_u2_element() - 1) :
176 last_u2_element(); 205 last_u2_element();
177 } 206 }
207 }
178 } 208 }
179 } 209 }
180 210
181 // Update the flags to indicate the presence of these optional fields. 211 // Update the flags to indicate the presence of these optional fields.
182 void ConstMethod::set_inlined_tables_length(u2 generic_signature_index, 212 void ConstMethod::set_inlined_tables_length(u2 generic_signature_index,
183 int checked_exceptions_len, 213 int checked_exceptions_len,
184 int compressed_line_number_size, 214 int compressed_line_number_size,
185 int localvariable_table_len, 215 int localvariable_table_len,
186 int exception_table_len) { 216 int exception_table_len,
187 // Must be done in the order below, otherwise length_addr accessors 217 int method_parameters_len) {
188 // will not work. Only set bit in header if length is positive.
189 assert(_flags == 0, "Error"); 218 assert(_flags == 0, "Error");
190 if (compressed_line_number_size > 0) { 219 if (compressed_line_number_size > 0)
191 _flags |= _has_linenumber_table; 220 _flags |= _has_linenumber_table;
192 } 221 if (generic_signature_index != 0)
193 if (generic_signature_index != 0) {
194 _flags |= _has_generic_signature; 222 _flags |= _has_generic_signature;
223 if (method_parameters_len > 0)
224 _flags |= _has_method_parameters;
225 if (checked_exceptions_len > 0)
226 _flags |= _has_checked_exceptions;
227 if (exception_table_len > 0)
228 _flags |= _has_exception_table;
229 if (localvariable_table_len > 0)
230 _flags |= _has_localvariable_table;
231
232 // This code is extremely brittle and should possibly be revised.
233 // The *_length_addr functions walk backwards through the
234 // constMethod data, using each of the length indexes ahead of them,
235 // as well as the flags variable. Therefore, the indexes must be
236 // initialized in reverse order, or else they will compute the wrong
237 // offsets. Moving the initialization of _flags into a separate
238 // block solves *half* of the problem, but the following part will
239 // still break if the order is not exactly right.
240 //
241 // Also, the servicability agent needs to be informed anytime
242 // anything is added here. It might be advisable to have some sort
243 // of indication of this inline.
244 if (generic_signature_index != 0)
195 *(generic_signature_index_addr()) = generic_signature_index; 245 *(generic_signature_index_addr()) = generic_signature_index;
196 } 246 // New data should probably go here.
197 if (checked_exceptions_len > 0) { 247 if (method_parameters_len > 0)
198 _flags |= _has_checked_exceptions; 248 *(method_parameters_length_addr()) = method_parameters_len;
249 if (checked_exceptions_len > 0)
199 *(checked_exceptions_length_addr()) = checked_exceptions_len; 250 *(checked_exceptions_length_addr()) = checked_exceptions_len;
200 } 251 if (exception_table_len > 0)
201 if (exception_table_len > 0) {
202 _flags |= _has_exception_table;
203 *(exception_table_length_addr()) = exception_table_len; 252 *(exception_table_length_addr()) = exception_table_len;
204 } 253 if (localvariable_table_len > 0)
205 if (localvariable_table_len > 0) {
206 _flags |= _has_localvariable_table;
207 *(localvariable_table_length_addr()) = localvariable_table_len; 254 *(localvariable_table_length_addr()) = localvariable_table_len;
208 } 255 }
256
257 int ConstMethod::method_parameters_length() const {
258 return has_method_parameters() ? *(method_parameters_length_addr()) : 0;
259 }
260
261 MethodParametersElement* ConstMethod::method_parameters_start() const {
262 u2* addr = method_parameters_length_addr();
263 u2 length = *addr;
264 assert(length > 0, "should only be called if table is present");
265 addr -= length * sizeof(MethodParametersElement) / sizeof(u2);
266 return (MethodParametersElement*) addr;
209 } 267 }
210 268
211 269
212 int ConstMethod::checked_exceptions_length() const { 270 int ConstMethod::checked_exceptions_length() const {
213 return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0; 271 return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0;
296 } 354 }
297 compressed_table_end += stream.position(); 355 compressed_table_end += stream.position();
298 } 356 }
299 guarantee(compressed_table_end <= m_end, "invalid method layout"); 357 guarantee(compressed_table_end <= m_end, "invalid method layout");
300 // Verify checked exceptions, exception table and local variable tables 358 // Verify checked exceptions, exception table and local variable tables
359 if (has_method_parameters()) {
360 u2* addr = method_parameters_length_addr();
361 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
362 }
301 if (has_checked_exceptions()) { 363 if (has_checked_exceptions()) {
302 u2* addr = checked_exceptions_length_addr(); 364 u2* addr = checked_exceptions_length_addr();
303 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 365 guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
304 } 366 }
305 if (has_exception_handler()) { 367 if (has_exception_handler()) {
316 uncompressed_table_start = (u2*) localvariable_table_start(); 378 uncompressed_table_start = (u2*) localvariable_table_start();
317 } else if (has_exception_handler()) { 379 } else if (has_exception_handler()) {
318 uncompressed_table_start = (u2*) exception_table_start(); 380 uncompressed_table_start = (u2*) exception_table_start();
319 } else if (has_checked_exceptions()) { 381 } else if (has_checked_exceptions()) {
320 uncompressed_table_start = (u2*) checked_exceptions_start(); 382 uncompressed_table_start = (u2*) checked_exceptions_start();
383 } else if (has_method_parameters()) {
384 uncompressed_table_start = (u2*) method_parameters_start();
321 } else { 385 } else {
322 uncompressed_table_start = (u2*) m_end; 386 uncompressed_table_start = (u2*) m_end;
323 } 387 }
324 int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end; 388 int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
325 int max_gap = align_object_size(1)*BytesPerWord; 389 int max_gap = align_object_size(1)*BytesPerWord;