1 /* 2 * Copyright (c) 2003, 2016, 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_VM_OOPS_CONSTMETHODOOP_HPP 26 #define SHARE_VM_OOPS_CONSTMETHODOOP_HPP 27 28 #include "oops/oop.hpp" 29 30 // An ConstMethod* represents portions of a Java method which 31 // do not vary. 32 // 33 // Memory layout (each line represents a word). Note that most 34 // applications load thousands of methods, so keeping the size of this 35 // structure small has a big impact on footprint. 36 // 37 // |------------------------------------------------------| 38 // | header | 39 // | klass | 40 // |------------------------------------------------------| 41 // | fingerprint 1 | 42 // | fingerprint 2 | 43 // | constants (oop) | 44 // | stackmap_data (oop) | 45 // | constMethod_size | 46 // | interp_kind | flags | code_size | 47 // | name index | signature index | 48 // | method_idnum | max_stack | 49 // | max_locals | size_of_parameters | 50 // |------------------------------------------------------| 51 // | | 52 // | byte codes | 53 // | | 54 // |------------------------------------------------------| 55 // | 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 // |------------------------------------------------------| 62 // | localvariable table elements + length (length last) | 63 // | (length is u2, elements are 6-tuples of u2) | 64 // | (see class LocalVariableTableElement) | 65 // | (access flags bit tells whether table is present) | 66 // | (indexed from end of ConstMethod*) | 67 // |------------------------------------------------------| 68 // | exception table + length (length last) | 69 // | (length is u2, elements are 4-tuples of u2) | 70 // | (see class ExceptionTableElement) | 71 // | (access flags bit tells whether table is present) | 72 // | (indexed from end of ConstMethod*) | 73 // |------------------------------------------------------| 74 // | checked exceptions elements + length (length last) | 75 // | (length is u2, elements are u2) | 76 // | (see class CheckedExceptionElement) | 77 // | (access flags bit tells whether table is present) | 78 // | (indexed from end of ConstMethod*) | 79 // |------------------------------------------------------| 80 // | method parameters elements + length (length last) | 81 // | (length is u2, elements are u2, u4 structures) | 82 // | (see class MethodParametersElement) | 83 // | (access flags bit tells whether table is present) | 84 // | (indexed from end of ConstMethod*) | 85 // |------------------------------------------------------| 86 // | generic signature index (u2) | 87 // | (indexed from start of constMethodOop) | 88 // |------------------------------------------------------| 89 // | annotations arrays - method, parameter, type, default| 90 // | pointer to Array<u1> if annotation is present | 91 // |------------------------------------------------------| 92 // 93 // IMPORTANT: If anything gets added here, there need to be changes to 94 // ensure that ServicabilityAgent doesn't get broken as a result! 95 96 97 // Utility class describing elements in checked exceptions table inlined in Method*. 98 class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC { 99 public: 100 u2 class_cp_index; 101 }; 102 103 104 // Utility class describing elements in local variable table inlined in Method*. 105 class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC { 106 public: 107 u2 start_bci; 108 u2 length; 109 u2 name_cp_index; 110 u2 descriptor_cp_index; 111 u2 signature_cp_index; 112 u2 slot; 113 }; 114 115 // Utility class describing elements in exception table 116 class ExceptionTableElement VALUE_OBJ_CLASS_SPEC { 117 public: 118 u2 start_pc; 119 u2 end_pc; 120 u2 handler_pc; 121 u2 catch_type_index; 122 }; 123 124 // Utility class describing elements in method parameters 125 class MethodParametersElement VALUE_OBJ_CLASS_SPEC { 126 public: 127 u2 name_cp_index; 128 u2 flags; 129 }; 130 131 class KlassSizeStats; 132 133 // Class to collect the sizes of ConstMethod inline tables 134 #define INLINE_TABLES_DO(do_element) \ 135 do_element(localvariable_table_length) \ 136 do_element(compressed_linenumber_size) \ 137 do_element(exception_table_length) \ 138 do_element(checked_exceptions_length) \ 139 do_element(method_parameters_length) \ 140 do_element(generic_signature_index) \ 141 do_element(method_annotations_length) \ 142 do_element(parameter_annotations_length) \ 143 do_element(type_annotations_length) \ 144 do_element(default_annotations_length) 145 146 #define INLINE_TABLE_DECLARE(sym) int _##sym; 147 #define INLINE_TABLE_PARAM(sym) int sym, 148 #define INLINE_TABLE_INIT(sym) _##sym(sym), 149 #define INLINE_TABLE_NULL(sym) _##sym(0), 150 #define INLINE_TABLE_ACCESSOR(sym) int sym() const { return _##sym; } 151 152 class InlineTableSizes : StackObj { 153 // declarations 154 INLINE_TABLES_DO(INLINE_TABLE_DECLARE) 155 int _end; 156 public: InlineTableSizes(INLINE_TABLES_DO (INLINE_TABLE_PARAM)int end)157 InlineTableSizes( 158 INLINE_TABLES_DO(INLINE_TABLE_PARAM) 159 int end) : 160 INLINE_TABLES_DO(INLINE_TABLE_INIT) 161 _end(end) {} 162 163 // Default constructor for no inlined tables InlineTableSizes()164 InlineTableSizes() : 165 INLINE_TABLES_DO(INLINE_TABLE_NULL) 166 _end(0) {} 167 168 // Accessors 169 INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR) 170 }; 171 #undef INLINE_TABLE_ACCESSOR 172 #undef INLINE_TABLE_NULL 173 #undef INLINE_TABLE_INIT 174 #undef INLINE_TABLE_PARAM 175 #undef INLINE_TABLE_DECLARE 176 177 178 class ConstMethod : public MetaspaceObj { 179 friend class VMStructs; 180 181 public: 182 typedef enum { NORMAL, OVERPASS } MethodType; 183 184 private: 185 enum { 186 _has_linenumber_table = 0x0001, 187 _has_checked_exceptions = 0x0002, 188 _has_localvariable_table = 0x0004, 189 _has_exception_table = 0x0008, 190 _has_generic_signature = 0x0010, 191 _has_method_parameters = 0x0020, 192 _is_overpass = 0x0040, 193 _has_method_annotations = 0x0080, 194 _has_parameter_annotations = 0x0100, 195 _has_type_annotations = 0x0200, 196 _has_default_annotations = 0x0400 197 }; 198 199 // Bit vector of signature 200 // Callers interpret 0=not initialized yet and 201 // -1=too many args to fix, must parse the slow way. 202 // The real initial value is special to account for nonatomicity of 64 bit 203 // loads and stores. This value may updated and read without a lock by 204 // multiple threads, so is volatile. 205 volatile uint64_t _fingerprint; 206 207 ConstantPool* _constants; // Constant pool 208 209 // Raw stackmap data for the method 210 Array<u1>* _stackmap_data; 211 212 int _constMethod_size; 213 u2 _flags; 214 u1 _result_type; // BasicType of result 215 216 // Size of Java bytecodes allocated immediately after Method*. 217 u2 _code_size; 218 u2 _name_index; // Method name (index in constant pool) 219 u2 _signature_index; // Method signature (index in constant pool) 220 u2 _method_idnum; // unique identification number for the method within the class 221 // initially corresponds to the index into the methods array. 222 // but this may change with redefinition 223 u2 _max_stack; // Maximum number of entries on the expression stack 224 u2 _max_locals; // Number of local variables used by this method 225 u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words 226 u2 _orig_method_idnum; // Original unique identification number for the method 227 228 // Constructor 229 ConstMethod(int byte_code_size, 230 InlineTableSizes* sizes, 231 MethodType is_overpass, 232 int size); 233 public: 234 235 static ConstMethod* allocate(ClassLoaderData* loader_data, 236 int byte_code_size, 237 InlineTableSizes* sizes, 238 MethodType mt, 239 TRAPS); 240 is_constMethod() const241 bool is_constMethod() const { return true; } 242 243 // Inlined tables 244 void set_inlined_tables_length(InlineTableSizes* sizes); 245 has_generic_signature() const246 bool has_generic_signature() const 247 { return (_flags & _has_generic_signature) != 0; } 248 has_linenumber_table() const249 bool has_linenumber_table() const 250 { return (_flags & _has_linenumber_table) != 0; } 251 has_checked_exceptions() const252 bool has_checked_exceptions() const 253 { return (_flags & _has_checked_exceptions) != 0; } 254 has_localvariable_table() const255 bool has_localvariable_table() const 256 { return (_flags & _has_localvariable_table) != 0; } 257 has_exception_handler() const258 bool has_exception_handler() const 259 { return (_flags & _has_exception_table) != 0; } 260 has_method_parameters() const261 bool has_method_parameters() const 262 { return (_flags & _has_method_parameters) != 0; } 263 method_type() const264 MethodType method_type() const { 265 return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; 266 } 267 set_method_type(MethodType mt)268 void set_method_type(MethodType mt) { 269 if (mt == NORMAL) { 270 _flags &= ~(_is_overpass); 271 } else { 272 _flags |= _is_overpass; 273 } 274 } 275 276 // constant pool constants() const277 ConstantPool* constants() const { return _constants; } set_constants(ConstantPool * c)278 void set_constants(ConstantPool* c) { _constants = c; } 279 280 Method* method() const; 281 282 // stackmap table data stackmap_data() const283 Array<u1>* stackmap_data() const { return _stackmap_data; } set_stackmap_data(Array<u1> * sd)284 void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; } 285 void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS); has_stackmap_table() const286 bool has_stackmap_table() const { return _stackmap_data != NULL; } 287 init_fingerprint()288 void init_fingerprint() { 289 const uint64_t initval = CONST64(0x8000000000000000); 290 _fingerprint = initval; 291 } 292 fingerprint() const293 uint64_t fingerprint() const { 294 // Since reads aren't atomic for 64 bits, if any of the high or low order 295 // word is the initial value, return 0. See init_fingerprint for initval. 296 uint high_fp = (uint)(_fingerprint >> 32); 297 if ((int) _fingerprint == 0 || high_fp == 0x80000000) { 298 return 0L; 299 } else { 300 return _fingerprint; 301 } 302 } 303 set_fingerprint(uint64_t new_fingerprint)304 uint64_t set_fingerprint(uint64_t new_fingerprint) { 305 #ifdef ASSERT 306 // Assert only valid if complete/valid 64 bit _fingerprint value is read. 307 uint64_t oldfp = fingerprint(); 308 #endif // ASSERT 309 _fingerprint = new_fingerprint; 310 assert(oldfp == 0L || new_fingerprint == oldfp, 311 "fingerprint cannot change"); 312 assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0, 313 "fingerprint should call init to set initial value"); 314 return new_fingerprint; 315 } 316 317 // name name_index() const318 int name_index() const { return _name_index; } set_name_index(int index)319 void set_name_index(int index) { _name_index = index; } 320 321 // signature signature_index() const322 int signature_index() const { return _signature_index; } set_signature_index(int index)323 void set_signature_index(int index) { _signature_index = index; } 324 325 // generics support generic_signature_index() const326 int generic_signature_index() const { 327 if (has_generic_signature()) { 328 return *generic_signature_index_addr(); 329 } else { 330 return 0; 331 } 332 } set_generic_signature_index(u2 index)333 void set_generic_signature_index(u2 index) { 334 assert(has_generic_signature(), ""); 335 u2* addr = generic_signature_index_addr(); 336 *addr = index; 337 } 338 339 // Sizing header_size()340 static int header_size() { 341 return sizeof(ConstMethod)/HeapWordSize; 342 } 343 344 // Size needed 345 static int size(int code_size, InlineTableSizes* sizes); 346 size() const347 int size() const { return _constMethod_size;} set_constMethod_size(int size)348 void set_constMethod_size(int size) { _constMethod_size = size; } 349 #if INCLUDE_SERVICES 350 void collect_statistics(KlassSizeStats *sz) const; 351 #endif 352 353 // code size code_size() const354 int code_size() const { return _code_size; } set_code_size(int size)355 void set_code_size(int size) { 356 assert(max_method_code_size < (1 << 16), 357 "u2 is too small to hold method code size in general"); 358 assert(0 <= size && size <= max_method_code_size, "invalid code size"); 359 _code_size = size; 360 } 361 362 // linenumber table - note that length is unknown until decompression, 363 // see class CompressedLineNumberReadStream. 364 u_char* compressed_linenumber_table() const; // not preserved by gc 365 u2* generic_signature_index_addr() const; 366 u2* checked_exceptions_length_addr() const; 367 u2* localvariable_table_length_addr() const; 368 u2* exception_table_length_addr() const; 369 u2* method_parameters_length_addr() const; 370 371 // checked exceptions 372 int checked_exceptions_length() const; 373 CheckedExceptionElement* checked_exceptions_start() const; 374 375 // localvariable table 376 int localvariable_table_length() const; 377 LocalVariableTableElement* localvariable_table_start() const; 378 379 // exception table 380 int exception_table_length() const; 381 ExceptionTableElement* exception_table_start() const; 382 383 // method parameters table 384 int method_parameters_length() const; 385 MethodParametersElement* method_parameters_start() const; 386 387 // method annotations has_method_annotations() const388 bool has_method_annotations() const 389 { return (_flags & _has_method_annotations) != 0; } 390 has_parameter_annotations() const391 bool has_parameter_annotations() const 392 { return (_flags & _has_parameter_annotations) != 0; } 393 has_type_annotations() const394 bool has_type_annotations() const 395 { return (_flags & _has_type_annotations) != 0; } 396 has_default_annotations() const397 bool has_default_annotations() const 398 { return (_flags & _has_default_annotations) != 0; } 399 400 401 AnnotationArray** method_annotations_addr() const; method_annotations() const402 AnnotationArray* method_annotations() const { 403 return has_method_annotations() ? *(method_annotations_addr()) : NULL; 404 } set_method_annotations(AnnotationArray * anno)405 void set_method_annotations(AnnotationArray* anno) { 406 *(method_annotations_addr()) = anno; 407 } 408 409 AnnotationArray** parameter_annotations_addr() const; parameter_annotations() const410 AnnotationArray* parameter_annotations() const { 411 return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL; 412 } set_parameter_annotations(AnnotationArray * anno)413 void set_parameter_annotations(AnnotationArray* anno) { 414 *(parameter_annotations_addr()) = anno; 415 } 416 417 AnnotationArray** type_annotations_addr() const; type_annotations() const418 AnnotationArray* type_annotations() const { 419 return has_type_annotations() ? *(type_annotations_addr()) : NULL; 420 } set_type_annotations(AnnotationArray * anno)421 void set_type_annotations(AnnotationArray* anno) { 422 *(type_annotations_addr()) = anno; 423 } 424 425 AnnotationArray** default_annotations_addr() const; default_annotations() const426 AnnotationArray* default_annotations() const { 427 return has_default_annotations() ? *(default_annotations_addr()) : NULL; 428 } set_default_annotations(AnnotationArray * anno)429 void set_default_annotations(AnnotationArray* anno) { 430 *(default_annotations_addr()) = anno; 431 } 432 method_annotations_length() const433 int method_annotations_length() const { 434 return has_method_annotations() ? method_annotations()->length() : 0; 435 } parameter_annotations_length() const436 int parameter_annotations_length() const { 437 return has_parameter_annotations() ? parameter_annotations()->length() : 0; 438 } type_annotations_length() const439 int type_annotations_length() const { 440 return has_type_annotations() ? type_annotations()->length() : 0; 441 } default_annotations_length() const442 int default_annotations_length() const { 443 return has_default_annotations() ? default_annotations()->length() : 0; 444 } 445 446 // Copy annotations from other ConstMethod 447 void copy_annotations_from(ConstMethod* cm); 448 449 // byte codes set_code(address code)450 void set_code(address code) { 451 if (code_size() > 0) { 452 memcpy(code_base(), code, code_size()); 453 } 454 } code_base() const455 address code_base() const { return (address) (this+1); } code_end() const456 address code_end() const { return code_base() + code_size(); } contains(address bcp) const457 bool contains(address bcp) const { return code_base() <= bcp 458 && bcp < code_end(); } 459 // Offset to bytecodes codes_offset()460 static ByteSize codes_offset() 461 { return in_ByteSize(sizeof(ConstMethod)); } 462 constants_offset()463 static ByteSize constants_offset() 464 { return byte_offset_of(ConstMethod, _constants); } 465 max_stack_offset()466 static ByteSize max_stack_offset() 467 { return byte_offset_of(ConstMethod, _max_stack); } size_of_locals_offset()468 static ByteSize size_of_locals_offset() 469 { return byte_offset_of(ConstMethod, _max_locals); } size_of_parameters_offset()470 static ByteSize size_of_parameters_offset() 471 { return byte_offset_of(ConstMethod, _size_of_parameters); } 472 result_type_offset()473 static ByteSize result_type_offset() 474 { return byte_offset_of(ConstMethod, _result_type); } 475 476 // Unique id for the method 477 static const u2 MAX_IDNUM; 478 static const u2 UNSET_IDNUM; method_idnum() const479 u2 method_idnum() const { return _method_idnum; } set_method_idnum(u2 idnum)480 void set_method_idnum(u2 idnum) { _method_idnum = idnum; } 481 orig_method_idnum() const482 u2 orig_method_idnum() const { return _orig_method_idnum; } set_orig_method_idnum(u2 idnum)483 void set_orig_method_idnum(u2 idnum) { _orig_method_idnum = idnum; } 484 485 // max stack max_stack() const486 int max_stack() const { return _max_stack; } set_max_stack(int size)487 void set_max_stack(int size) { _max_stack = size; } 488 489 // max locals max_locals() const490 int max_locals() const { return _max_locals; } set_max_locals(int size)491 void set_max_locals(int size) { _max_locals = size; } 492 493 // size of parameters size_of_parameters() const494 int size_of_parameters() const { return _size_of_parameters; } set_size_of_parameters(int size)495 void set_size_of_parameters(int size) { _size_of_parameters = size; } 496 set_result_type(BasicType rt)497 void set_result_type(BasicType rt) { assert(rt < 16, "result type too large"); 498 _result_type = (u1)rt; } 499 // Deallocation for RedefineClasses 500 void deallocate_contents(ClassLoaderData* loader_data); is_klass() const501 bool is_klass() const { return false; } 502 DEBUG_ONLY(bool on_stack() { return false; }) 503 504 private: 505 // Since the size of the compressed line number table is unknown, the 506 // offsets of the other variable sized sections are computed backwards 507 // from the end of the ConstMethod*. 508 509 // First byte after ConstMethod* constMethod_end() const510 address constMethod_end() const 511 { return (address)((intptr_t*)this + _constMethod_size); } 512 513 // Last short in ConstMethod* 514 u2* last_u2_element() const; 515 516 public: 517 // Printing 518 void print_on (outputStream* st) const; 519 void print_value_on(outputStream* st) const; 520 internal_name() const521 const char* internal_name() const { return "{constMethod}"; } 522 523 // Verify 524 void verify_on(outputStream* st); 525 }; 526 527 #endif // SHARE_VM_OOPS_CONSTMETHODOOP_HPP 528