1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/constMethod.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,518 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_OOPS_CONSTMETHODOOP_HPP 1.29 +#define SHARE_VM_OOPS_CONSTMETHODOOP_HPP 1.30 + 1.31 +#include "oops/oop.hpp" 1.32 + 1.33 +// An ConstMethod* represents portions of a Java method which 1.34 +// do not vary. 1.35 +// 1.36 +// Memory layout (each line represents a word). Note that most 1.37 +// applications load thousands of methods, so keeping the size of this 1.38 +// structure small has a big impact on footprint. 1.39 +// 1.40 +// |------------------------------------------------------| 1.41 +// | header | 1.42 +// | klass | 1.43 +// |------------------------------------------------------| 1.44 +// | fingerprint 1 | 1.45 +// | fingerprint 2 | 1.46 +// | constants (oop) | 1.47 +// | stackmap_data (oop) | 1.48 +// | constMethod_size | 1.49 +// | interp_kind | flags | code_size | 1.50 +// | name index | signature index | 1.51 +// | method_idnum | max_stack | 1.52 +// | max_locals | size_of_parameters | 1.53 +// |------------------------------------------------------| 1.54 +// | | 1.55 +// | byte codes | 1.56 +// | | 1.57 +// |------------------------------------------------------| 1.58 +// | compressed linenumber table | 1.59 +// | (see class CompressedLineNumberReadStream) | 1.60 +// | (note that length is unknown until decompressed) | 1.61 +// | (access flags bit tells whether table is present) | 1.62 +// | (indexed from start of ConstMethod*) | 1.63 +// | (elements not necessarily sorted!) | 1.64 +// |------------------------------------------------------| 1.65 +// | localvariable table elements + length (length last) | 1.66 +// | (length is u2, elements are 6-tuples of u2) | 1.67 +// | (see class LocalVariableTableElement) | 1.68 +// | (access flags bit tells whether table is present) | 1.69 +// | (indexed from end of ConstMethod*) | 1.70 +// |------------------------------------------------------| 1.71 +// | exception table + length (length last) | 1.72 +// | (length is u2, elements are 4-tuples of u2) | 1.73 +// | (see class ExceptionTableElement) | 1.74 +// | (access flags bit tells whether table is present) | 1.75 +// | (indexed from end of ConstMethod*) | 1.76 +// |------------------------------------------------------| 1.77 +// | checked exceptions elements + length (length last) | 1.78 +// | (length is u2, elements are u2) | 1.79 +// | (see class CheckedExceptionElement) | 1.80 +// | (access flags bit tells whether table is present) | 1.81 +// | (indexed from end of ConstMethod*) | 1.82 +// |------------------------------------------------------| 1.83 +// | method parameters elements + length (length last) | 1.84 +// | (length is u2, elements are u2, u4 structures) | 1.85 +// | (see class MethodParametersElement) | 1.86 +// | (access flags bit tells whether table is present) | 1.87 +// | (indexed from end of ConstMethod*) | 1.88 +// |------------------------------------------------------| 1.89 +// | generic signature index (u2) | 1.90 +// | (indexed from start of constMethodOop) | 1.91 +// |------------------------------------------------------| 1.92 +// | annotations arrays - method, parameter, type, default| 1.93 +// | pointer to Array<u1> if annotation is present | 1.94 +// |------------------------------------------------------| 1.95 +// 1.96 +// IMPORTANT: If anything gets added here, there need to be changes to 1.97 +// ensure that ServicabilityAgent doesn't get broken as a result! 1.98 + 1.99 + 1.100 +// Utility class describing elements in checked exceptions table inlined in Method*. 1.101 +class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC { 1.102 + public: 1.103 + u2 class_cp_index; 1.104 +}; 1.105 + 1.106 + 1.107 +// Utility class describing elements in local variable table inlined in Method*. 1.108 +class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC { 1.109 + public: 1.110 + u2 start_bci; 1.111 + u2 length; 1.112 + u2 name_cp_index; 1.113 + u2 descriptor_cp_index; 1.114 + u2 signature_cp_index; 1.115 + u2 slot; 1.116 +}; 1.117 + 1.118 +// Utility class describing elements in exception table 1.119 +class ExceptionTableElement VALUE_OBJ_CLASS_SPEC { 1.120 + public: 1.121 + u2 start_pc; 1.122 + u2 end_pc; 1.123 + u2 handler_pc; 1.124 + u2 catch_type_index; 1.125 +}; 1.126 + 1.127 +// Utility class describing elements in method parameters 1.128 +class MethodParametersElement VALUE_OBJ_CLASS_SPEC { 1.129 + public: 1.130 + u2 name_cp_index; 1.131 + u2 flags; 1.132 +}; 1.133 + 1.134 +class KlassSizeStats; 1.135 + 1.136 +// Class to collect the sizes of ConstMethod inline tables 1.137 +#define INLINE_TABLES_DO(do_element) \ 1.138 + do_element(localvariable_table_length) \ 1.139 + do_element(compressed_linenumber_size) \ 1.140 + do_element(exception_table_length) \ 1.141 + do_element(checked_exceptions_length) \ 1.142 + do_element(method_parameters_length) \ 1.143 + do_element(generic_signature_index) \ 1.144 + do_element(method_annotations_length) \ 1.145 + do_element(parameter_annotations_length) \ 1.146 + do_element(type_annotations_length) \ 1.147 + do_element(default_annotations_length) 1.148 + 1.149 +#define INLINE_TABLE_DECLARE(sym) int _##sym; 1.150 +#define INLINE_TABLE_PARAM(sym) int sym, 1.151 +#define INLINE_TABLE_INIT(sym) _##sym(sym), 1.152 +#define INLINE_TABLE_NULL(sym) _##sym(0), 1.153 +#define INLINE_TABLE_ACCESSOR(sym) int sym() const { return _##sym; } 1.154 + 1.155 +class InlineTableSizes : StackObj { 1.156 + // declarations 1.157 + INLINE_TABLES_DO(INLINE_TABLE_DECLARE) 1.158 + int _end; 1.159 + public: 1.160 + InlineTableSizes( 1.161 + INLINE_TABLES_DO(INLINE_TABLE_PARAM) 1.162 + int end) : 1.163 + INLINE_TABLES_DO(INLINE_TABLE_INIT) 1.164 + _end(end) {} 1.165 + 1.166 + // Default constructor for no inlined tables 1.167 + InlineTableSizes() : 1.168 + INLINE_TABLES_DO(INLINE_TABLE_NULL) 1.169 + _end(0) {} 1.170 + 1.171 + // Accessors 1.172 + INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR) 1.173 +}; 1.174 +#undef INLINE_TABLE_ACCESSOR 1.175 +#undef INLINE_TABLE_NULL 1.176 +#undef INLINE_TABLE_INIT 1.177 +#undef INLINE_TABLE_PARAM 1.178 +#undef INLINE_TABLE_DECLARE 1.179 + 1.180 + 1.181 +class ConstMethod : public MetaspaceObj { 1.182 + friend class VMStructs; 1.183 + 1.184 +public: 1.185 + typedef enum { NORMAL, OVERPASS } MethodType; 1.186 + 1.187 +private: 1.188 + enum { 1.189 + _has_linenumber_table = 0x0001, 1.190 + _has_checked_exceptions = 0x0002, 1.191 + _has_localvariable_table = 0x0004, 1.192 + _has_exception_table = 0x0008, 1.193 + _has_generic_signature = 0x0010, 1.194 + _has_method_parameters = 0x0020, 1.195 + _is_overpass = 0x0040, 1.196 + _has_method_annotations = 0x0080, 1.197 + _has_parameter_annotations = 0x0100, 1.198 + _has_type_annotations = 0x0200, 1.199 + _has_default_annotations = 0x0400 1.200 + }; 1.201 + 1.202 + // Bit vector of signature 1.203 + // Callers interpret 0=not initialized yet and 1.204 + // -1=too many args to fix, must parse the slow way. 1.205 + // The real initial value is special to account for nonatomicity of 64 bit 1.206 + // loads and stores. This value may updated and read without a lock by 1.207 + // multiple threads, so is volatile. 1.208 + volatile uint64_t _fingerprint; 1.209 + 1.210 + ConstantPool* _constants; // Constant pool 1.211 + 1.212 + // Raw stackmap data for the method 1.213 + Array<u1>* _stackmap_data; 1.214 + 1.215 + int _constMethod_size; 1.216 + u2 _flags; 1.217 + 1.218 + // Size of Java bytecodes allocated immediately after Method*. 1.219 + u2 _code_size; 1.220 + u2 _name_index; // Method name (index in constant pool) 1.221 + u2 _signature_index; // Method signature (index in constant pool) 1.222 + u2 _method_idnum; // unique identification number for the method within the class 1.223 + // initially corresponds to the index into the methods array. 1.224 + // but this may change with redefinition 1.225 + u2 _max_stack; // Maximum number of entries on the expression stack 1.226 + u2 _max_locals; // Number of local variables used by this method 1.227 + u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words 1.228 + 1.229 + // Constructor 1.230 + ConstMethod(int byte_code_size, 1.231 + InlineTableSizes* sizes, 1.232 + MethodType is_overpass, 1.233 + int size); 1.234 +public: 1.235 + 1.236 + static ConstMethod* allocate(ClassLoaderData* loader_data, 1.237 + int byte_code_size, 1.238 + InlineTableSizes* sizes, 1.239 + MethodType mt, 1.240 + TRAPS); 1.241 + 1.242 + bool is_constMethod() const { return true; } 1.243 + 1.244 + // Inlined tables 1.245 + void set_inlined_tables_length(InlineTableSizes* sizes); 1.246 + 1.247 + bool has_generic_signature() const 1.248 + { return (_flags & _has_generic_signature) != 0; } 1.249 + 1.250 + bool has_linenumber_table() const 1.251 + { return (_flags & _has_linenumber_table) != 0; } 1.252 + 1.253 + bool has_checked_exceptions() const 1.254 + { return (_flags & _has_checked_exceptions) != 0; } 1.255 + 1.256 + bool has_localvariable_table() const 1.257 + { return (_flags & _has_localvariable_table) != 0; } 1.258 + 1.259 + bool has_exception_handler() const 1.260 + { return (_flags & _has_exception_table) != 0; } 1.261 + 1.262 + bool has_method_parameters() const 1.263 + { return (_flags & _has_method_parameters) != 0; } 1.264 + 1.265 + MethodType method_type() const { 1.266 + return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; 1.267 + } 1.268 + 1.269 + void set_method_type(MethodType mt) { 1.270 + if (mt == NORMAL) { 1.271 + _flags &= ~(_is_overpass); 1.272 + } else { 1.273 + _flags |= _is_overpass; 1.274 + } 1.275 + } 1.276 + 1.277 + // constant pool 1.278 + ConstantPool* constants() const { return _constants; } 1.279 + void set_constants(ConstantPool* c) { _constants = c; } 1.280 + 1.281 + Method* method() const; 1.282 + 1.283 + // stackmap table data 1.284 + Array<u1>* stackmap_data() const { return _stackmap_data; } 1.285 + void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; } 1.286 + void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS); 1.287 + bool has_stackmap_table() const { return _stackmap_data != NULL; } 1.288 + 1.289 + void init_fingerprint() { 1.290 + const uint64_t initval = CONST64(0x8000000000000000); 1.291 + _fingerprint = initval; 1.292 + } 1.293 + 1.294 + uint64_t fingerprint() const { 1.295 + // Since reads aren't atomic for 64 bits, if any of the high or low order 1.296 + // word is the initial value, return 0. See init_fingerprint for initval. 1.297 + uint high_fp = (uint)(_fingerprint >> 32); 1.298 + if ((int) _fingerprint == 0 || high_fp == 0x80000000) { 1.299 + return 0L; 1.300 + } else { 1.301 + return _fingerprint; 1.302 + } 1.303 + } 1.304 + 1.305 + uint64_t set_fingerprint(uint64_t new_fingerprint) { 1.306 +#ifdef ASSERT 1.307 + // Assert only valid if complete/valid 64 bit _fingerprint value is read. 1.308 + uint64_t oldfp = fingerprint(); 1.309 +#endif // ASSERT 1.310 + _fingerprint = new_fingerprint; 1.311 + assert(oldfp == 0L || new_fingerprint == oldfp, 1.312 + "fingerprint cannot change"); 1.313 + assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0, 1.314 + "fingerprint should call init to set initial value"); 1.315 + return new_fingerprint; 1.316 + } 1.317 + 1.318 + // name 1.319 + int name_index() const { return _name_index; } 1.320 + void set_name_index(int index) { _name_index = index; } 1.321 + 1.322 + // signature 1.323 + int signature_index() const { return _signature_index; } 1.324 + void set_signature_index(int index) { _signature_index = index; } 1.325 + 1.326 + // generics support 1.327 + int generic_signature_index() const { 1.328 + if (has_generic_signature()) { 1.329 + return *generic_signature_index_addr(); 1.330 + } else { 1.331 + return 0; 1.332 + } 1.333 + } 1.334 + void set_generic_signature_index(u2 index) { 1.335 + assert(has_generic_signature(), ""); 1.336 + u2* addr = generic_signature_index_addr(); 1.337 + *addr = index; 1.338 + } 1.339 + 1.340 + // Sizing 1.341 + static int header_size() { 1.342 + return sizeof(ConstMethod)/HeapWordSize; 1.343 + } 1.344 + 1.345 + // Size needed 1.346 + static int size(int code_size, InlineTableSizes* sizes); 1.347 + 1.348 + int size() const { return _constMethod_size;} 1.349 + void set_constMethod_size(int size) { _constMethod_size = size; } 1.350 +#if INCLUDE_SERVICES 1.351 + void collect_statistics(KlassSizeStats *sz) const; 1.352 +#endif 1.353 + 1.354 + // code size 1.355 + int code_size() const { return _code_size; } 1.356 + void set_code_size(int size) { 1.357 + assert(max_method_code_size < (1 << 16), 1.358 + "u2 is too small to hold method code size in general"); 1.359 + assert(0 <= size && size <= max_method_code_size, "invalid code size"); 1.360 + _code_size = size; 1.361 + } 1.362 + 1.363 + // linenumber table - note that length is unknown until decompression, 1.364 + // see class CompressedLineNumberReadStream. 1.365 + u_char* compressed_linenumber_table() const; // not preserved by gc 1.366 + u2* generic_signature_index_addr() const; 1.367 + u2* checked_exceptions_length_addr() const; 1.368 + u2* localvariable_table_length_addr() const; 1.369 + u2* exception_table_length_addr() const; 1.370 + u2* method_parameters_length_addr() const; 1.371 + 1.372 + // checked exceptions 1.373 + int checked_exceptions_length() const; 1.374 + CheckedExceptionElement* checked_exceptions_start() const; 1.375 + 1.376 + // localvariable table 1.377 + int localvariable_table_length() const; 1.378 + LocalVariableTableElement* localvariable_table_start() const; 1.379 + 1.380 + // exception table 1.381 + int exception_table_length() const; 1.382 + ExceptionTableElement* exception_table_start() const; 1.383 + 1.384 + // method parameters table 1.385 + int method_parameters_length() const; 1.386 + MethodParametersElement* method_parameters_start() const; 1.387 + 1.388 + // method annotations 1.389 + bool has_method_annotations() const 1.390 + { return (_flags & _has_method_annotations) != 0; } 1.391 + 1.392 + bool has_parameter_annotations() const 1.393 + { return (_flags & _has_parameter_annotations) != 0; } 1.394 + 1.395 + bool has_type_annotations() const 1.396 + { return (_flags & _has_type_annotations) != 0; } 1.397 + 1.398 + bool has_default_annotations() const 1.399 + { return (_flags & _has_default_annotations) != 0; } 1.400 + 1.401 + 1.402 + AnnotationArray** method_annotations_addr() const; 1.403 + AnnotationArray* method_annotations() const { 1.404 + return has_method_annotations() ? *(method_annotations_addr()) : NULL; 1.405 + } 1.406 + void set_method_annotations(AnnotationArray* anno) { 1.407 + *(method_annotations_addr()) = anno; 1.408 + } 1.409 + 1.410 + AnnotationArray** parameter_annotations_addr() const; 1.411 + AnnotationArray* parameter_annotations() const { 1.412 + return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL; 1.413 + } 1.414 + void set_parameter_annotations(AnnotationArray* anno) { 1.415 + *(parameter_annotations_addr()) = anno; 1.416 + } 1.417 + 1.418 + AnnotationArray** type_annotations_addr() const; 1.419 + AnnotationArray* type_annotations() const { 1.420 + return has_type_annotations() ? *(type_annotations_addr()) : NULL; 1.421 + } 1.422 + void set_type_annotations(AnnotationArray* anno) { 1.423 + *(type_annotations_addr()) = anno; 1.424 + } 1.425 + 1.426 + AnnotationArray** default_annotations_addr() const; 1.427 + AnnotationArray* default_annotations() const { 1.428 + return has_default_annotations() ? *(default_annotations_addr()) : NULL; 1.429 + } 1.430 + void set_default_annotations(AnnotationArray* anno) { 1.431 + *(default_annotations_addr()) = anno; 1.432 + } 1.433 + 1.434 + int method_annotations_length() const { 1.435 + return has_method_annotations() ? method_annotations()->length() : 0; 1.436 + } 1.437 + int parameter_annotations_length() const { 1.438 + return has_parameter_annotations() ? parameter_annotations()->length() : 0; 1.439 + } 1.440 + int type_annotations_length() const { 1.441 + return has_type_annotations() ? type_annotations()->length() : 0; 1.442 + } 1.443 + int default_annotations_length() const { 1.444 + return has_default_annotations() ? default_annotations()->length() : 0; 1.445 + } 1.446 + 1.447 + // Copy annotations from other ConstMethod 1.448 + void copy_annotations_from(ConstMethod* cm); 1.449 + 1.450 + // byte codes 1.451 + void set_code(address code) { 1.452 + if (code_size() > 0) { 1.453 + memcpy(code_base(), code, code_size()); 1.454 + } 1.455 + } 1.456 + address code_base() const { return (address) (this+1); } 1.457 + address code_end() const { return code_base() + code_size(); } 1.458 + bool contains(address bcp) const { return code_base() <= bcp 1.459 + && bcp < code_end(); } 1.460 + // Offset to bytecodes 1.461 + static ByteSize codes_offset() 1.462 + { return in_ByteSize(sizeof(ConstMethod)); } 1.463 + 1.464 + static ByteSize constants_offset() 1.465 + { return byte_offset_of(ConstMethod, _constants); } 1.466 + 1.467 + static ByteSize max_stack_offset() 1.468 + { return byte_offset_of(ConstMethod, _max_stack); } 1.469 + static ByteSize size_of_locals_offset() 1.470 + { return byte_offset_of(ConstMethod, _max_locals); } 1.471 + static ByteSize size_of_parameters_offset() 1.472 + { return byte_offset_of(ConstMethod, _size_of_parameters); } 1.473 + 1.474 + 1.475 + // Unique id for the method 1.476 + static const u2 MAX_IDNUM; 1.477 + static const u2 UNSET_IDNUM; 1.478 + u2 method_idnum() const { return _method_idnum; } 1.479 + void set_method_idnum(u2 idnum) { _method_idnum = idnum; } 1.480 + 1.481 + // max stack 1.482 + int max_stack() const { return _max_stack; } 1.483 + void set_max_stack(int size) { _max_stack = size; } 1.484 + 1.485 + // max locals 1.486 + int max_locals() const { return _max_locals; } 1.487 + void set_max_locals(int size) { _max_locals = size; } 1.488 + 1.489 + // size of parameters 1.490 + int size_of_parameters() const { return _size_of_parameters; } 1.491 + void set_size_of_parameters(int size) { _size_of_parameters = size; } 1.492 + 1.493 + // Deallocation for RedefineClasses 1.494 + void deallocate_contents(ClassLoaderData* loader_data); 1.495 + bool is_klass() const { return false; } 1.496 + DEBUG_ONLY(bool on_stack() { return false; }) 1.497 + 1.498 +private: 1.499 + // Since the size of the compressed line number table is unknown, the 1.500 + // offsets of the other variable sized sections are computed backwards 1.501 + // from the end of the ConstMethod*. 1.502 + 1.503 + // First byte after ConstMethod* 1.504 + address constMethod_end() const 1.505 + { return (address)((intptr_t*)this + _constMethod_size); } 1.506 + 1.507 + // Last short in ConstMethod* 1.508 + u2* last_u2_element() const; 1.509 + 1.510 + public: 1.511 + // Printing 1.512 + void print_on (outputStream* st) const; 1.513 + void print_value_on(outputStream* st) const; 1.514 + 1.515 + const char* internal_name() const { return "{constMethod}"; } 1.516 + 1.517 + // Verify 1.518 + void verify_on(outputStream* st); 1.519 +}; 1.520 + 1.521 +#endif // SHARE_VM_OOPS_CONSTMETHODOOP_HPP