34 const u2 ConstMethod::MAX_IDNUM = 0xFFFE; |
34 const u2 ConstMethod::MAX_IDNUM = 0xFFFE; |
35 const u2 ConstMethod::UNSET_IDNUM = 0xFFFF; |
35 const u2 ConstMethod::UNSET_IDNUM = 0xFFFF; |
36 |
36 |
37 ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data, |
37 ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data, |
38 int byte_code_size, |
38 int byte_code_size, |
39 int compressed_line_number_size, |
39 InlineTableSizes* sizes, |
40 int localvariable_table_length, |
|
41 int exception_table_length, |
|
42 int checked_exceptions_length, |
|
43 int method_parameters_length, |
|
44 u2 generic_signature_index, |
|
45 MethodType method_type, |
40 MethodType method_type, |
46 TRAPS) { |
41 TRAPS) { |
47 int size = ConstMethod::size(byte_code_size, |
42 int size = ConstMethod::size(byte_code_size, sizes); |
48 compressed_line_number_size, |
|
49 localvariable_table_length, |
|
50 exception_table_length, |
|
51 checked_exceptions_length, |
|
52 method_parameters_length, |
|
53 generic_signature_index); |
|
54 return new (loader_data, size, true, THREAD) ConstMethod( |
43 return new (loader_data, size, true, THREAD) ConstMethod( |
55 byte_code_size, compressed_line_number_size, localvariable_table_length, |
44 byte_code_size, sizes, method_type, size); |
56 exception_table_length, checked_exceptions_length, |
|
57 method_parameters_length, generic_signature_index, |
|
58 method_type, size); |
|
59 } |
45 } |
60 |
46 |
61 ConstMethod::ConstMethod(int byte_code_size, |
47 ConstMethod::ConstMethod(int byte_code_size, |
62 int compressed_line_number_size, |
48 InlineTableSizes* sizes, |
63 int localvariable_table_length, |
|
64 int exception_table_length, |
|
65 int checked_exceptions_length, |
|
66 int method_parameters_length, |
|
67 u2 generic_signature_index, |
|
68 MethodType method_type, |
49 MethodType method_type, |
69 int size) { |
50 int size) { |
70 |
51 |
71 No_Safepoint_Verifier no_safepoint; |
52 No_Safepoint_Verifier no_safepoint; |
72 set_interpreter_kind(Interpreter::invalid); |
|
73 init_fingerprint(); |
53 init_fingerprint(); |
74 set_constants(NULL); |
54 set_constants(NULL); |
75 set_stackmap_data(NULL); |
55 set_stackmap_data(NULL); |
76 set_code_size(byte_code_size); |
56 set_code_size(byte_code_size); |
77 set_constMethod_size(size); |
57 set_constMethod_size(size); |
78 set_inlined_tables_length(generic_signature_index, |
58 set_inlined_tables_length(sizes); |
79 checked_exceptions_length, |
|
80 compressed_line_number_size, |
|
81 localvariable_table_length, |
|
82 exception_table_length, |
|
83 method_parameters_length); |
|
84 set_method_type(method_type); |
59 set_method_type(method_type); |
85 assert(this->size() == size, "wrong size for object"); |
60 assert(this->size() == size, "wrong size for object"); |
86 } |
61 } |
87 |
62 |
88 |
63 |
89 // Deallocate metadata fields associated with ConstMethod* |
64 // Deallocate metadata fields associated with ConstMethod* |
90 void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) { |
65 void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) { |
91 set_interpreter_kind(Interpreter::invalid); |
|
92 if (stackmap_data() != NULL) { |
66 if (stackmap_data() != NULL) { |
93 MetadataFactory::free_array<u1>(loader_data, stackmap_data()); |
67 MetadataFactory::free_array<u1>(loader_data, stackmap_data()); |
94 } |
68 } |
95 set_stackmap_data(NULL); |
69 set_stackmap_data(NULL); |
|
70 |
|
71 // deallocate annotation arrays |
|
72 if (has_method_annotations()) |
|
73 MetadataFactory::free_array<u1>(loader_data, method_annotations()); |
|
74 if (has_parameter_annotations()) |
|
75 MetadataFactory::free_array<u1>(loader_data, parameter_annotations()); |
|
76 if (has_type_annotations()) |
|
77 MetadataFactory::free_array<u1>(loader_data, type_annotations()); |
|
78 if (has_default_annotations()) |
|
79 MetadataFactory::free_array<u1>(loader_data, default_annotations()); |
96 } |
80 } |
97 |
81 |
98 // How big must this constMethodObject be? |
82 // How big must this constMethodObject be? |
99 |
83 |
100 int ConstMethod::size(int code_size, |
84 int ConstMethod::size(int code_size, |
101 int compressed_line_number_size, |
85 InlineTableSizes* sizes) { |
102 int local_variable_table_length, |
|
103 int exception_table_length, |
|
104 int checked_exceptions_length, |
|
105 int method_parameters_length, |
|
106 u2 generic_signature_index) { |
|
107 int extra_bytes = code_size; |
86 int extra_bytes = code_size; |
108 if (compressed_line_number_size > 0) { |
87 if (sizes->compressed_linenumber_size() > 0) { |
109 extra_bytes += compressed_line_number_size; |
88 extra_bytes += sizes->compressed_linenumber_size(); |
110 } |
89 } |
111 if (checked_exceptions_length > 0) { |
90 if (sizes->checked_exceptions_length() > 0) { |
112 extra_bytes += sizeof(u2); |
91 extra_bytes += sizeof(u2); |
113 extra_bytes += checked_exceptions_length * sizeof(CheckedExceptionElement); |
92 extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement); |
114 } |
93 } |
115 if (local_variable_table_length > 0) { |
94 if (sizes->localvariable_table_length() > 0) { |
116 extra_bytes += sizeof(u2); |
95 extra_bytes += sizeof(u2); |
117 extra_bytes += |
96 extra_bytes += |
118 local_variable_table_length * sizeof(LocalVariableTableElement); |
97 sizes->localvariable_table_length() * sizeof(LocalVariableTableElement); |
119 } |
98 } |
120 if (exception_table_length > 0) { |
99 if (sizes->exception_table_length() > 0) { |
121 extra_bytes += sizeof(u2); |
100 extra_bytes += sizeof(u2); |
122 extra_bytes += exception_table_length * sizeof(ExceptionTableElement); |
101 extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement); |
123 } |
102 } |
124 if (generic_signature_index != 0) { |
103 if (sizes->generic_signature_index() != 0) { |
125 extra_bytes += sizeof(u2); |
104 extra_bytes += sizeof(u2); |
126 } |
105 } |
127 if (method_parameters_length > 0) { |
106 if (sizes->method_parameters_length() > 0) { |
128 extra_bytes += sizeof(u2); |
107 extra_bytes += sizeof(u2); |
129 extra_bytes += method_parameters_length * sizeof(MethodParametersElement); |
108 extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement); |
130 } |
109 } |
|
110 |
|
111 // Align sizes up to a word. |
|
112 extra_bytes = align_size_up(extra_bytes, BytesPerWord); |
|
113 |
|
114 // One pointer per annotation array |
|
115 if (sizes->method_annotations_length() > 0) { |
|
116 extra_bytes += sizeof(AnnotationArray*); |
|
117 } |
|
118 if (sizes->parameter_annotations_length() > 0) { |
|
119 extra_bytes += sizeof(AnnotationArray*); |
|
120 } |
|
121 if (sizes->type_annotations_length() > 0) { |
|
122 extra_bytes += sizeof(AnnotationArray*); |
|
123 } |
|
124 if (sizes->default_annotations_length() > 0) { |
|
125 extra_bytes += sizeof(AnnotationArray*); |
|
126 } |
|
127 |
131 int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; |
128 int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; |
|
129 assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned"); |
132 return align_object_size(header_size() + extra_words); |
130 return align_object_size(header_size() + extra_words); |
133 } |
131 } |
134 |
132 |
135 Method* ConstMethod::method() const { |
133 Method* ConstMethod::method() const { |
136 return _constants->pool_holder()->method_with_idnum(_method_idnum); |
134 return _constants->pool_holder()->method_with_idnum(_method_idnum); |
202 return (u2*)method_parameters_start() - 1; |
210 return (u2*)method_parameters_start() - 1; |
203 } else { |
211 } else { |
204 // Else, the exception table is at the end of the constMethod. |
212 // Else, the exception table is at the end of the constMethod. |
205 return has_generic_signature() ? (last_u2_element() - 1) : |
213 return has_generic_signature() ? (last_u2_element() - 1) : |
206 last_u2_element(); |
214 last_u2_element(); |
|
215 } |
207 } |
216 } |
208 } |
217 } |
209 } |
|
210 } |
218 } |
211 |
219 |
212 // Update the flags to indicate the presence of these optional fields. |
220 // Update the flags to indicate the presence of these optional fields. |
213 void ConstMethod::set_inlined_tables_length(u2 generic_signature_index, |
221 void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) { |
214 int checked_exceptions_len, |
222 _flags = 0; |
215 int compressed_line_number_size, |
223 if (sizes->compressed_linenumber_size() > 0) |
216 int localvariable_table_len, |
|
217 int exception_table_len, |
|
218 int method_parameters_len) { |
|
219 assert(_flags == 0, "Error"); |
|
220 if (compressed_line_number_size > 0) |
|
221 _flags |= _has_linenumber_table; |
224 _flags |= _has_linenumber_table; |
222 if (generic_signature_index != 0) |
225 if (sizes->generic_signature_index() != 0) |
223 _flags |= _has_generic_signature; |
226 _flags |= _has_generic_signature; |
224 if (method_parameters_len > 0) |
227 if (sizes->method_parameters_length() > 0) |
225 _flags |= _has_method_parameters; |
228 _flags |= _has_method_parameters; |
226 if (checked_exceptions_len > 0) |
229 if (sizes->checked_exceptions_length() > 0) |
227 _flags |= _has_checked_exceptions; |
230 _flags |= _has_checked_exceptions; |
228 if (exception_table_len > 0) |
231 if (sizes->exception_table_length() > 0) |
229 _flags |= _has_exception_table; |
232 _flags |= _has_exception_table; |
230 if (localvariable_table_len > 0) |
233 if (sizes->localvariable_table_length() > 0) |
231 _flags |= _has_localvariable_table; |
234 _flags |= _has_localvariable_table; |
|
235 |
|
236 // annotations, they are all pointer sized embedded objects so don't have |
|
237 // a length embedded also. |
|
238 if (sizes->method_annotations_length() > 0) |
|
239 _flags |= _has_method_annotations; |
|
240 if (sizes->parameter_annotations_length() > 0) |
|
241 _flags |= _has_parameter_annotations; |
|
242 if (sizes->type_annotations_length() > 0) |
|
243 _flags |= _has_type_annotations; |
|
244 if (sizes->default_annotations_length() > 0) |
|
245 _flags |= _has_default_annotations; |
232 |
246 |
233 // This code is extremely brittle and should possibly be revised. |
247 // This code is extremely brittle and should possibly be revised. |
234 // The *_length_addr functions walk backwards through the |
248 // The *_length_addr functions walk backwards through the |
235 // constMethod data, using each of the length indexes ahead of them, |
249 // constMethod data, using each of the length indexes ahead of them, |
236 // as well as the flags variable. Therefore, the indexes must be |
250 // as well as the flags variable. Therefore, the indexes must be |
240 // still break if the order is not exactly right. |
254 // still break if the order is not exactly right. |
241 // |
255 // |
242 // Also, the servicability agent needs to be informed anytime |
256 // Also, the servicability agent needs to be informed anytime |
243 // anything is added here. It might be advisable to have some sort |
257 // anything is added here. It might be advisable to have some sort |
244 // of indication of this inline. |
258 // of indication of this inline. |
245 if (generic_signature_index != 0) |
259 if (sizes->generic_signature_index() != 0) |
246 *(generic_signature_index_addr()) = generic_signature_index; |
260 *(generic_signature_index_addr()) = sizes->generic_signature_index(); |
247 // New data should probably go here. |
261 // New data should probably go here. |
248 if (method_parameters_len > 0) |
262 if (sizes->method_parameters_length() > 0) |
249 *(method_parameters_length_addr()) = method_parameters_len; |
263 *(method_parameters_length_addr()) = sizes->method_parameters_length(); |
250 if (checked_exceptions_len > 0) |
264 if (sizes->checked_exceptions_length() > 0) |
251 *(checked_exceptions_length_addr()) = checked_exceptions_len; |
265 *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length(); |
252 if (exception_table_len > 0) |
266 if (sizes->exception_table_length() > 0) |
253 *(exception_table_length_addr()) = exception_table_len; |
267 *(exception_table_length_addr()) = sizes->exception_table_length(); |
254 if (localvariable_table_len > 0) |
268 if (sizes->localvariable_table_length() > 0) |
255 *(localvariable_table_length_addr()) = localvariable_table_len; |
269 *(localvariable_table_length_addr()) = sizes->localvariable_table_length(); |
256 } |
270 } |
257 |
271 |
258 int ConstMethod::method_parameters_length() const { |
272 int ConstMethod::method_parameters_length() const { |
259 return has_method_parameters() ? *(method_parameters_length_addr()) : 0; |
273 return has_method_parameters() ? *(method_parameters_length_addr()) : 0; |
260 } |
274 } |