1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/constMethod.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,494 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2014, 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 +#include "precompiled.hpp" 1.29 +#include "interpreter/interpreter.hpp" 1.30 +#include "memory/gcLocker.hpp" 1.31 +#include "memory/heapInspection.hpp" 1.32 +#include "memory/metadataFactory.hpp" 1.33 +#include "oops/constMethod.hpp" 1.34 +#include "oops/method.hpp" 1.35 + 1.36 +// Static initialization 1.37 +const u2 ConstMethod::MAX_IDNUM = 0xFFFE; 1.38 +const u2 ConstMethod::UNSET_IDNUM = 0xFFFF; 1.39 + 1.40 +ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data, 1.41 + int byte_code_size, 1.42 + InlineTableSizes* sizes, 1.43 + MethodType method_type, 1.44 + TRAPS) { 1.45 + int size = ConstMethod::size(byte_code_size, sizes); 1.46 + return new (loader_data, size, true, MetaspaceObj::ConstMethodType, THREAD) ConstMethod( 1.47 + byte_code_size, sizes, method_type, size); 1.48 +} 1.49 + 1.50 +ConstMethod::ConstMethod(int byte_code_size, 1.51 + InlineTableSizes* sizes, 1.52 + MethodType method_type, 1.53 + int size) { 1.54 + 1.55 + No_Safepoint_Verifier no_safepoint; 1.56 + init_fingerprint(); 1.57 + set_constants(NULL); 1.58 + set_stackmap_data(NULL); 1.59 + set_code_size(byte_code_size); 1.60 + set_constMethod_size(size); 1.61 + set_inlined_tables_length(sizes); // sets _flags 1.62 + set_method_type(method_type); 1.63 + assert(this->size() == size, "wrong size for object"); 1.64 + set_name_index(0); 1.65 + set_signature_index(0); 1.66 + set_constants(NULL); 1.67 + set_max_stack(0); 1.68 + set_max_locals(0); 1.69 + set_method_idnum(0); 1.70 + set_size_of_parameters(0); 1.71 +} 1.72 + 1.73 +// Accessor that copies to metadata. 1.74 +void ConstMethod::copy_stackmap_data(ClassLoaderData* loader_data, 1.75 + u1* sd, int length, TRAPS) { 1.76 + _stackmap_data = MetadataFactory::new_array<u1>(loader_data, length, CHECK); 1.77 + memcpy((void*)_stackmap_data->adr_at(0), (void*)sd, length); 1.78 +} 1.79 + 1.80 +// Deallocate metadata fields associated with ConstMethod* 1.81 +void ConstMethod::deallocate_contents(ClassLoaderData* loader_data) { 1.82 + if (stackmap_data() != NULL) { 1.83 + MetadataFactory::free_array<u1>(loader_data, stackmap_data()); 1.84 + } 1.85 + set_stackmap_data(NULL); 1.86 + 1.87 + // deallocate annotation arrays 1.88 + if (has_method_annotations()) 1.89 + MetadataFactory::free_array<u1>(loader_data, method_annotations()); 1.90 + if (has_parameter_annotations()) 1.91 + MetadataFactory::free_array<u1>(loader_data, parameter_annotations()); 1.92 + if (has_type_annotations()) 1.93 + MetadataFactory::free_array<u1>(loader_data, type_annotations()); 1.94 + if (has_default_annotations()) 1.95 + MetadataFactory::free_array<u1>(loader_data, default_annotations()); 1.96 +} 1.97 + 1.98 +// How big must this constMethodObject be? 1.99 + 1.100 +int ConstMethod::size(int code_size, 1.101 + InlineTableSizes* sizes) { 1.102 + int extra_bytes = code_size; 1.103 + if (sizes->compressed_linenumber_size() > 0) { 1.104 + extra_bytes += sizes->compressed_linenumber_size(); 1.105 + } 1.106 + if (sizes->checked_exceptions_length() > 0) { 1.107 + extra_bytes += sizeof(u2); 1.108 + extra_bytes += sizes->checked_exceptions_length() * sizeof(CheckedExceptionElement); 1.109 + } 1.110 + if (sizes->localvariable_table_length() > 0) { 1.111 + extra_bytes += sizeof(u2); 1.112 + extra_bytes += 1.113 + sizes->localvariable_table_length() * sizeof(LocalVariableTableElement); 1.114 + } 1.115 + if (sizes->exception_table_length() > 0) { 1.116 + extra_bytes += sizeof(u2); 1.117 + extra_bytes += sizes->exception_table_length() * sizeof(ExceptionTableElement); 1.118 + } 1.119 + if (sizes->generic_signature_index() != 0) { 1.120 + extra_bytes += sizeof(u2); 1.121 + } 1.122 + if (sizes->method_parameters_length() > 0) { 1.123 + extra_bytes += sizeof(u2); 1.124 + extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement); 1.125 + } 1.126 + 1.127 + // Align sizes up to a word. 1.128 + extra_bytes = align_size_up(extra_bytes, BytesPerWord); 1.129 + 1.130 + // One pointer per annotation array 1.131 + if (sizes->method_annotations_length() > 0) { 1.132 + extra_bytes += sizeof(AnnotationArray*); 1.133 + } 1.134 + if (sizes->parameter_annotations_length() > 0) { 1.135 + extra_bytes += sizeof(AnnotationArray*); 1.136 + } 1.137 + if (sizes->type_annotations_length() > 0) { 1.138 + extra_bytes += sizeof(AnnotationArray*); 1.139 + } 1.140 + if (sizes->default_annotations_length() > 0) { 1.141 + extra_bytes += sizeof(AnnotationArray*); 1.142 + } 1.143 + 1.144 + int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; 1.145 + assert(extra_words == extra_bytes/BytesPerWord, "should already be aligned"); 1.146 + return align_object_size(header_size() + extra_words); 1.147 +} 1.148 + 1.149 +Method* ConstMethod::method() const { 1.150 + return _constants->pool_holder()->method_with_idnum(_method_idnum); 1.151 + } 1.152 + 1.153 +// linenumber table - note that length is unknown until decompression, 1.154 +// see class CompressedLineNumberReadStream. 1.155 + 1.156 +u_char* ConstMethod::compressed_linenumber_table() const { 1.157 + // Located immediately following the bytecodes. 1.158 + assert(has_linenumber_table(), "called only if table is present"); 1.159 + return code_end(); 1.160 +} 1.161 + 1.162 +// Last short in ConstMethod* before annotations 1.163 +u2* ConstMethod::last_u2_element() const { 1.164 + int offset = 0; 1.165 + if (has_method_annotations()) offset++; 1.166 + if (has_parameter_annotations()) offset++; 1.167 + if (has_type_annotations()) offset++; 1.168 + if (has_default_annotations()) offset++; 1.169 + return (u2*)((AnnotationArray**)constMethod_end() - offset) - 1; 1.170 +} 1.171 + 1.172 +u2* ConstMethod::generic_signature_index_addr() const { 1.173 + // Located at the end of the constMethod. 1.174 + assert(has_generic_signature(), "called only if generic signature exists"); 1.175 + return last_u2_element(); 1.176 +} 1.177 + 1.178 +u2* ConstMethod::method_parameters_length_addr() const { 1.179 + assert(has_method_parameters(), "called only if table is present"); 1.180 + return has_generic_signature() ? (last_u2_element() - 1) : 1.181 + last_u2_element(); 1.182 +} 1.183 + 1.184 +u2* ConstMethod::checked_exceptions_length_addr() const { 1.185 + // Located immediately before the generic signature index. 1.186 + assert(has_checked_exceptions(), "called only if table is present"); 1.187 + if(has_method_parameters()) { 1.188 + // If method parameters present, locate immediately before them. 1.189 + return (u2*)method_parameters_start() - 1; 1.190 + } else { 1.191 + // Else, the exception table is at the end of the constMethod. 1.192 + return has_generic_signature() ? (last_u2_element() - 1) : 1.193 + last_u2_element(); 1.194 + } 1.195 +} 1.196 + 1.197 +u2* ConstMethod::exception_table_length_addr() const { 1.198 + assert(has_exception_handler(), "called only if table is present"); 1.199 + if (has_checked_exceptions()) { 1.200 + // If checked_exception present, locate immediately before them. 1.201 + return (u2*) checked_exceptions_start() - 1; 1.202 + } else { 1.203 + if(has_method_parameters()) { 1.204 + // If method parameters present, locate immediately before them. 1.205 + return (u2*)method_parameters_start() - 1; 1.206 + } else { 1.207 + // Else, the exception table is at the end of the constMethod. 1.208 + return has_generic_signature() ? (last_u2_element() - 1) : 1.209 + last_u2_element(); 1.210 + } 1.211 + } 1.212 +} 1.213 + 1.214 +u2* ConstMethod::localvariable_table_length_addr() const { 1.215 + assert(has_localvariable_table(), "called only if table is present"); 1.216 + if (has_exception_handler()) { 1.217 + // If exception_table present, locate immediately before them. 1.218 + return (u2*) exception_table_start() - 1; 1.219 + } else { 1.220 + if (has_checked_exceptions()) { 1.221 + // If checked_exception present, locate immediately before them. 1.222 + return (u2*) checked_exceptions_start() - 1; 1.223 + } else { 1.224 + if(has_method_parameters()) { 1.225 + // If method parameters present, locate immediately before them. 1.226 + return (u2*)method_parameters_start() - 1; 1.227 + } else { 1.228 + // Else, the exception table is at the end of the constMethod. 1.229 + return has_generic_signature() ? (last_u2_element() - 1) : 1.230 + last_u2_element(); 1.231 + } 1.232 + } 1.233 + } 1.234 +} 1.235 + 1.236 +// Update the flags to indicate the presence of these optional fields. 1.237 +void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) { 1.238 + _flags = 0; 1.239 + if (sizes->compressed_linenumber_size() > 0) 1.240 + _flags |= _has_linenumber_table; 1.241 + if (sizes->generic_signature_index() != 0) 1.242 + _flags |= _has_generic_signature; 1.243 + if (sizes->method_parameters_length() > 0) 1.244 + _flags |= _has_method_parameters; 1.245 + if (sizes->checked_exceptions_length() > 0) 1.246 + _flags |= _has_checked_exceptions; 1.247 + if (sizes->exception_table_length() > 0) 1.248 + _flags |= _has_exception_table; 1.249 + if (sizes->localvariable_table_length() > 0) 1.250 + _flags |= _has_localvariable_table; 1.251 + 1.252 + // annotations, they are all pointer sized embedded objects so don't have 1.253 + // a length embedded also. 1.254 + if (sizes->method_annotations_length() > 0) 1.255 + _flags |= _has_method_annotations; 1.256 + if (sizes->parameter_annotations_length() > 0) 1.257 + _flags |= _has_parameter_annotations; 1.258 + if (sizes->type_annotations_length() > 0) 1.259 + _flags |= _has_type_annotations; 1.260 + if (sizes->default_annotations_length() > 0) 1.261 + _flags |= _has_default_annotations; 1.262 + 1.263 + // This code is extremely brittle and should possibly be revised. 1.264 + // The *_length_addr functions walk backwards through the 1.265 + // constMethod data, using each of the length indexes ahead of them, 1.266 + // as well as the flags variable. Therefore, the indexes must be 1.267 + // initialized in reverse order, or else they will compute the wrong 1.268 + // offsets. Moving the initialization of _flags into a separate 1.269 + // block solves *half* of the problem, but the following part will 1.270 + // still break if the order is not exactly right. 1.271 + // 1.272 + // Also, the servicability agent needs to be informed anytime 1.273 + // anything is added here. It might be advisable to have some sort 1.274 + // of indication of this inline. 1.275 + if (sizes->generic_signature_index() != 0) 1.276 + *(generic_signature_index_addr()) = sizes->generic_signature_index(); 1.277 + // New data should probably go here. 1.278 + if (sizes->method_parameters_length() > 0) 1.279 + *(method_parameters_length_addr()) = sizes->method_parameters_length(); 1.280 + if (sizes->checked_exceptions_length() > 0) 1.281 + *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length(); 1.282 + if (sizes->exception_table_length() > 0) 1.283 + *(exception_table_length_addr()) = sizes->exception_table_length(); 1.284 + if (sizes->localvariable_table_length() > 0) 1.285 + *(localvariable_table_length_addr()) = sizes->localvariable_table_length(); 1.286 +} 1.287 + 1.288 +int ConstMethod::method_parameters_length() const { 1.289 + return has_method_parameters() ? *(method_parameters_length_addr()) : 0; 1.290 +} 1.291 + 1.292 +MethodParametersElement* ConstMethod::method_parameters_start() const { 1.293 + u2* addr = method_parameters_length_addr(); 1.294 + u2 length = *addr; 1.295 + assert(length > 0, "should only be called if table is present"); 1.296 + addr -= length * sizeof(MethodParametersElement) / sizeof(u2); 1.297 + return (MethodParametersElement*) addr; 1.298 +} 1.299 + 1.300 + 1.301 +int ConstMethod::checked_exceptions_length() const { 1.302 + return has_checked_exceptions() ? *(checked_exceptions_length_addr()) : 0; 1.303 +} 1.304 + 1.305 + 1.306 +CheckedExceptionElement* ConstMethod::checked_exceptions_start() const { 1.307 + u2* addr = checked_exceptions_length_addr(); 1.308 + u2 length = *addr; 1.309 + assert(length > 0, "should only be called if table is present"); 1.310 + addr -= length * sizeof(CheckedExceptionElement) / sizeof(u2); 1.311 + return (CheckedExceptionElement*) addr; 1.312 +} 1.313 + 1.314 + 1.315 +int ConstMethod::localvariable_table_length() const { 1.316 + return has_localvariable_table() ? *(localvariable_table_length_addr()) : 0; 1.317 +} 1.318 + 1.319 + 1.320 +LocalVariableTableElement* ConstMethod::localvariable_table_start() const { 1.321 + u2* addr = localvariable_table_length_addr(); 1.322 + u2 length = *addr; 1.323 + assert(length > 0, "should only be called if table is present"); 1.324 + addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2); 1.325 + return (LocalVariableTableElement*) addr; 1.326 +} 1.327 + 1.328 +int ConstMethod::exception_table_length() const { 1.329 + return has_exception_handler() ? *(exception_table_length_addr()) : 0; 1.330 +} 1.331 + 1.332 +ExceptionTableElement* ConstMethod::exception_table_start() const { 1.333 + u2* addr = exception_table_length_addr(); 1.334 + u2 length = *addr; 1.335 + assert(length > 0, "should only be called if table is present"); 1.336 + addr -= length * sizeof(ExceptionTableElement) / sizeof(u2); 1.337 + return (ExceptionTableElement*)addr; 1.338 +} 1.339 + 1.340 +AnnotationArray** ConstMethod::method_annotations_addr() const { 1.341 + assert(has_method_annotations(), "should only be called if method annotations are present"); 1.342 + return (AnnotationArray**)constMethod_end() - 1; 1.343 +} 1.344 + 1.345 +AnnotationArray** ConstMethod::parameter_annotations_addr() const { 1.346 + assert(has_parameter_annotations(), "should only be called if method parameter annotations are present"); 1.347 + int offset = 1; 1.348 + if (has_method_annotations()) offset++; 1.349 + return (AnnotationArray**)constMethod_end() - offset; 1.350 +} 1.351 + 1.352 +AnnotationArray** ConstMethod::type_annotations_addr() const { 1.353 + assert(has_type_annotations(), "should only be called if method type annotations are present"); 1.354 + int offset = 1; 1.355 + if (has_method_annotations()) offset++; 1.356 + if (has_parameter_annotations()) offset++; 1.357 + return (AnnotationArray**)constMethod_end() - offset; 1.358 +} 1.359 + 1.360 +AnnotationArray** ConstMethod::default_annotations_addr() const { 1.361 + assert(has_default_annotations(), "should only be called if method default annotations are present"); 1.362 + int offset = 1; 1.363 + if (has_method_annotations()) offset++; 1.364 + if (has_parameter_annotations()) offset++; 1.365 + if (has_type_annotations()) offset++; 1.366 + return (AnnotationArray**)constMethod_end() - offset; 1.367 +} 1.368 + 1.369 +// copy annotations from 'cm' to 'this' 1.370 +void ConstMethod::copy_annotations_from(ConstMethod* cm) { 1.371 + if (cm->has_method_annotations()) { 1.372 + assert(has_method_annotations(), "should be allocated already"); 1.373 + set_method_annotations(cm->method_annotations()); 1.374 + } 1.375 + if (cm->has_parameter_annotations()) { 1.376 + assert(has_parameter_annotations(), "should be allocated already"); 1.377 + set_parameter_annotations(cm->parameter_annotations()); 1.378 + } 1.379 + if (cm->has_type_annotations()) { 1.380 + assert(has_type_annotations(), "should be allocated already"); 1.381 + set_type_annotations(cm->type_annotations()); 1.382 + } 1.383 + if (cm->has_default_annotations()) { 1.384 + assert(has_default_annotations(), "should be allocated already"); 1.385 + set_default_annotations(cm->default_annotations()); 1.386 + } 1.387 +} 1.388 + 1.389 +// Printing 1.390 + 1.391 +void ConstMethod::print_on(outputStream* st) const { 1.392 + ResourceMark rm; 1.393 + assert(is_constMethod(), "must be constMethod"); 1.394 + st->print_cr("%s", internal_name()); 1.395 + st->print(" - method: " INTPTR_FORMAT " ", p2i((address)method())); 1.396 + method()->print_value_on(st); st->cr(); 1.397 + if (has_stackmap_table()) { 1.398 + st->print(" - stackmap data: "); 1.399 + stackmap_data()->print_value_on(st); 1.400 + st->cr(); 1.401 + } 1.402 +} 1.403 + 1.404 +// Short version of printing ConstMethod* - just print the name of the 1.405 +// method it belongs to. 1.406 +void ConstMethod::print_value_on(outputStream* st) const { 1.407 + assert(is_constMethod(), "must be constMethod"); 1.408 + st->print(" const part of method " ); 1.409 + method()->print_value_on(st); 1.410 +} 1.411 + 1.412 +#if INCLUDE_SERVICES 1.413 +// Size Statistics 1.414 +void ConstMethod::collect_statistics(KlassSizeStats *sz) const { 1.415 + int n1, n2, n3; 1.416 + sz->_const_method_bytes += (n1 = sz->count(this)); 1.417 + sz->_bytecode_bytes += (n2 = code_size()); 1.418 + sz->_stackmap_bytes += (n3 = sz->count_array(stackmap_data())); 1.419 + 1.420 + // Count method annotations 1.421 + int a1 = 0, a2 = 0, a3 = 0, a4 = 0; 1.422 + if (has_method_annotations()) { 1.423 + sz->_methods_annotations_bytes += (a1 = sz->count_array(method_annotations())); 1.424 + } 1.425 + if (has_parameter_annotations()) { 1.426 + sz->_methods_parameter_annotations_bytes += (a2 = sz->count_array(parameter_annotations())); 1.427 + } 1.428 + if (has_type_annotations()) { 1.429 + sz->_methods_type_annotations_bytes += (a3 = sz->count_array(type_annotations())); 1.430 + } 1.431 + if (has_default_annotations()) { 1.432 + sz->_methods_default_annotations_bytes += (a4 = sz->count_array(default_annotations())); 1.433 + } 1.434 + 1.435 + int size_annotations = a1 + a2 + a3 + a4; 1.436 + 1.437 + sz->_method_all_bytes += n1 + n3 + size_annotations; // note: n2 is part of n3 1.438 + sz->_ro_bytes += n1 + n3 + size_annotations; 1.439 +} 1.440 +#endif // INCLUDE_SERVICES 1.441 + 1.442 +// Verification 1.443 + 1.444 +void ConstMethod::verify_on(outputStream* st) { 1.445 + guarantee(is_constMethod(), "object must be constMethod"); 1.446 + 1.447 + // Verification can occur during oop construction before the method or 1.448 + // other fields have been initialized. 1.449 + guarantee(method()->is_method(), "should be method"); 1.450 + 1.451 + address m_end = (address)((intptr_t) this + size()); 1.452 + address compressed_table_start = code_end(); 1.453 + guarantee(compressed_table_start <= m_end, "invalid method layout"); 1.454 + address compressed_table_end = compressed_table_start; 1.455 + // Verify line number table 1.456 + if (has_linenumber_table()) { 1.457 + CompressedLineNumberReadStream stream(compressed_linenumber_table()); 1.458 + while (stream.read_pair()) { 1.459 + guarantee(stream.bci() >= 0 && stream.bci() <= code_size(), "invalid bci in line number table"); 1.460 + } 1.461 + compressed_table_end += stream.position(); 1.462 + } 1.463 + guarantee(compressed_table_end <= m_end, "invalid method layout"); 1.464 + // Verify checked exceptions, exception table and local variable tables 1.465 + if (has_method_parameters()) { 1.466 + u2* addr = method_parameters_length_addr(); 1.467 + guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 1.468 + } 1.469 + if (has_checked_exceptions()) { 1.470 + u2* addr = checked_exceptions_length_addr(); 1.471 + guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 1.472 + } 1.473 + if (has_exception_handler()) { 1.474 + u2* addr = exception_table_length_addr(); 1.475 + guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 1.476 + } 1.477 + if (has_localvariable_table()) { 1.478 + u2* addr = localvariable_table_length_addr(); 1.479 + guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 1.480 + } 1.481 + // Check compressed_table_end relative to uncompressed_table_start 1.482 + u2* uncompressed_table_start; 1.483 + if (has_localvariable_table()) { 1.484 + uncompressed_table_start = (u2*) localvariable_table_start(); 1.485 + } else if (has_exception_handler()) { 1.486 + uncompressed_table_start = (u2*) exception_table_start(); 1.487 + } else if (has_checked_exceptions()) { 1.488 + uncompressed_table_start = (u2*) checked_exceptions_start(); 1.489 + } else if (has_method_parameters()) { 1.490 + uncompressed_table_start = (u2*) method_parameters_start(); 1.491 + } else { 1.492 + uncompressed_table_start = (u2*) m_end; 1.493 + } 1.494 + int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end; 1.495 + int max_gap = align_object_size(1)*BytesPerWord; 1.496 + guarantee(gap >= 0 && gap < max_gap, "invalid method layout"); 1.497 +}