1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/method.hpp Sat Sep 01 13:25:18 2012 -0400 1.3 @@ -0,0 +1,976 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 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_METHODOOP_HPP 1.29 +#define SHARE_VM_OOPS_METHODOOP_HPP 1.30 + 1.31 +#include "classfile/vmSymbols.hpp" 1.32 +#include "code/compressedStream.hpp" 1.33 +#include "compiler/oopMap.hpp" 1.34 +#include "interpreter/invocationCounter.hpp" 1.35 +#include "oops/annotations.hpp" 1.36 +#include "oops/constMethod.hpp" 1.37 +#include "oops/constantPool.hpp" 1.38 +#include "oops/instanceKlass.hpp" 1.39 +#include "oops/oop.hpp" 1.40 +#include "oops/typeArrayOop.hpp" 1.41 +#include "utilities/accessFlags.hpp" 1.42 +#include "utilities/growableArray.hpp" 1.43 + 1.44 +// A Method* represents a Java method. 1.45 +// 1.46 +// Memory layout (each line represents a word). Note that most applications load thousands of methods, 1.47 +// so keeping the size of this structure small has a big impact on footprint. 1.48 +// 1.49 +// We put all oops and method_size first for better gc cache locality. 1.50 +// 1.51 +// The actual bytecodes are inlined after the end of the Method struct. 1.52 +// 1.53 +// There are bits in the access_flags telling whether inlined tables are present. 1.54 +// Note that accessing the line number and local variable tables is not performance critical at all. 1.55 +// Accessing the checked exceptions table is used by reflection, so we put that last to make access 1.56 +// to it fast. 1.57 +// 1.58 +// The line number table is compressed and inlined following the byte codes. It is found as the first 1.59 +// byte following the byte codes. The checked exceptions table and the local variable table are inlined 1.60 +// after the line number table, and indexed from the end of the method. We do not compress the checked 1.61 +// exceptions table since the average length is less than 2, and do not bother to compress the local 1.62 +// variable table either since it is mostly absent. 1.63 +// 1.64 +// Note that native_function and signature_handler has to be at fixed offsets (required by the interpreter) 1.65 +// 1.66 +// |------------------------------------------------------| 1.67 +// | header | 1.68 +// | klass | 1.69 +// |------------------------------------------------------| 1.70 +// | ConstMethod* (oop) | 1.71 +// |------------------------------------------------------| 1.72 +// | methodData (oop) | 1.73 +// | interp_invocation_count | 1.74 +// |------------------------------------------------------| 1.75 +// | access_flags | 1.76 +// | vtable_index | 1.77 +// |------------------------------------------------------| 1.78 +// | result_index (C++ interpreter only) | 1.79 +// |------------------------------------------------------| 1.80 +// | method_size | max_stack | 1.81 +// | max_locals | size_of_parameters | 1.82 +// |------------------------------------------------------| 1.83 +// |intrinsic_id| flags | throwout_count | 1.84 +// |------------------------------------------------------| 1.85 +// | num_breakpoints | (unused) | 1.86 +// |------------------------------------------------------| 1.87 +// | invocation_counter | 1.88 +// | backedge_counter | 1.89 +// |------------------------------------------------------| 1.90 +// | prev_time (tiered only, 64 bit wide) | 1.91 +// | | 1.92 +// |------------------------------------------------------| 1.93 +// | rate (tiered) | 1.94 +// |------------------------------------------------------| 1.95 +// | code (pointer) | 1.96 +// | i2i (pointer) | 1.97 +// | adapter (pointer) | 1.98 +// | from_compiled_entry (pointer) | 1.99 +// | from_interpreted_entry (pointer) | 1.100 +// |------------------------------------------------------| 1.101 +// | native_function (present only if native) | 1.102 +// | signature_handler (present only if native) | 1.103 +// |------------------------------------------------------| 1.104 + 1.105 + 1.106 +class CheckedExceptionElement; 1.107 +class LocalVariableTableElement; 1.108 +class AdapterHandlerEntry; 1.109 +class MethodData; 1.110 + 1.111 +class Method : public Metadata { 1.112 + friend class VMStructs; 1.113 + private: 1.114 + ConstMethod* _constMethod; // Method read-only data. 1.115 + MethodData* _method_data; 1.116 + int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) 1.117 + AccessFlags _access_flags; // Access flags 1.118 + int _vtable_index; // vtable index of this method (see VtableIndexFlag) 1.119 + // note: can have vtables with >2**16 elements (because of inheritance) 1.120 +#ifdef CC_INTERP 1.121 + int _result_index; // C++ interpreter needs for converting results to/from stack 1.122 +#endif 1.123 + u2 _method_size; // size of this object 1.124 + u2 _max_stack; // Maximum number of entries on the expression stack 1.125 + u2 _max_locals; // Number of local variables used by this method 1.126 + u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words 1.127 + u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none) 1.128 + u1 _jfr_towrite : 1, // Flags 1.129 + _force_inline : 1, 1.130 + _hidden : 1, 1.131 + _dont_inline : 1, 1.132 + : 4; 1.133 + u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting 1.134 + u2 _number_of_breakpoints; // fullspeed debugging support 1.135 + InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations 1.136 + InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations 1.137 + 1.138 +#ifdef TIERED 1.139 + jlong _prev_time; // Previous time the rate was acquired 1.140 + float _rate; // Events (invocation and backedge counter increments) per millisecond 1.141 +#endif 1.142 + 1.143 +#ifndef PRODUCT 1.144 + int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) 1.145 +#endif 1.146 + // Entry point for calling both from and to the interpreter. 1.147 + address _i2i_entry; // All-args-on-stack calling convention 1.148 + // Adapter blob (i2c/c2i) for this Method*. Set once when method is linked. 1.149 + AdapterHandlerEntry* _adapter; 1.150 + // Entry point for calling from compiled code, to compiled code if it exists 1.151 + // or else the interpreter. 1.152 + volatile address _from_compiled_entry; // Cache of: _code ? _code->entry_point() : _adapter->c2i_entry() 1.153 + // The entry point for calling both from and to compiled code is 1.154 + // "_code->entry_point()". Because of tiered compilation and de-opt, this 1.155 + // field can come and go. It can transition from NULL to not-null at any 1.156 + // time (whenever a compile completes). It can transition from not-null to 1.157 + // NULL only at safepoints (because of a de-opt). 1.158 + nmethod* volatile _code; // Points to the corresponding piece of native code 1.159 + volatile address _from_interpreted_entry; // Cache of _code ? _adapter->i2c_entry() : _i2i_entry 1.160 + 1.161 + // Constructor 1.162 + Method(ConstMethod* xconst, AccessFlags access_flags, int size); 1.163 + public: 1.164 + static Method* allocate(ClassLoaderData* loader_data, 1.165 + int byte_code_size, 1.166 + AccessFlags access_flags, 1.167 + int compressed_line_number_size, 1.168 + int localvariable_table_length, 1.169 + int exception_table_length, 1.170 + int checked_exceptions_length, 1.171 + TRAPS); 1.172 + 1.173 + Method() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); } 1.174 + bool is_method() const volatile { return true; } 1.175 + 1.176 + // accessors for instance variables 1.177 + ConstMethod* constMethod() const { return _constMethod; } 1.178 + void set_constMethod(ConstMethod* xconst) { _constMethod = xconst; } 1.179 + 1.180 + 1.181 + static address make_adapters(methodHandle mh, TRAPS); 1.182 + volatile address from_compiled_entry() const { return (address)OrderAccess::load_ptr_acquire(&_from_compiled_entry); } 1.183 + volatile address from_interpreted_entry() const{ return (address)OrderAccess::load_ptr_acquire(&_from_interpreted_entry); } 1.184 + 1.185 + // access flag 1.186 + AccessFlags access_flags() const { return _access_flags; } 1.187 + void set_access_flags(AccessFlags flags) { _access_flags = flags; } 1.188 + 1.189 + // name 1.190 + Symbol* name() const { return constants()->symbol_at(name_index()); } 1.191 + int name_index() const { return constMethod()->name_index(); } 1.192 + void set_name_index(int index) { constMethod()->set_name_index(index); } 1.193 + 1.194 + // signature 1.195 + Symbol* signature() const { return constants()->symbol_at(signature_index()); } 1.196 + int signature_index() const { return constMethod()->signature_index(); } 1.197 + void set_signature_index(int index) { constMethod()->set_signature_index(index); } 1.198 + 1.199 + // generics support 1.200 + Symbol* generic_signature() const { int idx = generic_signature_index(); return ((idx != 0) ? constants()->symbol_at(idx) : (Symbol*)NULL); } 1.201 + int generic_signature_index() const { return constMethod()->generic_signature_index(); } 1.202 + void set_generic_signature_index(int index) { constMethod()->set_generic_signature_index(index); } 1.203 + 1.204 + // annotations support 1.205 + AnnotationArray* annotations() const { 1.206 + InstanceKlass* ik = InstanceKlass::cast(method_holder()); 1.207 + if (ik->annotations() == NULL) { 1.208 + return NULL; 1.209 + } 1.210 + return ik->annotations()->get_method_annotations_of(method_idnum()); 1.211 + } 1.212 + AnnotationArray* parameter_annotations() const { 1.213 + InstanceKlass* ik = InstanceKlass::cast(method_holder()); 1.214 + if (ik->annotations() == NULL) { 1.215 + return NULL; 1.216 + } 1.217 + return ik->annotations()->get_method_parameter_annotations_of(method_idnum()); 1.218 + } 1.219 + AnnotationArray* annotation_default() const { 1.220 + InstanceKlass* ik = InstanceKlass::cast(method_holder()); 1.221 + if (ik->annotations() == NULL) { 1.222 + return NULL; 1.223 + } 1.224 + return ik->annotations()->get_method_default_annotations_of(method_idnum()); 1.225 + } 1.226 + 1.227 +#ifdef CC_INTERP 1.228 + void set_result_index(BasicType type); 1.229 + int result_index() { return _result_index; } 1.230 +#endif 1.231 + 1.232 + // Helper routine: get klass name + "." + method name + signature as 1.233 + // C string, for the purpose of providing more useful NoSuchMethodErrors 1.234 + // and fatal error handling. The string is allocated in resource 1.235 + // area if a buffer is not provided by the caller. 1.236 + char* name_and_sig_as_C_string() const; 1.237 + char* name_and_sig_as_C_string(char* buf, int size) const; 1.238 + 1.239 + // Static routine in the situations we don't have a Method* 1.240 + static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature); 1.241 + static char* name_and_sig_as_C_string(Klass* klass, Symbol* method_name, Symbol* signature, char* buf, int size); 1.242 + 1.243 + Bytecodes::Code java_code_at(int bci) const { 1.244 + return Bytecodes::java_code_at(this, bcp_from(bci)); 1.245 + } 1.246 + Bytecodes::Code code_at(int bci) const { 1.247 + return Bytecodes::code_at(this, bcp_from(bci)); 1.248 + } 1.249 + 1.250 + // JVMTI breakpoints 1.251 + Bytecodes::Code orig_bytecode_at(int bci) const; 1.252 + void set_orig_bytecode_at(int bci, Bytecodes::Code code); 1.253 + void set_breakpoint(int bci); 1.254 + void clear_breakpoint(int bci); 1.255 + void clear_all_breakpoints(); 1.256 + // Tracking number of breakpoints, for fullspeed debugging. 1.257 + // Only mutated by VM thread. 1.258 + u2 number_of_breakpoints() const { return _number_of_breakpoints; } 1.259 + void incr_number_of_breakpoints() { ++_number_of_breakpoints; } 1.260 + void decr_number_of_breakpoints() { --_number_of_breakpoints; } 1.261 + // Initialization only 1.262 + void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } 1.263 + 1.264 + // index into InstanceKlass methods() array 1.265 + // note: also used by jfr 1.266 + u2 method_idnum() const { return constMethod()->method_idnum(); } 1.267 + void set_method_idnum(u2 idnum) { constMethod()->set_method_idnum(idnum); } 1.268 + 1.269 + // code size 1.270 + int code_size() const { return constMethod()->code_size(); } 1.271 + 1.272 + // method size 1.273 + int method_size() const { return _method_size; } 1.274 + void set_method_size(int size) { 1.275 + assert(0 <= size && size < (1 << 16), "invalid method size"); 1.276 + _method_size = size; 1.277 + } 1.278 + 1.279 + // constant pool for Klass* holding this method 1.280 + ConstantPool* constants() const { return constMethod()->constants(); } 1.281 + void set_constants(ConstantPool* c) { constMethod()->set_constants(c); } 1.282 + 1.283 + // max stack 1.284 + // return original max stack size for method verification 1.285 + int verifier_max_stack() const { return _max_stack; } 1.286 + int max_stack() const { return _max_stack + extra_stack_entries(); } 1.287 + void set_max_stack(int size) { _max_stack = size; } 1.288 + 1.289 + // max locals 1.290 + int max_locals() const { return _max_locals; } 1.291 + void set_max_locals(int size) { _max_locals = size; } 1.292 + 1.293 + int highest_comp_level() const; 1.294 + void set_highest_comp_level(int level); 1.295 + int highest_osr_comp_level() const; 1.296 + void set_highest_osr_comp_level(int level); 1.297 + 1.298 + // Count of times method was exited via exception while interpreting 1.299 + void interpreter_throwout_increment() { 1.300 + if (_interpreter_throwout_count < 65534) { 1.301 + _interpreter_throwout_count++; 1.302 + } 1.303 + } 1.304 + 1.305 + int interpreter_throwout_count() const { return _interpreter_throwout_count; } 1.306 + void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; } 1.307 + 1.308 + // size of parameters 1.309 + int size_of_parameters() const { return _size_of_parameters; } 1.310 + 1.311 + bool has_stackmap_table() const { 1.312 + return constMethod()->has_stackmap_table(); 1.313 + } 1.314 + 1.315 + Array<u1>* stackmap_data() const { 1.316 + return constMethod()->stackmap_data(); 1.317 + } 1.318 + 1.319 + void set_stackmap_data(Array<u1>* sd) { 1.320 + constMethod()->set_stackmap_data(sd); 1.321 + } 1.322 + 1.323 + // exception handler table 1.324 + bool has_exception_handler() const 1.325 + { return constMethod()->has_exception_handler(); } 1.326 + int exception_table_length() const 1.327 + { return constMethod()->exception_table_length(); } 1.328 + ExceptionTableElement* exception_table_start() const 1.329 + { return constMethod()->exception_table_start(); } 1.330 + 1.331 + // Finds the first entry point bci of an exception handler for an 1.332 + // exception of klass ex_klass thrown at throw_bci. A value of NULL 1.333 + // for ex_klass indicates that the exception klass is not known; in 1.334 + // this case it matches any constraint class. Returns -1 if the 1.335 + // exception cannot be handled in this method. The handler 1.336 + // constraint classes are loaded if necessary. Note that this may 1.337 + // throw an exception if loading of the constraint classes causes 1.338 + // an IllegalAccessError (bugid 4307310) or an OutOfMemoryError. 1.339 + // If an exception is thrown, returns the bci of the 1.340 + // exception handler which caused the exception to be thrown, which 1.341 + // is needed for proper retries. See, for example, 1.342 + // InterpreterRuntime::exception_handler_for_exception. 1.343 + int fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS); 1.344 + 1.345 + // method data access 1.346 + MethodData* method_data() const { 1.347 + return _method_data; 1.348 + } 1.349 + void set_method_data(MethodData* data) { 1.350 + _method_data = data; 1.351 + } 1.352 + 1.353 + // invocation counter 1.354 + InvocationCounter* invocation_counter() { return &_invocation_counter; } 1.355 + InvocationCounter* backedge_counter() { return &_backedge_counter; } 1.356 + 1.357 +#ifdef TIERED 1.358 + // We are reusing interpreter_invocation_count as a holder for the previous event count! 1.359 + // We can do that since interpreter_invocation_count is not used in tiered. 1.360 + int prev_event_count() const { return _interpreter_invocation_count; } 1.361 + void set_prev_event_count(int count) { _interpreter_invocation_count = count; } 1.362 + jlong prev_time() const { return _prev_time; } 1.363 + void set_prev_time(jlong time) { _prev_time = time; } 1.364 + float rate() const { return _rate; } 1.365 + void set_rate(float rate) { _rate = rate; } 1.366 +#endif 1.367 + 1.368 + int invocation_count(); 1.369 + int backedge_count(); 1.370 + 1.371 + bool was_executed_more_than(int n); 1.372 + bool was_never_executed() { return !was_executed_more_than(0); } 1.373 + 1.374 + static void build_interpreter_method_data(methodHandle method, TRAPS); 1.375 + 1.376 + int interpreter_invocation_count() { 1.377 + if (TieredCompilation) return invocation_count(); 1.378 + else return _interpreter_invocation_count; 1.379 + } 1.380 + void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; } 1.381 + int increment_interpreter_invocation_count() { 1.382 + if (TieredCompilation) ShouldNotReachHere(); 1.383 + return ++_interpreter_invocation_count; 1.384 + } 1.385 + 1.386 +#ifndef PRODUCT 1.387 + int compiled_invocation_count() const { return _compiled_invocation_count; } 1.388 + void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; } 1.389 +#endif // not PRODUCT 1.390 + 1.391 + // Clear (non-shared space) pointers which could not be relevant 1.392 + // if this (shared) method were mapped into another JVM. 1.393 + void remove_unshareable_info(); 1.394 + 1.395 + // nmethod/verified compiler entry 1.396 + address verified_code_entry(); 1.397 + bool check_code() const; // Not inline to avoid circular ref 1.398 + nmethod* volatile code() const { assert( check_code(), "" ); return (nmethod *)OrderAccess::load_ptr_acquire(&_code); } 1.399 + void clear_code(); // Clear out any compiled code 1.400 + static void set_code(methodHandle mh, nmethod* code); 1.401 + void set_adapter_entry(AdapterHandlerEntry* adapter) { _adapter = adapter; } 1.402 + address get_i2c_entry(); 1.403 + address get_c2i_entry(); 1.404 + address get_c2i_unverified_entry(); 1.405 + AdapterHandlerEntry* adapter() { return _adapter; } 1.406 + // setup entry points 1.407 + void link_method(methodHandle method, TRAPS); 1.408 + // clear entry points. Used by sharing code 1.409 + void unlink_method(); 1.410 + 1.411 + // vtable index 1.412 + enum VtableIndexFlag { 1.413 + // Valid vtable indexes are non-negative (>= 0). 1.414 + // These few negative values are used as sentinels. 1.415 + highest_unused_vtable_index_value = -5, 1.416 + invalid_vtable_index = -4, // distinct from any valid vtable index 1.417 + garbage_vtable_index = -3, // not yet linked; no vtable layout yet 1.418 + nonvirtual_vtable_index = -2 // there is no need for vtable dispatch 1.419 + // 6330203 Note: Do not use -1, which was overloaded with many meanings. 1.420 + }; 1.421 + DEBUG_ONLY(bool valid_vtable_index() const { return _vtable_index >= nonvirtual_vtable_index; }) 1.422 + int vtable_index() const { assert(valid_vtable_index(), ""); 1.423 + return _vtable_index; } 1.424 + void set_vtable_index(int index) { _vtable_index = index; } 1.425 + 1.426 + // interpreter entry 1.427 + address interpreter_entry() const { return _i2i_entry; } 1.428 + // Only used when first initialize so we can set _i2i_entry and _from_interpreted_entry 1.429 + void set_interpreter_entry(address entry) { _i2i_entry = entry; _from_interpreted_entry = entry; } 1.430 + int interpreter_kind(void) { 1.431 + return constMethod()->interpreter_kind(); 1.432 + } 1.433 + void set_interpreter_kind(); 1.434 + void set_interpreter_kind(int kind) { 1.435 + constMethod()->set_interpreter_kind(kind); 1.436 + } 1.437 + 1.438 + // native function (used for native methods only) 1.439 + enum { 1.440 + native_bind_event_is_interesting = true 1.441 + }; 1.442 + address native_function() const { return *(native_function_addr()); } 1.443 + address critical_native_function(); 1.444 + 1.445 + // Must specify a real function (not NULL). 1.446 + // Use clear_native_function() to unregister. 1.447 + void set_native_function(address function, bool post_event_flag); 1.448 + bool has_native_function() const; 1.449 + void clear_native_function(); 1.450 + 1.451 + // signature handler (used for native methods only) 1.452 + address signature_handler() const { return *(signature_handler_addr()); } 1.453 + void set_signature_handler(address handler); 1.454 + 1.455 + // Interpreter oopmap support 1.456 + void mask_for(int bci, InterpreterOopMap* mask); 1.457 + 1.458 +#ifndef PRODUCT 1.459 + // operations on invocation counter 1.460 + void print_invocation_count(); 1.461 +#endif 1.462 + 1.463 + // byte codes 1.464 + void set_code(address code) { return constMethod()->set_code(code); } 1.465 + address code_base() const { return constMethod()->code_base(); } 1.466 + bool contains(address bcp) const { return constMethod()->contains(bcp); } 1.467 + 1.468 + // prints byte codes 1.469 + void print_codes() const { print_codes_on(tty); } 1.470 + void print_codes_on(outputStream* st) const PRODUCT_RETURN; 1.471 + void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN; 1.472 + 1.473 + // checked exceptions 1.474 + int checked_exceptions_length() const 1.475 + { return constMethod()->checked_exceptions_length(); } 1.476 + CheckedExceptionElement* checked_exceptions_start() const 1.477 + { return constMethod()->checked_exceptions_start(); } 1.478 + 1.479 + // localvariable table 1.480 + bool has_localvariable_table() const 1.481 + { return constMethod()->has_localvariable_table(); } 1.482 + int localvariable_table_length() const 1.483 + { return constMethod()->localvariable_table_length(); } 1.484 + LocalVariableTableElement* localvariable_table_start() const 1.485 + { return constMethod()->localvariable_table_start(); } 1.486 + 1.487 + bool has_linenumber_table() const 1.488 + { return constMethod()->has_linenumber_table(); } 1.489 + u_char* compressed_linenumber_table() const 1.490 + { return constMethod()->compressed_linenumber_table(); } 1.491 + 1.492 + // method holder (the Klass* holding this method) 1.493 + Klass* method_holder() const { return constants()->pool_holder(); } 1.494 + 1.495 + void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments) 1.496 + Symbol* klass_name() const; // returns the name of the method holder 1.497 + BasicType result_type() const; // type of the method result 1.498 + int result_type_index() const; // type index of the method result 1.499 + bool is_returning_oop() const { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); } 1.500 + bool is_returning_fp() const { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); } 1.501 + 1.502 + // Checked exceptions thrown by this method (resolved to mirrors) 1.503 + objArrayHandle resolved_checked_exceptions(TRAPS) { return resolved_checked_exceptions_impl(this, THREAD); } 1.504 + 1.505 + // Access flags 1.506 + bool is_public() const { return access_flags().is_public(); } 1.507 + bool is_private() const { return access_flags().is_private(); } 1.508 + bool is_protected() const { return access_flags().is_protected(); } 1.509 + bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); } 1.510 + bool is_static() const { return access_flags().is_static(); } 1.511 + bool is_final() const { return access_flags().is_final(); } 1.512 + bool is_synchronized() const { return access_flags().is_synchronized();} 1.513 + bool is_native() const { return access_flags().is_native(); } 1.514 + bool is_abstract() const { return access_flags().is_abstract(); } 1.515 + bool is_strict() const { return access_flags().is_strict(); } 1.516 + bool is_synthetic() const { return access_flags().is_synthetic(); } 1.517 + 1.518 + // returns true if contains only return operation 1.519 + bool is_empty_method() const; 1.520 + 1.521 + // returns true if this is a vanilla constructor 1.522 + bool is_vanilla_constructor() const; 1.523 + 1.524 + // checks method and its method holder 1.525 + bool is_final_method() const; 1.526 + bool is_strict_method() const; 1.527 + 1.528 + // true if method needs no dynamic dispatch (final and/or no vtable entry) 1.529 + bool can_be_statically_bound() const; 1.530 + 1.531 + // returns true if the method has any backward branches. 1.532 + bool has_loops() { 1.533 + return access_flags().loops_flag_init() ? access_flags().has_loops() : compute_has_loops_flag(); 1.534 + }; 1.535 + 1.536 + bool compute_has_loops_flag(); 1.537 + 1.538 + bool has_jsrs() { 1.539 + return access_flags().has_jsrs(); 1.540 + }; 1.541 + void set_has_jsrs() { 1.542 + _access_flags.set_has_jsrs(); 1.543 + } 1.544 + 1.545 + // returns true if the method has any monitors. 1.546 + bool has_monitors() const { return is_synchronized() || access_flags().has_monitor_bytecodes(); } 1.547 + bool has_monitor_bytecodes() const { return access_flags().has_monitor_bytecodes(); } 1.548 + 1.549 + void set_has_monitor_bytecodes() { _access_flags.set_has_monitor_bytecodes(); } 1.550 + 1.551 + // monitor matching. This returns a conservative estimate of whether the monitorenter/monitorexit bytecodes 1.552 + // propererly nest in the method. It might return false, even though they actually nest properly, since the info. 1.553 + // has not been computed yet. 1.554 + bool guaranteed_monitor_matching() const { return access_flags().is_monitor_matching(); } 1.555 + void set_guaranteed_monitor_matching() { _access_flags.set_monitor_matching(); } 1.556 + 1.557 + // returns true if the method is an accessor function (setter/getter). 1.558 + bool is_accessor() const; 1.559 + 1.560 + // returns true if the method is an initializer (<init> or <clinit>). 1.561 + bool is_initializer() const; 1.562 + 1.563 + // returns true if the method is static OR if the classfile version < 51 1.564 + bool has_valid_initializer_flags() const; 1.565 + 1.566 + // returns true if the method name is <clinit> and the method has 1.567 + // valid static initializer flags. 1.568 + bool is_static_initializer() const; 1.569 + 1.570 + // compiled code support 1.571 + // NOTE: code() is inherently racy as deopt can be clearing code 1.572 + // simultaneously. Use with caution. 1.573 + bool has_compiled_code() const { return code() != NULL; } 1.574 + 1.575 + // sizing 1.576 + static int header_size() { return sizeof(Method)/HeapWordSize; } 1.577 + static int size(bool is_native); 1.578 + int size() const { return method_size(); } 1.579 + 1.580 + // interpreter support 1.581 + static ByteSize const_offset() { return byte_offset_of(Method, _constMethod ); } 1.582 + static ByteSize access_flags_offset() { return byte_offset_of(Method, _access_flags ); } 1.583 +#ifdef CC_INTERP 1.584 + static ByteSize result_index_offset() { return byte_offset_of(Method, _result_index ); } 1.585 +#endif /* CC_INTERP */ 1.586 + static ByteSize size_of_locals_offset() { return byte_offset_of(Method, _max_locals ); } 1.587 + static ByteSize size_of_parameters_offset() { return byte_offset_of(Method, _size_of_parameters); } 1.588 + static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } 1.589 + static ByteSize code_offset() { return byte_offset_of(Method, _code); } 1.590 + static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); } 1.591 + static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); } 1.592 + static ByteSize method_data_offset() { 1.593 + return byte_offset_of(Method, _method_data); 1.594 + } 1.595 + static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); } 1.596 +#ifndef PRODUCT 1.597 + static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } 1.598 +#endif // not PRODUCT 1.599 + static ByteSize native_function_offset() { return in_ByteSize(sizeof(Method)); } 1.600 + static ByteSize from_interpreted_offset() { return byte_offset_of(Method, _from_interpreted_entry ); } 1.601 + static ByteSize interpreter_entry_offset() { return byte_offset_of(Method, _i2i_entry ); } 1.602 + static ByteSize signature_handler_offset() { return in_ByteSize(sizeof(Method) + wordSize); } 1.603 + static ByteSize max_stack_offset() { return byte_offset_of(Method, _max_stack ); } 1.604 + 1.605 + // for code generation 1.606 + static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } 1.607 + static int interpreter_invocation_counter_offset_in_bytes() 1.608 + { return offset_of(Method, _interpreter_invocation_count); } 1.609 + static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } 1.610 + static int intrinsic_id_size_in_bytes() { return sizeof(u1); } 1.611 + 1.612 + // Static methods that are used to implement member methods where an exposed this pointer 1.613 + // is needed due to possible GCs 1.614 + static objArrayHandle resolved_checked_exceptions_impl(Method* this_oop, TRAPS); 1.615 + 1.616 + // Returns the byte code index from the byte code pointer 1.617 + int bci_from(address bcp) const; 1.618 + address bcp_from(int bci) const; 1.619 + int validate_bci_from_bcx(intptr_t bcx) const; 1.620 + 1.621 + // Returns the line number for a bci if debugging information for the method is prowided, 1.622 + // -1 is returned otherwise. 1.623 + int line_number_from_bci(int bci) const; 1.624 + 1.625 + // Reflection support 1.626 + bool is_overridden_in(Klass* k) const; 1.627 + 1.628 + // JSR 292 support 1.629 + bool is_method_handle_intrinsic() const; // MethodHandles::is_signature_polymorphic_intrinsic(intrinsic_id) 1.630 + bool is_compiled_lambda_form() const; // intrinsic_id() == vmIntrinsics::_compiledLambdaForm 1.631 + bool has_member_arg() const; // intrinsic_id() == vmIntrinsics::_linkToSpecial, etc. 1.632 + static methodHandle make_method_handle_intrinsic(vmIntrinsics::ID iid, // _invokeBasic, _linkToVirtual 1.633 + Symbol* signature, //anything at all 1.634 + TRAPS); 1.635 + static Klass* check_non_bcp_klass(Klass* klass); 1.636 + // these operate only on invoke methods: 1.637 + // presize interpreter frames for extra interpreter stack entries, if needed 1.638 + // method handles want to be able to push a few extra values (e.g., a bound receiver), and 1.639 + // invokedynamic sometimes needs to push a bootstrap method, call site, and arglist, 1.640 + // all without checking for a stack overflow 1.641 + static int extra_stack_entries() { return EnableInvokeDynamic ? 2 : 0; } 1.642 + static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize() 1.643 + 1.644 + // RedefineClasses() support: 1.645 + bool is_old() const { return access_flags().is_old(); } 1.646 + void set_is_old() { _access_flags.set_is_old(); } 1.647 + bool is_obsolete() const { return access_flags().is_obsolete(); } 1.648 + void set_is_obsolete() { _access_flags.set_is_obsolete(); } 1.649 + bool on_stack() const { return access_flags().on_stack(); } 1.650 + void set_on_stack(const bool value); 1.651 + 1.652 + // see the definition in Method*.cpp for the gory details 1.653 + bool should_not_be_cached() const; 1.654 + 1.655 + // JVMTI Native method prefixing support: 1.656 + bool is_prefixed_native() const { return access_flags().is_prefixed_native(); } 1.657 + void set_is_prefixed_native() { _access_flags.set_is_prefixed_native(); } 1.658 + 1.659 + // Rewriting support 1.660 + static methodHandle clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length, 1.661 + u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS); 1.662 + 1.663 + // jmethodID handling 1.664 + // Because the useful life-span of a jmethodID cannot be determined, 1.665 + // once created they are never reclaimed. The methods to which they refer, 1.666 + // however, can be GC'ed away if the class is unloaded or if the method is 1.667 + // made obsolete or deleted -- in these cases, the jmethodID 1.668 + // refers to NULL (as is the case for any weak reference). 1.669 + static jmethodID make_jmethod_id(ClassLoaderData* loader_data, Method* mh); 1.670 + static void destroy_jmethod_id(ClassLoaderData* loader_data, jmethodID mid); 1.671 + 1.672 + // Use resolve_jmethod_id() in situations where the caller is expected 1.673 + // to provide a valid jmethodID; the only sanity checks are in asserts; 1.674 + // result guaranteed not to be NULL. 1.675 + inline static Method* resolve_jmethod_id(jmethodID mid) { 1.676 + assert(mid != NULL, "JNI method id should not be null"); 1.677 + return *((Method**)mid); 1.678 + } 1.679 + 1.680 + // Use checked_resolve_jmethod_id() in situations where the caller 1.681 + // should provide a valid jmethodID, but might not. NULL is returned 1.682 + // when the jmethodID does not refer to a valid method. 1.683 + static Method* checked_resolve_jmethod_id(jmethodID mid); 1.684 + 1.685 + static void change_method_associated_with_jmethod_id(jmethodID old_jmid_ptr, Method* new_method); 1.686 + static bool is_method_id(jmethodID mid); 1.687 + 1.688 + // Clear methods 1.689 + static void clear_jmethod_ids(ClassLoaderData* loader_data); 1.690 + static void print_jmethod_ids(ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN; 1.691 + 1.692 + // Get this method's jmethodID -- allocate if it doesn't exist 1.693 + jmethodID jmethod_id() { methodHandle this_h(this); 1.694 + return InstanceKlass::get_jmethod_id(InstanceKlass::cast(method_holder()), this_h); } 1.695 + 1.696 + // Lookup the jmethodID for this method. Return NULL if not found. 1.697 + // NOTE that this function can be called from a signal handler 1.698 + // (see AsyncGetCallTrace support for Forte Analyzer) and this 1.699 + // needs to be async-safe. No allocation should be done and 1.700 + // so handles are not used to avoid deadlock. 1.701 + jmethodID find_jmethod_id_or_null() { return InstanceKlass::cast(method_holder())->jmethod_id_or_null(this); } 1.702 + 1.703 + // JNI static invoke cached itable index accessors 1.704 + int cached_itable_index() { return InstanceKlass::cast(method_holder())->cached_itable_index(method_idnum()); } 1.705 + void set_cached_itable_index(int index) { InstanceKlass::cast(method_holder())->set_cached_itable_index(method_idnum(), index); } 1.706 + 1.707 + // Support for inlining of intrinsic methods 1.708 + vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; } 1.709 + void set_intrinsic_id(vmIntrinsics::ID id) { _intrinsic_id = (u1) id; } 1.710 + 1.711 + // Helper routines for intrinsic_id() and vmIntrinsics::method(). 1.712 + void init_intrinsic_id(); // updates from _none if a match 1.713 + static vmSymbols::SID klass_id_for_intrinsics(Klass* holder); 1.714 + 1.715 + bool jfr_towrite() { return _jfr_towrite; } 1.716 + void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; } 1.717 + 1.718 + bool force_inline() { return _force_inline; } 1.719 + void set_force_inline(bool x) { _force_inline = x; } 1.720 + bool dont_inline() { return _dont_inline; } 1.721 + void set_dont_inline(bool x) { _dont_inline = x; } 1.722 + bool is_hidden() { return _hidden; } 1.723 + void set_hidden(bool x) { _hidden = x; } 1.724 + 1.725 + // On-stack replacement support 1.726 + bool has_osr_nmethod(int level, bool match_level) { 1.727 + return InstanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL; 1.728 + } 1.729 + 1.730 + nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) { 1.731 + return InstanceKlass::cast(method_holder())->lookup_osr_nmethod(this, bci, level, match_level); 1.732 + } 1.733 + 1.734 + // Inline cache support 1.735 + void cleanup_inline_caches(); 1.736 + 1.737 + // Find if klass for method is loaded 1.738 + bool is_klass_loaded_by_klass_index(int klass_index) const; 1.739 + bool is_klass_loaded(int refinfo_index, bool must_be_resolved = false) const; 1.740 + 1.741 + // Indicates whether compilation failed earlier for this method, or 1.742 + // whether it is not compilable for another reason like having a 1.743 + // breakpoint set in it. 1.744 + bool is_not_compilable(int comp_level = CompLevel_any) const; 1.745 + void set_not_compilable(int comp_level = CompLevel_all, bool report = true); 1.746 + void set_not_compilable_quietly(int comp_level = CompLevel_all) { 1.747 + set_not_compilable(comp_level, false); 1.748 + } 1.749 + bool is_not_osr_compilable(int comp_level = CompLevel_any) const { 1.750 + return is_not_compilable(comp_level) || access_flags().is_not_osr_compilable(); 1.751 + } 1.752 + void set_not_osr_compilable() { _access_flags.set_not_osr_compilable(); } 1.753 + bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } 1.754 + void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } 1.755 + bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); } 1.756 + void set_not_c2_compilable() { _access_flags.set_not_c2_compilable(); } 1.757 + 1.758 + // Background compilation support 1.759 + bool queued_for_compilation() const { return access_flags().queued_for_compilation(); } 1.760 + void set_queued_for_compilation() { _access_flags.set_queued_for_compilation(); } 1.761 + void clear_queued_for_compilation() { _access_flags.clear_queued_for_compilation(); } 1.762 + 1.763 + // Resolve all classes in signature, return 'true' if successful 1.764 + static bool load_signature_classes(methodHandle m, TRAPS); 1.765 + 1.766 + // Return if true if not all classes references in signature, including return type, has been loaded 1.767 + static bool has_unloaded_classes_in_signature(methodHandle m, TRAPS); 1.768 + 1.769 + // Printing 1.770 + void print_short_name(outputStream* st = tty) /*PRODUCT_RETURN*/; // prints as klassname::methodname; Exposed so field engineers can debug VM 1.771 + void print_name(outputStream* st = tty) PRODUCT_RETURN; // prints as "virtual void foo(int)" 1.772 + 1.773 + // Helper routine used for method sorting 1.774 + static void sort_methods(Array<Method*>* methods, 1.775 + Array<AnnotationArray*>* methods_annotations, 1.776 + Array<AnnotationArray*>* methods_parameter_annotations, 1.777 + Array<AnnotationArray*>* methods_default_annotations, 1.778 + bool idempotent = false); 1.779 + 1.780 + // size of parameters 1.781 + void set_size_of_parameters(int size) { _size_of_parameters = size; } 1.782 + 1.783 + // Deallocation function for redefine classes or if an error occurs 1.784 + void deallocate_contents(ClassLoaderData* loader_data); 1.785 + 1.786 + // Printing 1.787 +#ifndef PRODUCT 1.788 + void print_on(outputStream* st) const; 1.789 +#endif 1.790 + void print_value_on(outputStream* st) const; 1.791 + 1.792 + const char* internal_name() const { return "{method}"; } 1.793 + 1.794 + // Verify 1.795 + void verify() { verify_on(tty); } 1.796 + void verify_on(outputStream* st); 1.797 + 1.798 + private: 1.799 + 1.800 + // Inlined elements 1.801 + address* native_function_addr() const { assert(is_native(), "must be native"); return (address*) (this+1); } 1.802 + address* signature_handler_addr() const { return native_function_addr() + 1; } 1.803 +}; 1.804 + 1.805 + 1.806 +// Utility class for compressing line number tables 1.807 + 1.808 +class CompressedLineNumberWriteStream: public CompressedWriteStream { 1.809 + private: 1.810 + int _bci; 1.811 + int _line; 1.812 + public: 1.813 + // Constructor 1.814 + CompressedLineNumberWriteStream(int initial_size) : CompressedWriteStream(initial_size), _bci(0), _line(0) {} 1.815 + CompressedLineNumberWriteStream(u_char* buffer, int initial_size) : CompressedWriteStream(buffer, initial_size), _bci(0), _line(0) {} 1.816 + 1.817 + // Write (bci, line number) pair to stream 1.818 + void write_pair_regular(int bci_delta, int line_delta); 1.819 + 1.820 + inline void write_pair_inline(int bci, int line) { 1.821 + int bci_delta = bci - _bci; 1.822 + int line_delta = line - _line; 1.823 + _bci = bci; 1.824 + _line = line; 1.825 + // Skip (0,0) deltas - they do not add information and conflict with terminator. 1.826 + if (bci_delta == 0 && line_delta == 0) return; 1.827 + // Check if bci is 5-bit and line number 3-bit unsigned. 1.828 + if (((bci_delta & ~0x1F) == 0) && ((line_delta & ~0x7) == 0)) { 1.829 + // Compress into single byte. 1.830 + jubyte value = ((jubyte) bci_delta << 3) | (jubyte) line_delta; 1.831 + // Check that value doesn't match escape character. 1.832 + if (value != 0xFF) { 1.833 + write_byte(value); 1.834 + return; 1.835 + } 1.836 + } 1.837 + write_pair_regular(bci_delta, line_delta); 1.838 + } 1.839 + 1.840 +// Windows AMD64 + Apr 2005 PSDK with /O2 generates bad code for write_pair. 1.841 +// Disabling optimization doesn't work for methods in header files 1.842 +// so we force it to call through the non-optimized version in the .cpp. 1.843 +// It's gross, but it's the only way we can ensure that all callers are 1.844 +// fixed. _MSC_VER is defined by the windows compiler 1.845 +#if defined(_M_AMD64) && _MSC_VER >= 1400 1.846 + void write_pair(int bci, int line); 1.847 +#else 1.848 + void write_pair(int bci, int line) { write_pair_inline(bci, line); } 1.849 +#endif 1.850 + 1.851 + // Write end-of-stream marker 1.852 + void write_terminator() { write_byte(0); } 1.853 +}; 1.854 + 1.855 + 1.856 +// Utility class for decompressing line number tables 1.857 + 1.858 +class CompressedLineNumberReadStream: public CompressedReadStream { 1.859 + private: 1.860 + int _bci; 1.861 + int _line; 1.862 + public: 1.863 + // Constructor 1.864 + CompressedLineNumberReadStream(u_char* buffer); 1.865 + // Read (bci, line number) pair from stream. Returns false at end-of-stream. 1.866 + bool read_pair(); 1.867 + // Accessing bci and line number (after calling read_pair) 1.868 + int bci() const { return _bci; } 1.869 + int line() const { return _line; } 1.870 +}; 1.871 + 1.872 + 1.873 +/// Fast Breakpoints. 1.874 + 1.875 +// If this structure gets more complicated (because bpts get numerous), 1.876 +// move it into its own header. 1.877 + 1.878 +// There is presently no provision for concurrent access 1.879 +// to breakpoint lists, which is only OK for JVMTI because 1.880 +// breakpoints are written only at safepoints, and are read 1.881 +// concurrently only outside of safepoints. 1.882 + 1.883 +class BreakpointInfo : public CHeapObj<mtClass> { 1.884 + friend class VMStructs; 1.885 + private: 1.886 + Bytecodes::Code _orig_bytecode; 1.887 + int _bci; 1.888 + u2 _name_index; // of method 1.889 + u2 _signature_index; // of method 1.890 + BreakpointInfo* _next; // simple storage allocation 1.891 + 1.892 + public: 1.893 + BreakpointInfo(Method* m, int bci); 1.894 + 1.895 + // accessors 1.896 + Bytecodes::Code orig_bytecode() { return _orig_bytecode; } 1.897 + void set_orig_bytecode(Bytecodes::Code code) { _orig_bytecode = code; } 1.898 + int bci() { return _bci; } 1.899 + 1.900 + BreakpointInfo* next() const { return _next; } 1.901 + void set_next(BreakpointInfo* n) { _next = n; } 1.902 + 1.903 + // helps for searchers 1.904 + bool match(const Method* m, int bci) { 1.905 + return bci == _bci && match(m); 1.906 + } 1.907 + 1.908 + bool match(const Method* m) { 1.909 + return _name_index == m->name_index() && 1.910 + _signature_index == m->signature_index(); 1.911 + } 1.912 + 1.913 + void set(Method* method); 1.914 + void clear(Method* method); 1.915 +}; 1.916 + 1.917 +// Utility class for access exception handlers 1.918 +class ExceptionTable : public StackObj { 1.919 + private: 1.920 + ExceptionTableElement* _table; 1.921 + u2 _length; 1.922 + 1.923 + public: 1.924 + ExceptionTable(Method* m) { 1.925 + if (m->has_exception_handler()) { 1.926 + _table = m->exception_table_start(); 1.927 + _length = m->exception_table_length(); 1.928 + } else { 1.929 + _table = NULL; 1.930 + _length = 0; 1.931 + } 1.932 + } 1.933 + 1.934 + int length() const { 1.935 + return _length; 1.936 + } 1.937 + 1.938 + u2 start_pc(int idx) const { 1.939 + assert(idx < _length, "out of bounds"); 1.940 + return _table[idx].start_pc; 1.941 + } 1.942 + 1.943 + void set_start_pc(int idx, u2 value) { 1.944 + assert(idx < _length, "out of bounds"); 1.945 + _table[idx].start_pc = value; 1.946 + } 1.947 + 1.948 + u2 end_pc(int idx) const { 1.949 + assert(idx < _length, "out of bounds"); 1.950 + return _table[idx].end_pc; 1.951 + } 1.952 + 1.953 + void set_end_pc(int idx, u2 value) { 1.954 + assert(idx < _length, "out of bounds"); 1.955 + _table[idx].end_pc = value; 1.956 + } 1.957 + 1.958 + u2 handler_pc(int idx) const { 1.959 + assert(idx < _length, "out of bounds"); 1.960 + return _table[idx].handler_pc; 1.961 + } 1.962 + 1.963 + void set_handler_pc(int idx, u2 value) { 1.964 + assert(idx < _length, "out of bounds"); 1.965 + _table[idx].handler_pc = value; 1.966 + } 1.967 + 1.968 + u2 catch_type_index(int idx) const { 1.969 + assert(idx < _length, "out of bounds"); 1.970 + return _table[idx].catch_type_index; 1.971 + } 1.972 + 1.973 + void set_catch_type_index(int idx, u2 value) { 1.974 + assert(idx < _length, "out of bounds"); 1.975 + _table[idx].catch_type_index = value; 1.976 + } 1.977 +}; 1.978 + 1.979 +#endif // SHARE_VM_OOPS_METHODOOP_HPP