1 | /* |
2 | * Copyright (c) 2003, 2019, 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 | */ |
24 | |
25 | #ifndef SHARE_OOPS_CONSTMETHOD_HPP |
26 | #define SHARE_OOPS_CONSTMETHOD_HPP |
27 | |
28 | #include "oops/oop.hpp" |
29 | #include "utilities/align.hpp" |
30 | |
31 | // An ConstMethod represents portions of a Java method which are not written to after |
32 | // the classfile is parsed(*see below). This part of the method can be shared across |
33 | // processes in a read-only section with Class Data Sharing (CDS). It's important |
34 | // that this class doesn't have virtual functions because the vptr cannot be shared |
35 | // with CDS. |
36 | // |
37 | // Note that most applications load thousands of methods, so keeping the size of this |
38 | // structure small has a big impact on footprint. |
39 | |
40 | // The actual bytecodes are inlined after the end of the ConstMethod struct. |
41 | // |
42 | // The line number table is compressed and inlined following the byte codes. It is |
43 | // found as the first byte following the byte codes. Note that accessing the line |
44 | // number and local variable tables is not performance critical at all. |
45 | // |
46 | // The checked exceptions table and the local variable table are inlined after the |
47 | // line number table, and indexed from the end of the method. We do not compress the |
48 | // checked exceptions table since the average length is less than 2, and it is used |
49 | // by reflection so access should be fast. We do not bother to compress the local |
50 | // variable table either since it is mostly absent. |
51 | // |
52 | // |
53 | // ConstMethod embedded field layout (after declared fields): |
54 | // [EMBEDDED byte codes] |
55 | // [EMBEDDED compressed linenumber table] |
56 | // (see class CompressedLineNumberReadStream) |
57 | // (note that length is unknown until decompressed) |
58 | // (access flags bit tells whether table is present) |
59 | // (indexed from start of ConstMethod) |
60 | // (elements not necessarily sorted!) |
61 | // [EMBEDDED localvariable table elements + length (length last)] |
62 | // (length is u2, elements are 6-tuples of u2) |
63 | // (see class LocalVariableTableElement) |
64 | // (access flags bit tells whether table is present) |
65 | // (indexed from end of ConstMethod*) |
66 | // [EMBEDDED exception table + length (length last)] |
67 | // (length is u2, elements are 4-tuples of u2) |
68 | // (see class ExceptionTableElement) |
69 | // (access flags bit tells whether table is present) |
70 | // (indexed from end of ConstMethod*) |
71 | // [EMBEDDED checked exceptions elements + length (length last)] |
72 | // (length is u2, elements are u2) |
73 | // (see class CheckedExceptionElement) |
74 | // (access flags bit tells whether table is present) |
75 | // (indexed from end of ConstMethod*) |
76 | // [EMBEDDED method parameters elements + length (length last)] |
77 | // (length is u2, elements are u2, u4 structures) |
78 | // (see class MethodParametersElement) |
79 | // (access flags bit tells whether table is present) |
80 | // (indexed from end of ConstMethod*) |
81 | // [EMBEDDED generic signature index (u2)] |
82 | // (indexed from end of constMethodOop) |
83 | // [EMBEDDED annotations arrays - method, parameter, type, default] |
84 | // pointer to Array<u1> if annotation is present |
85 | // |
86 | // IMPORTANT: If anything gets added here, there need to be changes to |
87 | // ensure that ServicabilityAgent doesn't get broken as a result! |
88 | |
89 | |
90 | // Utility class describing elements in checked exceptions table inlined in Method*. |
91 | class CheckedExceptionElement { |
92 | public: |
93 | u2 class_cp_index; |
94 | }; |
95 | |
96 | |
97 | // Utility class describing elements in local variable table inlined in Method*. |
98 | class LocalVariableTableElement { |
99 | public: |
100 | u2 start_bci; |
101 | u2 length; |
102 | u2 name_cp_index; |
103 | u2 descriptor_cp_index; |
104 | u2 signature_cp_index; |
105 | u2 slot; |
106 | }; |
107 | |
108 | // Utility class describing elements in exception table |
109 | class ExceptionTableElement { |
110 | public: |
111 | u2 start_pc; |
112 | u2 end_pc; |
113 | u2 handler_pc; |
114 | u2 catch_type_index; |
115 | }; |
116 | |
117 | // Utility class describing elements in method parameters |
118 | class MethodParametersElement { |
119 | public: |
120 | u2 name_cp_index; |
121 | u2 flags; |
122 | }; |
123 | |
124 | class KlassSizeStats; |
125 | class AdapterHandlerEntry; |
126 | |
127 | // Class to collect the sizes of ConstMethod inline tables |
128 | #define INLINE_TABLES_DO(do_element) \ |
129 | do_element(localvariable_table_length) \ |
130 | do_element(compressed_linenumber_size) \ |
131 | do_element(exception_table_length) \ |
132 | do_element(checked_exceptions_length) \ |
133 | do_element(method_parameters_length) \ |
134 | do_element(generic_signature_index) \ |
135 | do_element(method_annotations_length) \ |
136 | do_element(parameter_annotations_length) \ |
137 | do_element(type_annotations_length) \ |
138 | do_element(default_annotations_length) |
139 | |
140 | #define INLINE_TABLE_DECLARE(sym) int _##sym; |
141 | #define INLINE_TABLE_PARAM(sym) int sym, |
142 | #define INLINE_TABLE_INIT(sym) _##sym(sym), |
143 | #define INLINE_TABLE_NULL(sym) _##sym(0), |
144 | #define INLINE_TABLE_ACCESSOR(sym) int sym() const { return _##sym; } |
145 | |
146 | class InlineTableSizes : StackObj { |
147 | // declarations |
148 | INLINE_TABLES_DO(INLINE_TABLE_DECLARE) |
149 | int _end; |
150 | public: |
151 | InlineTableSizes( |
152 | INLINE_TABLES_DO(INLINE_TABLE_PARAM) |
153 | int end) : |
154 | INLINE_TABLES_DO(INLINE_TABLE_INIT) |
155 | _end(end) {} |
156 | |
157 | // Default constructor for no inlined tables |
158 | InlineTableSizes() : |
159 | INLINE_TABLES_DO(INLINE_TABLE_NULL) |
160 | _end(0) {} |
161 | |
162 | // Accessors |
163 | INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR) |
164 | }; |
165 | #undef INLINE_TABLE_ACCESSOR |
166 | #undef INLINE_TABLE_NULL |
167 | #undef INLINE_TABLE_INIT |
168 | #undef INLINE_TABLE_PARAM |
169 | #undef INLINE_TABLE_DECLARE |
170 | |
171 | class ConstMethod : public MetaspaceObj { |
172 | friend class VMStructs; |
173 | friend class JVMCIVMStructs; |
174 | |
175 | public: |
176 | typedef enum { NORMAL, OVERPASS } MethodType; |
177 | |
178 | private: |
179 | enum { |
180 | _has_linenumber_table = 0x0001, |
181 | _has_checked_exceptions = 0x0002, |
182 | _has_localvariable_table = 0x0004, |
183 | _has_exception_table = 0x0008, |
184 | _has_generic_signature = 0x0010, |
185 | _has_method_parameters = 0x0020, |
186 | _is_overpass = 0x0040, |
187 | _has_method_annotations = 0x0080, |
188 | _has_parameter_annotations = 0x0100, |
189 | _has_type_annotations = 0x0200, |
190 | _has_default_annotations = 0x0400 |
191 | }; |
192 | |
193 | // Bit vector of signature |
194 | // Callers interpret 0=not initialized yet and |
195 | // -1=too many args to fix, must parse the slow way. |
196 | // The real initial value is special to account for nonatomicity of 64 bit |
197 | // loads and stores. This value may updated and read without a lock by |
198 | // multiple threads, so is volatile. |
199 | volatile uint64_t _fingerprint; |
200 | |
201 | // If you add a new field that points to any metaspace object, you |
202 | // must add this field to ConstMethod::metaspace_pointers_do(). |
203 | |
204 | ConstantPool* _constants; // Constant pool |
205 | |
206 | // Raw stackmap data for the method |
207 | Array<u1>* _stackmap_data; |
208 | |
209 | // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked. |
210 | union { |
211 | AdapterHandlerEntry* _adapter; |
212 | AdapterHandlerEntry** _adapter_trampoline; // see comments around Method::link_method() |
213 | }; |
214 | |
215 | int _constMethod_size; |
216 | u2 _flags; |
217 | u1 _result_type; // BasicType of result |
218 | |
219 | // Size of Java bytecodes allocated immediately after Method*. |
220 | u2 _code_size; |
221 | u2 _name_index; // Method name (index in constant pool) |
222 | u2 _signature_index; // Method signature (index in constant pool) |
223 | u2 _method_idnum; // unique identification number for the method within the class |
224 | // initially corresponds to the index into the methods array. |
225 | // but this may change with redefinition |
226 | u2 _max_stack; // Maximum number of entries on the expression stack |
227 | u2 _max_locals; // Number of local variables used by this method |
228 | u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words |
229 | u2 _orig_method_idnum; // Original unique identification number for the method |
230 | |
231 | // Constructor |
232 | ConstMethod(int byte_code_size, |
233 | InlineTableSizes* sizes, |
234 | MethodType is_overpass, |
235 | int size); |
236 | public: |
237 | |
238 | static ConstMethod* allocate(ClassLoaderData* loader_data, |
239 | int byte_code_size, |
240 | InlineTableSizes* sizes, |
241 | MethodType mt, |
242 | TRAPS); |
243 | |
244 | // Inlined tables |
245 | void set_inlined_tables_length(InlineTableSizes* sizes); |
246 | |
247 | bool has_generic_signature() const |
248 | { return (_flags & _has_generic_signature) != 0; } |
249 | |
250 | bool has_linenumber_table() const |
251 | { return (_flags & _has_linenumber_table) != 0; } |
252 | |
253 | bool has_checked_exceptions() const |
254 | { return (_flags & _has_checked_exceptions) != 0; } |
255 | |
256 | bool has_localvariable_table() const |
257 | { return (_flags & _has_localvariable_table) != 0; } |
258 | |
259 | bool has_exception_handler() const |
260 | { return (_flags & _has_exception_table) != 0; } |
261 | |
262 | bool has_method_parameters() const |
263 | { return (_flags & _has_method_parameters) != 0; } |
264 | |
265 | MethodType method_type() const { |
266 | return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; |
267 | } |
268 | |
269 | void set_method_type(MethodType mt) { |
270 | if (mt == NORMAL) { |
271 | _flags &= ~(_is_overpass); |
272 | } else { |
273 | _flags |= _is_overpass; |
274 | } |
275 | } |
276 | |
277 | // constant pool |
278 | ConstantPool* constants() const { return _constants; } |
279 | void set_constants(ConstantPool* c) { _constants = c; } |
280 | |
281 | Method* method() const; |
282 | |
283 | // stackmap table data |
284 | Array<u1>* stackmap_data() const { return _stackmap_data; } |
285 | void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; } |
286 | void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS); |
287 | bool has_stackmap_table() const { return _stackmap_data != NULL; } |
288 | |
289 | // adapter |
290 | void set_adapter_entry(AdapterHandlerEntry* adapter) { |
291 | assert(!is_shared(), |
292 | "shared methods in archive have fixed adapter_trampoline" ); |
293 | _adapter = adapter; |
294 | } |
295 | void set_adapter_trampoline(AdapterHandlerEntry** trampoline) { |
296 | assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "must be" ); |
297 | if (DumpSharedSpaces) { |
298 | assert(*trampoline == NULL, |
299 | "must be NULL during dump time, to be initialized at run time" ); |
300 | } |
301 | _adapter_trampoline = trampoline; |
302 | } |
303 | void update_adapter_trampoline(AdapterHandlerEntry* adapter) { |
304 | assert(is_shared(), "must be" ); |
305 | *_adapter_trampoline = adapter; |
306 | assert(this->adapter() == adapter, "must be" ); |
307 | } |
308 | AdapterHandlerEntry* adapter() { |
309 | if (is_shared()) { |
310 | return *_adapter_trampoline; |
311 | } else { |
312 | return _adapter; |
313 | } |
314 | } |
315 | |
316 | void init_fingerprint() { |
317 | const uint64_t initval = UCONST64(0x8000000000000000); |
318 | _fingerprint = initval; |
319 | } |
320 | |
321 | uint64_t fingerprint() const { |
322 | // Since reads aren't atomic for 64 bits, if any of the high or low order |
323 | // word is the initial value, return 0. See init_fingerprint for initval. |
324 | uint high_fp = (uint)(_fingerprint >> 32); |
325 | if ((int) _fingerprint == 0 || high_fp == 0x80000000) { |
326 | return 0L; |
327 | } else { |
328 | return _fingerprint; |
329 | } |
330 | } |
331 | |
332 | uint64_t set_fingerprint(uint64_t new_fingerprint) { |
333 | #ifdef ASSERT |
334 | // Assert only valid if complete/valid 64 bit _fingerprint value is read. |
335 | uint64_t oldfp = fingerprint(); |
336 | #endif // ASSERT |
337 | _fingerprint = new_fingerprint; |
338 | assert(oldfp == 0L || new_fingerprint == oldfp, |
339 | "fingerprint cannot change" ); |
340 | assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0, |
341 | "fingerprint should call init to set initial value" ); |
342 | return new_fingerprint; |
343 | } |
344 | |
345 | // name |
346 | int name_index() const { return _name_index; } |
347 | void set_name_index(int index) { _name_index = index; } |
348 | |
349 | // signature |
350 | int signature_index() const { return _signature_index; } |
351 | void set_signature_index(int index) { _signature_index = index; } |
352 | |
353 | // generics support |
354 | int generic_signature_index() const { |
355 | if (has_generic_signature()) { |
356 | return *generic_signature_index_addr(); |
357 | } else { |
358 | return 0; |
359 | } |
360 | } |
361 | void set_generic_signature_index(u2 index) { |
362 | assert(has_generic_signature(), "" ); |
363 | u2* addr = generic_signature_index_addr(); |
364 | *addr = index; |
365 | } |
366 | |
367 | // Sizing |
368 | static int () { |
369 | return align_up((int)sizeof(ConstMethod), wordSize) / wordSize; |
370 | } |
371 | |
372 | // Size needed |
373 | static int size(int code_size, InlineTableSizes* sizes); |
374 | |
375 | int size() const { return _constMethod_size;} |
376 | void set_constMethod_size(int size) { _constMethod_size = size; } |
377 | |
378 | // ConstMethods should be stored in the read-only region of CDS archive. |
379 | static bool is_read_only_by_default() { return true; } |
380 | |
381 | #if INCLUDE_SERVICES |
382 | void collect_statistics(KlassSizeStats *sz) const; |
383 | #endif |
384 | |
385 | // code size |
386 | int code_size() const { return _code_size; } |
387 | void set_code_size(int size) { |
388 | assert(max_method_code_size < (1 << 16), |
389 | "u2 is too small to hold method code size in general" ); |
390 | assert(0 <= size && size <= max_method_code_size, "invalid code size" ); |
391 | _code_size = size; |
392 | } |
393 | |
394 | // linenumber table - note that length is unknown until decompression, |
395 | // see class CompressedLineNumberReadStream. |
396 | u_char* compressed_linenumber_table() const; // not preserved by gc |
397 | u2* generic_signature_index_addr() const; |
398 | u2* checked_exceptions_length_addr() const; |
399 | u2* localvariable_table_length_addr() const; |
400 | u2* exception_table_length_addr() const; |
401 | u2* method_parameters_length_addr() const; |
402 | |
403 | // checked exceptions |
404 | int checked_exceptions_length() const; |
405 | CheckedExceptionElement* checked_exceptions_start() const; |
406 | |
407 | // localvariable table |
408 | int localvariable_table_length() const; |
409 | LocalVariableTableElement* localvariable_table_start() const; |
410 | |
411 | // exception table |
412 | int exception_table_length() const; |
413 | ExceptionTableElement* exception_table_start() const; |
414 | |
415 | // method parameters table |
416 | |
417 | // This returns -1 if no parameters are present, a non-negative |
418 | // value otherwise. Note: sometimes, there are 0-length parameters |
419 | // attributes that must be reported up to the reflection API all the |
420 | // same. |
421 | int method_parameters_length() const; |
422 | MethodParametersElement* method_parameters_start() const; |
423 | |
424 | // method annotations |
425 | bool has_method_annotations() const |
426 | { return (_flags & _has_method_annotations) != 0; } |
427 | |
428 | bool has_parameter_annotations() const |
429 | { return (_flags & _has_parameter_annotations) != 0; } |
430 | |
431 | bool has_type_annotations() const |
432 | { return (_flags & _has_type_annotations) != 0; } |
433 | |
434 | bool has_default_annotations() const |
435 | { return (_flags & _has_default_annotations) != 0; } |
436 | |
437 | |
438 | AnnotationArray** method_annotations_addr() const; |
439 | AnnotationArray* method_annotations() const { |
440 | return has_method_annotations() ? *(method_annotations_addr()) : NULL; |
441 | } |
442 | void set_method_annotations(AnnotationArray* anno) { |
443 | *(method_annotations_addr()) = anno; |
444 | } |
445 | |
446 | AnnotationArray** parameter_annotations_addr() const; |
447 | AnnotationArray* parameter_annotations() const { |
448 | return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL; |
449 | } |
450 | void set_parameter_annotations(AnnotationArray* anno) { |
451 | *(parameter_annotations_addr()) = anno; |
452 | } |
453 | |
454 | AnnotationArray** type_annotations_addr() const; |
455 | AnnotationArray* type_annotations() const { |
456 | return has_type_annotations() ? *(type_annotations_addr()) : NULL; |
457 | } |
458 | void set_type_annotations(AnnotationArray* anno) { |
459 | *(type_annotations_addr()) = anno; |
460 | } |
461 | |
462 | AnnotationArray** default_annotations_addr() const; |
463 | AnnotationArray* default_annotations() const { |
464 | return has_default_annotations() ? *(default_annotations_addr()) : NULL; |
465 | } |
466 | void set_default_annotations(AnnotationArray* anno) { |
467 | *(default_annotations_addr()) = anno; |
468 | } |
469 | |
470 | int method_annotations_length() const { |
471 | return has_method_annotations() ? method_annotations()->length() : 0; |
472 | } |
473 | int parameter_annotations_length() const { |
474 | return has_parameter_annotations() ? parameter_annotations()->length() : 0; |
475 | } |
476 | int type_annotations_length() const { |
477 | return has_type_annotations() ? type_annotations()->length() : 0; |
478 | } |
479 | int default_annotations_length() const { |
480 | return has_default_annotations() ? default_annotations()->length() : 0; |
481 | } |
482 | |
483 | // Copy annotations from other ConstMethod |
484 | void copy_annotations_from(ClassLoaderData* loader_data, ConstMethod* cm, TRAPS); |
485 | |
486 | // byte codes |
487 | void set_code(address code) { |
488 | if (code_size() > 0) { |
489 | memcpy(code_base(), code, code_size()); |
490 | } |
491 | } |
492 | address code_base() const { return (address) (this+1); } |
493 | address code_end() const { return code_base() + code_size(); } |
494 | bool contains(address bcp) const { return code_base() <= bcp |
495 | && bcp < code_end(); } |
496 | // Offset to bytecodes |
497 | static ByteSize codes_offset() |
498 | { return in_ByteSize(sizeof(ConstMethod)); } |
499 | |
500 | static ByteSize constants_offset() |
501 | { return byte_offset_of(ConstMethod, _constants); } |
502 | |
503 | static ByteSize max_stack_offset() |
504 | { return byte_offset_of(ConstMethod, _max_stack); } |
505 | static ByteSize size_of_locals_offset() |
506 | { return byte_offset_of(ConstMethod, _max_locals); } |
507 | static ByteSize size_of_parameters_offset() |
508 | { return byte_offset_of(ConstMethod, _size_of_parameters); } |
509 | |
510 | static ByteSize result_type_offset() |
511 | { return byte_offset_of(ConstMethod, _result_type); } |
512 | |
513 | // Unique id for the method |
514 | static const u2 MAX_IDNUM; |
515 | static const u2 UNSET_IDNUM; |
516 | u2 method_idnum() const { return _method_idnum; } |
517 | void set_method_idnum(u2 idnum) { _method_idnum = idnum; } |
518 | |
519 | u2 orig_method_idnum() const { return _orig_method_idnum; } |
520 | void set_orig_method_idnum(u2 idnum) { _orig_method_idnum = idnum; } |
521 | |
522 | // max stack |
523 | int max_stack() const { return _max_stack; } |
524 | void set_max_stack(int size) { _max_stack = size; } |
525 | |
526 | // max locals |
527 | int max_locals() const { return _max_locals; } |
528 | void set_max_locals(int size) { _max_locals = size; } |
529 | |
530 | // size of parameters |
531 | int size_of_parameters() const { return _size_of_parameters; } |
532 | void set_size_of_parameters(int size) { _size_of_parameters = size; } |
533 | |
534 | void set_result_type(BasicType rt) { assert(rt < 16, "result type too large" ); |
535 | _result_type = (u1)rt; } |
536 | // Deallocation for RedefineClasses |
537 | void deallocate_contents(ClassLoaderData* loader_data); |
538 | bool is_klass() const { return false; } |
539 | DEBUG_ONLY(bool on_stack() { return false; }) |
540 | |
541 | void metaspace_pointers_do(MetaspaceClosure* it); |
542 | MetaspaceObj::Type type() const { return ConstMethodType; } |
543 | private: |
544 | // Since the size of the compressed line number table is unknown, the |
545 | // offsets of the other variable sized sections are computed backwards |
546 | // from the end of the ConstMethod*. |
547 | |
548 | // First byte after ConstMethod* |
549 | address constMethod_end() const |
550 | { return (address)((intptr_t*)this + _constMethod_size); } |
551 | |
552 | // Last short in ConstMethod* |
553 | u2* last_u2_element() const; |
554 | |
555 | public: |
556 | // Printing |
557 | void print_on (outputStream* st) const; |
558 | void print_value_on(outputStream* st) const; |
559 | |
560 | const char* internal_name() const { return "{constMethod}" ; } |
561 | |
562 | // Verify |
563 | void verify_on(outputStream* st); |
564 | }; |
565 | |
566 | #endif // SHARE_OOPS_CONSTMETHOD_HPP |
567 | |