1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/constMethod.hpp Sat Sep 01 13:25:18 2012 -0400 1.3 @@ -0,0 +1,331 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2012, 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 | generic_signature_index | 1.52 +// |------------------------------------------------------| 1.53 +// | | 1.54 +// | byte codes | 1.55 +// | | 1.56 +// |------------------------------------------------------| 1.57 +// | compressed linenumber table | 1.58 +// | (see class CompressedLineNumberReadStream) | 1.59 +// | (note that length is unknown until decompressed) | 1.60 +// | (access flags bit tells whether table is present) | 1.61 +// | (indexed from start of ConstMethod*) | 1.62 +// | (elements not necessarily sorted!) | 1.63 +// |------------------------------------------------------| 1.64 +// | localvariable table elements + length (length last) | 1.65 +// | (length is u2, elements are 6-tuples of u2) | 1.66 +// | (see class LocalVariableTableElement) | 1.67 +// | (access flags bit tells whether table is present) | 1.68 +// | (indexed from end of ConstMethod*) | 1.69 +// |------------------------------------------------------| 1.70 +// | exception table + length (length last) | 1.71 +// | (length is u2, elements are 4-tuples of u2) | 1.72 +// | (see class ExceptionTableElement) | 1.73 +// | (access flags bit tells whether table is present) | 1.74 +// | (indexed from end of ConstMethod*) | 1.75 +// |------------------------------------------------------| 1.76 +// | checked exceptions elements + length (length last) | 1.77 +// | (length is u2, elements are u2) | 1.78 +// | (see class CheckedExceptionElement) | 1.79 +// | (access flags bit tells whether table is present) | 1.80 +// | (indexed from end of ConstMethod*) | 1.81 +// |------------------------------------------------------| 1.82 + 1.83 + 1.84 +// Utitily class decribing elements in checked exceptions table inlined in Method*. 1.85 +class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC { 1.86 + public: 1.87 + u2 class_cp_index; 1.88 +}; 1.89 + 1.90 + 1.91 +// Utitily class decribing elements in local variable table inlined in Method*. 1.92 +class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC { 1.93 + public: 1.94 + u2 start_bci; 1.95 + u2 length; 1.96 + u2 name_cp_index; 1.97 + u2 descriptor_cp_index; 1.98 + u2 signature_cp_index; 1.99 + u2 slot; 1.100 +}; 1.101 + 1.102 +// Utitily class describing elements in exception table 1.103 +class ExceptionTableElement VALUE_OBJ_CLASS_SPEC { 1.104 + public: 1.105 + u2 start_pc; 1.106 + u2 end_pc; 1.107 + u2 handler_pc; 1.108 + u2 catch_type_index; 1.109 +}; 1.110 + 1.111 + 1.112 +class ConstMethod : public MetaspaceObj { 1.113 + friend class VMStructs; 1.114 +private: 1.115 + enum { 1.116 + _has_linenumber_table = 1, 1.117 + _has_checked_exceptions = 2, 1.118 + _has_localvariable_table = 4, 1.119 + _has_exception_table = 8 1.120 + }; 1.121 + 1.122 + // Bit vector of signature 1.123 + // Callers interpret 0=not initialized yet and 1.124 + // -1=too many args to fix, must parse the slow way. 1.125 + // The real initial value is special to account for nonatomicity of 64 bit 1.126 + // loads and stores. This value may updated and read without a lock by 1.127 + // multiple threads, so is volatile. 1.128 + volatile uint64_t _fingerprint; 1.129 + 1.130 + ConstantPool* _constants; // Constant pool 1.131 + 1.132 + // Raw stackmap data for the method 1.133 + Array<u1>* _stackmap_data; 1.134 + 1.135 + int _constMethod_size; 1.136 + jbyte _interpreter_kind; 1.137 + jbyte _flags; 1.138 + 1.139 + // Size of Java bytecodes allocated immediately after Method*. 1.140 + u2 _code_size; 1.141 + u2 _name_index; // Method name (index in constant pool) 1.142 + u2 _signature_index; // Method signature (index in constant pool) 1.143 + u2 _method_idnum; // unique identification number for the method within the class 1.144 + // initially corresponds to the index into the methods array. 1.145 + // but this may change with redefinition 1.146 + u2 _generic_signature_index; // Generic signature (index in constant pool, 0 if absent) 1.147 + 1.148 + 1.149 + // Constructor 1.150 + ConstMethod(int byte_code_size, 1.151 + int compressed_line_number_size, 1.152 + int localvariable_table_length, 1.153 + int exception_table_length, 1.154 + int checked_exceptions_length, 1.155 + int size); 1.156 +public: 1.157 + static ConstMethod* allocate(ClassLoaderData* loader_data, 1.158 + int byte_code_size, 1.159 + int compressed_line_number_size, 1.160 + int localvariable_table_length, 1.161 + int exception_table_length, 1.162 + int checked_exceptions_length, 1.163 + TRAPS); 1.164 + 1.165 + bool is_constMethod() const { return true; } 1.166 + 1.167 + // Inlined tables 1.168 + void set_inlined_tables_length(int checked_exceptions_len, 1.169 + int compressed_line_number_size, 1.170 + int localvariable_table_len, 1.171 + int exception_table_len); 1.172 + 1.173 + bool has_linenumber_table() const 1.174 + { return (_flags & _has_linenumber_table) != 0; } 1.175 + 1.176 + bool has_checked_exceptions() const 1.177 + { return (_flags & _has_checked_exceptions) != 0; } 1.178 + 1.179 + bool has_localvariable_table() const 1.180 + { return (_flags & _has_localvariable_table) != 0; } 1.181 + 1.182 + bool has_exception_handler() const 1.183 + { return (_flags & _has_exception_table) != 0; } 1.184 + 1.185 + void set_interpreter_kind(int kind) { _interpreter_kind = kind; } 1.186 + int interpreter_kind(void) const { return _interpreter_kind; } 1.187 + 1.188 + // constant pool 1.189 + ConstantPool* constants() const { return _constants; } 1.190 + void set_constants(ConstantPool* c) { _constants = c; } 1.191 + 1.192 + Method* method() const; 1.193 + 1.194 + // stackmap table data 1.195 + Array<u1>* stackmap_data() const { return _stackmap_data; } 1.196 + void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; } 1.197 + bool has_stackmap_table() const { return _stackmap_data != NULL; } 1.198 + 1.199 + void init_fingerprint() { 1.200 + const uint64_t initval = CONST64(0x8000000000000000); 1.201 + _fingerprint = initval; 1.202 + } 1.203 + 1.204 + uint64_t fingerprint() const { 1.205 + // Since reads aren't atomic for 64 bits, if any of the high or low order 1.206 + // word is the initial value, return 0. See init_fingerprint for initval. 1.207 + uint high_fp = (uint)(_fingerprint >> 32); 1.208 + if ((int) _fingerprint == 0 || high_fp == 0x80000000) { 1.209 + return 0L; 1.210 + } else { 1.211 + return _fingerprint; 1.212 + } 1.213 + } 1.214 + 1.215 + uint64_t set_fingerprint(uint64_t new_fingerprint) { 1.216 +#ifdef ASSERT 1.217 + // Assert only valid if complete/valid 64 bit _fingerprint value is read. 1.218 + uint64_t oldfp = fingerprint(); 1.219 +#endif // ASSERT 1.220 + _fingerprint = new_fingerprint; 1.221 + assert(oldfp == 0L || new_fingerprint == oldfp, 1.222 + "fingerprint cannot change"); 1.223 + assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0, 1.224 + "fingerprint should call init to set initial value"); 1.225 + return new_fingerprint; 1.226 + } 1.227 + 1.228 + // name 1.229 + int name_index() const { return _name_index; } 1.230 + void set_name_index(int index) { _name_index = index; } 1.231 + 1.232 + // signature 1.233 + int signature_index() const { return _signature_index; } 1.234 + void set_signature_index(int index) { _signature_index = index; } 1.235 + 1.236 + // generics support 1.237 + int generic_signature_index() const { return _generic_signature_index; } 1.238 + void set_generic_signature_index(int index) { _generic_signature_index = index; } 1.239 + 1.240 + // Sizing 1.241 + static int header_size() { 1.242 + return sizeof(ConstMethod)/HeapWordSize; 1.243 + } 1.244 + 1.245 + // Size needed 1.246 + static int size(int code_size, int compressed_line_number_size, 1.247 + int local_variable_table_length, 1.248 + int exception_table_length, 1.249 + int checked_exceptions_length); 1.250 + 1.251 + int size() const { return _constMethod_size;} 1.252 + void set_constMethod_size(int size) { _constMethod_size = size; } 1.253 + 1.254 + // code size 1.255 + int code_size() const { return _code_size; } 1.256 + void set_code_size(int size) { 1.257 + assert(max_method_code_size < (1 << 16), 1.258 + "u2 is too small to hold method code size in general"); 1.259 + assert(0 <= size && size <= max_method_code_size, "invalid code size"); 1.260 + _code_size = size; 1.261 + } 1.262 + 1.263 + // linenumber table - note that length is unknown until decompression, 1.264 + // see class CompressedLineNumberReadStream. 1.265 + u_char* compressed_linenumber_table() const; // not preserved by gc 1.266 + u2* checked_exceptions_length_addr() const; 1.267 + u2* localvariable_table_length_addr() const; 1.268 + u2* exception_table_length_addr() const; 1.269 + 1.270 + // checked exceptions 1.271 + int checked_exceptions_length() const; 1.272 + CheckedExceptionElement* checked_exceptions_start() const; 1.273 + 1.274 + // localvariable table 1.275 + int localvariable_table_length() const; 1.276 + LocalVariableTableElement* localvariable_table_start() const; 1.277 + 1.278 + // exception table 1.279 + int exception_table_length() const; 1.280 + ExceptionTableElement* exception_table_start() const; 1.281 + 1.282 + // byte codes 1.283 + void set_code(address code) { 1.284 + if (code_size() > 0) { 1.285 + memcpy(code_base(), code, code_size()); 1.286 + } 1.287 + } 1.288 + address code_base() const { return (address) (this+1); } 1.289 + address code_end() const { return code_base() + code_size(); } 1.290 + bool contains(address bcp) const { return code_base() <= bcp 1.291 + && bcp < code_end(); } 1.292 + // Offset to bytecodes 1.293 + static ByteSize codes_offset() 1.294 + { return in_ByteSize(sizeof(ConstMethod)); } 1.295 + 1.296 + static ByteSize constants_offset() 1.297 + { return byte_offset_of(ConstMethod, _constants); } 1.298 + 1.299 + // Unique id for the method 1.300 + static const u2 MAX_IDNUM; 1.301 + static const u2 UNSET_IDNUM; 1.302 + u2 method_idnum() const { return _method_idnum; } 1.303 + void set_method_idnum(u2 idnum) { _method_idnum = idnum; } 1.304 + 1.305 + // Deallocation for RedefineClasses 1.306 + void deallocate_contents(ClassLoaderData* loader_data); 1.307 + bool is_klass() const { return false; } 1.308 + DEBUG_ONLY(bool on_stack() { return false; }) 1.309 + 1.310 +private: 1.311 + // Since the size of the compressed line number table is unknown, the 1.312 + // offsets of the other variable sized sections are computed backwards 1.313 + // from the end of the ConstMethod*. 1.314 + 1.315 + // First byte after ConstMethod* 1.316 + address constMethod_end() const 1.317 + { return (address)((oop*)this + _constMethod_size); } 1.318 + 1.319 + // Last short in ConstMethod* 1.320 + u2* last_u2_element() const 1.321 + { return (u2*)constMethod_end() - 1; } 1.322 + 1.323 + public: 1.324 + // Printing 1.325 + void print_on (outputStream* st) const; 1.326 + void print_value_on(outputStream* st) const; 1.327 + 1.328 + const char* internal_name() const { return "{constMethod}"; } 1.329 + 1.330 + // Verify 1.331 + void verify_on(outputStream* st); 1.332 +}; 1.333 + 1.334 +#endif // SHARE_VM_OOPS_CONSTMETHODOOP_HPP