1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/methodHandles.hpp Wed Apr 08 10:56:49 2009 -0700 1.3 @@ -0,0 +1,435 @@ 1.4 +/* 1.5 + * Copyright 2008-2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +class MacroAssembler; 1.29 +class Label; 1.30 +class MethodHandleEntry; 1.31 + 1.32 +class MethodHandles: AllStatic { 1.33 + // JVM support for MethodHandle, MethodType, and related types 1.34 + // in java.dyn and java.dyn.hotspot. 1.35 + // See also javaClasses for layouts java_dyn_Method{Handle,Type,Type::Form}. 1.36 + public: 1.37 + enum EntryKind { 1.38 + _check_mtype, // how a caller calls a MH 1.39 + _wrong_method_type, // what happens when there is a type mismatch 1.40 + _invokestatic_mh, // how a MH emulates invokestatic 1.41 + _invokespecial_mh, // ditto for the other invokes... 1.42 + _invokevirtual_mh, 1.43 + _invokeinterface_mh, 1.44 + _bound_ref_mh, // reference argument is bound 1.45 + _bound_int_mh, // int argument is bound (via an Integer or Float) 1.46 + _bound_long_mh, // long argument is bound (via a Long or Double) 1.47 + _bound_ref_direct_mh, // same as above, with direct linkage to methodOop 1.48 + _bound_int_direct_mh, 1.49 + _bound_long_direct_mh, 1.50 + 1.51 + _adapter_mh_first, // adapter sequence goes here... 1.52 + _adapter_retype_only = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RETYPE_ONLY, 1.53 + _adapter_check_cast = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_CHECK_CAST, 1.54 + _adapter_prim_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_PRIM, 1.55 + _adapter_ref_to_prim = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_REF_TO_PRIM, 1.56 + _adapter_prim_to_ref = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_PRIM_TO_REF, 1.57 + _adapter_swap_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SWAP_ARGS, 1.58 + _adapter_rot_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_ROT_ARGS, 1.59 + _adapter_dup_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DUP_ARGS, 1.60 + _adapter_drop_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_DROP_ARGS, 1.61 + _adapter_collect_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_COLLECT_ARGS, 1.62 + _adapter_spread_args = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_SPREAD_ARGS, 1.63 + _adapter_flyby = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_FLYBY, 1.64 + _adapter_ricochet = _adapter_mh_first + sun_dyn_AdapterMethodHandle::OP_RICOCHET, 1.65 + _adapter_mh_last = _adapter_mh_first + sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT - 1, 1.66 + 1.67 + // Optimized adapter types 1.68 + 1.69 + // argument list reordering 1.70 + _adapter_opt_swap_1, 1.71 + _adapter_opt_swap_2, 1.72 + _adapter_opt_rot_1_up, 1.73 + _adapter_opt_rot_1_down, 1.74 + _adapter_opt_rot_2_up, 1.75 + _adapter_opt_rot_2_down, 1.76 + // primitive single to single: 1.77 + _adapter_opt_i2i, // i2c, i2z, i2b, i2s 1.78 + // primitive double to single: 1.79 + _adapter_opt_l2i, 1.80 + _adapter_opt_d2f, 1.81 + // primitive single to double: 1.82 + _adapter_opt_i2l, 1.83 + _adapter_opt_f2d, 1.84 + // conversion between floating point and integer type is handled by Java 1.85 + 1.86 + // reference to primitive: 1.87 + _adapter_opt_unboxi, 1.88 + _adapter_opt_unboxl, 1.89 + 1.90 + // spreading (array length cases 0, 1, >=2) 1.91 + _adapter_opt_spread_0, 1.92 + _adapter_opt_spread_1, 1.93 + _adapter_opt_spread_more, 1.94 + 1.95 + _EK_LIMIT, 1.96 + _EK_FIRST = 0 1.97 + }; 1.98 + 1.99 + public: 1.100 + static bool enabled() { return _enabled; } 1.101 + static void set_enabled(bool z); 1.102 + 1.103 + private: 1.104 + enum { // import sun_dyn_AdapterMethodHandle::CONV_OP_* 1.105 + CONV_OP_LIMIT = sun_dyn_AdapterMethodHandle::CONV_OP_LIMIT, 1.106 + CONV_OP_MASK = sun_dyn_AdapterMethodHandle::CONV_OP_MASK, 1.107 + CONV_VMINFO_MASK = sun_dyn_AdapterMethodHandle::CONV_VMINFO_MASK, 1.108 + CONV_VMINFO_SHIFT = sun_dyn_AdapterMethodHandle::CONV_VMINFO_SHIFT, 1.109 + CONV_OP_SHIFT = sun_dyn_AdapterMethodHandle::CONV_OP_SHIFT, 1.110 + CONV_DEST_TYPE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT, 1.111 + CONV_SRC_TYPE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT, 1.112 + CONV_STACK_MOVE_SHIFT = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT, 1.113 + CONV_STACK_MOVE_MASK = sun_dyn_AdapterMethodHandle::CONV_STACK_MOVE_MASK 1.114 + }; 1.115 + 1.116 + static bool _enabled; 1.117 + static MethodHandleEntry* _entries[_EK_LIMIT]; 1.118 + static const char* _entry_names[_EK_LIMIT+1]; 1.119 + static bool ek_valid(EntryKind ek) { return (uint)ek < (uint)_EK_LIMIT; } 1.120 + static bool conv_op_valid(int op) { return (uint)op < (uint)CONV_OP_LIMIT; } 1.121 + 1.122 + public: 1.123 + static bool have_entry(EntryKind ek) { return ek_valid(ek) && _entries[ek] != NULL; } 1.124 + static MethodHandleEntry* entry(EntryKind ek) { assert(ek_valid(ek), "initialized"); 1.125 + return _entries[ek]; } 1.126 + static const char* entry_name(EntryKind ek) { assert(ek_valid(ek), "oob"); 1.127 + return _entry_names[ek]; } 1.128 + static EntryKind adapter_entry_kind(int op) { assert(conv_op_valid(op), "oob"); 1.129 + return EntryKind(_adapter_mh_first + op); } 1.130 + 1.131 + static void init_entry(EntryKind ek, MethodHandleEntry* me) { 1.132 + assert(ek_valid(ek), "oob"); 1.133 + assert(_entries[ek] == NULL, "no double initialization"); 1.134 + _entries[ek] = me; 1.135 + } 1.136 + 1.137 + static jint adapter_conversion(int conv_op, BasicType src, BasicType dest, 1.138 + int stack_move = 0, int vminfo = 0) { 1.139 + assert(conv_op_valid(conv_op), "oob"); 1.140 + jint conv = ((conv_op << CONV_OP_SHIFT) 1.141 + | (src << CONV_SRC_TYPE_SHIFT) 1.142 + | (dest << CONV_DEST_TYPE_SHIFT) 1.143 + | (stack_move << CONV_STACK_MOVE_SHIFT) 1.144 + | (vminfo << CONV_VMINFO_SHIFT) 1.145 + ); 1.146 + assert(adapter_conversion_op(conv) == conv_op, "decode conv_op"); 1.147 + assert(adapter_conversion_src_type(conv) == src, "decode src"); 1.148 + assert(adapter_conversion_dest_type(conv) == dest, "decode dest"); 1.149 + assert(adapter_conversion_stack_move(conv) == stack_move, "decode stack_move"); 1.150 + assert(adapter_conversion_vminfo(conv) == vminfo, "decode vminfo"); 1.151 + return conv; 1.152 + } 1.153 + static int adapter_conversion_op(jint conv) { 1.154 + return ((conv >> CONV_OP_SHIFT) & 0xF); 1.155 + } 1.156 + static BasicType adapter_conversion_src_type(jint conv) { 1.157 + return (BasicType)((conv >> CONV_SRC_TYPE_SHIFT) & 0xF); 1.158 + } 1.159 + static BasicType adapter_conversion_dest_type(jint conv) { 1.160 + return (BasicType)((conv >> CONV_DEST_TYPE_SHIFT) & 0xF); 1.161 + } 1.162 + static int adapter_conversion_stack_move(jint conv) { 1.163 + return (conv >> CONV_STACK_MOVE_SHIFT); 1.164 + } 1.165 + static int adapter_conversion_vminfo(jint conv) { 1.166 + return (conv >> CONV_VMINFO_SHIFT) & CONV_VMINFO_MASK; 1.167 + } 1.168 + 1.169 + // Offset in words that the interpreter stack pointer moves when an argument is pushed. 1.170 + // The stack_move value must always be a multiple of this. 1.171 + static int stack_move_unit() { 1.172 + return frame::interpreter_frame_expression_stack_direction() * Interpreter::stackElementWords(); 1.173 + } 1.174 + 1.175 + enum { CONV_VMINFO_SIGN_FLAG = 0x80 }; 1.176 + static int adapter_subword_vminfo(BasicType dest) { 1.177 + if (dest == T_BOOLEAN) return (BitsPerInt - 1); 1.178 + if (dest == T_CHAR) return (BitsPerInt - 16); 1.179 + if (dest == T_BYTE) return (BitsPerInt - 8) | CONV_VMINFO_SIGN_FLAG; 1.180 + if (dest == T_SHORT) return (BitsPerInt - 16) | CONV_VMINFO_SIGN_FLAG; 1.181 + return 0; // case T_INT 1.182 + } 1.183 + // Here is the transformation the i2i adapter must perform: 1.184 + static int truncate_subword_from_vminfo(jint value, int vminfo) { 1.185 + jint tem = value << vminfo; 1.186 + if ((vminfo & CONV_VMINFO_SIGN_FLAG) != 0) { 1.187 + return (jint)tem >> vminfo; 1.188 + } else { 1.189 + return (juint)tem >> vminfo; 1.190 + } 1.191 + } 1.192 + 1.193 + static inline address from_compiled_entry(EntryKind ek); 1.194 + static inline address from_interpreted_entry(EntryKind ek); 1.195 + 1.196 + // helpers for decode_method. 1.197 + static methodOop decode_methodOop(methodOop m, int& decode_flags_result); 1.198 + static methodOop decode_vmtarget(oop vmtarget, int vmindex, oop mtype, klassOop& receiver_limit_result, int& decode_flags_result); 1.199 + static methodOop decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result); 1.200 + static methodOop decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); 1.201 + static methodOop decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); 1.202 + static methodOop decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); 1.203 + static methodOop decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); 1.204 + 1.205 + // Find out how many stack slots an mh pushes or pops. 1.206 + // The result is *not* reported as a multiple of stack_move_unit(); 1.207 + // It is a signed net number of pushes (a difference in vmslots). 1.208 + // To compare with a stack_move value, first multiply by stack_move_unit(). 1.209 + static int decode_MethodHandle_stack_pushes(oop mh); 1.210 + 1.211 + public: 1.212 + // working with member names 1.213 + static void resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type 1.214 + static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing 1.215 + static void init_MemberName(oop mname_oop, oop target); // compute vmtarget/vmindex from target 1.216 + static void init_MemberName(oop mname_oop, methodOop m, bool do_dispatch); 1.217 + static void init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset); 1.218 + static int find_MemberNames(klassOop k, symbolOop name, symbolOop sig, 1.219 + int mflags, klassOop caller, 1.220 + int skip, objArrayOop results); 1.221 + // bit values for suppress argument to expand_MemberName: 1.222 + enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 }; 1.223 + 1.224 + // called from InterpreterGenerator and StubGenerator 1.225 + static address generate_method_handle_interpreter_entry(MacroAssembler* _masm); 1.226 + static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek); 1.227 + 1.228 + // argument list parsing 1.229 + static int argument_slot(oop method_type, int arg); 1.230 + static int argument_slot_count(oop method_type) { return argument_slot(method_type, -1); } 1.231 + static int argument_slot_to_argnum(oop method_type, int argslot); 1.232 + 1.233 + // Runtime support 1.234 + enum { // bit-encoded flags from decode_method or decode_vmref 1.235 + _dmf_has_receiver = 0x01, // target method has leading reference argument 1.236 + _dmf_does_dispatch = 0x02, // method handle performs virtual or interface dispatch 1.237 + _dmf_from_interface = 0x04, // peforms interface dispatch 1.238 + _DMF_DIRECT_MASK = (_dmf_from_interface*2 - _dmf_has_receiver), 1.239 + _dmf_binds_method = 0x08, 1.240 + _dmf_binds_argument = 0x10, 1.241 + _DMF_BOUND_MASK = (_dmf_binds_argument*2 - _dmf_binds_method), 1.242 + _dmf_adapter_lsb = 0x20, 1.243 + _DMF_ADAPTER_MASK = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb 1.244 + }; 1.245 + static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result); 1.246 + enum { 1.247 + // format of query to getConstant: 1.248 + GC_JVM_PUSH_LIMIT = 0, 1.249 + GC_JVM_STACK_MOVE_LIMIT = 1, 1.250 + 1.251 + // format of result from getTarget / encode_target: 1.252 + ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method) 1.253 + ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self) 1.254 + ETF_METHOD_NAME = 2, // ultimate method as MemberName 1.255 + ETF_REFLECT_METHOD = 3 // ultimate method as java.lang.reflect object (sans refClass) 1.256 + }; 1.257 + static int get_named_constant(int which, Handle name_box, TRAPS); 1.258 + static oop encode_target(Handle mh, int format, TRAPS); // report vmtarget (to Java code) 1.259 + static bool class_cast_needed(klassOop src, klassOop dst); 1.260 + 1.261 + private: 1.262 + // These checkers operate on a pair of whole MethodTypes: 1.263 + static const char* check_method_type_change(oop src_mtype, int src_beg, int src_end, 1.264 + int insert_argnum, oop insert_type, 1.265 + int change_argnum, oop change_type, 1.266 + int delete_argnum, 1.267 + oop dst_mtype, int dst_beg, int dst_end); 1.268 + static const char* check_method_type_insertion(oop src_mtype, 1.269 + int insert_argnum, oop insert_type, 1.270 + oop dst_mtype) { 1.271 + oop no_ref = NULL; 1.272 + return check_method_type_change(src_mtype, 0, -1, 1.273 + insert_argnum, insert_type, 1.274 + -1, no_ref, -1, dst_mtype, 0, -1); 1.275 + } 1.276 + static const char* check_method_type_conversion(oop src_mtype, 1.277 + int change_argnum, oop change_type, 1.278 + oop dst_mtype) { 1.279 + oop no_ref = NULL; 1.280 + return check_method_type_change(src_mtype, 0, -1, -1, no_ref, 1.281 + change_argnum, change_type, 1.282 + -1, dst_mtype, 0, -1); 1.283 + } 1.284 + static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype) { 1.285 + oop no_ref = NULL; 1.286 + return check_method_type_change(src_mtype, 0, -1, 1.287 + -1, no_ref, -1, no_ref, -1, 1.288 + dst_mtype, 0, -1); 1.289 + } 1.290 + 1.291 + // These checkers operate on pairs of argument or return types: 1.292 + static const char* check_argument_type_change(BasicType src_type, klassOop src_klass, 1.293 + BasicType dst_type, klassOop dst_klass, 1.294 + int argnum); 1.295 + 1.296 + static const char* check_argument_type_change(oop src_type, oop dst_type, 1.297 + int argnum) { 1.298 + klassOop src_klass = NULL, dst_klass = NULL; 1.299 + BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass); 1.300 + BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass); 1.301 + return check_argument_type_change(src_bt, src_klass, 1.302 + dst_bt, dst_klass, argnum); 1.303 + } 1.304 + 1.305 + static const char* check_return_type_change(oop src_type, oop dst_type) { 1.306 + return check_argument_type_change(src_type, dst_type, -1); 1.307 + } 1.308 + 1.309 + static const char* check_return_type_change(BasicType src_type, klassOop src_klass, 1.310 + BasicType dst_type, klassOop dst_klass) { 1.311 + return check_argument_type_change(src_type, src_klass, dst_type, dst_klass, -1); 1.312 + } 1.313 + 1.314 + static const char* check_method_receiver(methodOop m, klassOop passed_recv_type); 1.315 + 1.316 + // These verifiers can block, and will throw an error if the checking fails: 1.317 + static void verify_vmslots(Handle mh, TRAPS); 1.318 + static void verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS); 1.319 + 1.320 + static void verify_method_type(methodHandle m, Handle mtype, 1.321 + bool has_bound_oop, 1.322 + KlassHandle bound_oop_type, 1.323 + TRAPS); 1.324 + 1.325 + static void verify_method_signature(methodHandle m, Handle mtype, 1.326 + int first_ptype_pos, 1.327 + KlassHandle insert_ptype, TRAPS); 1.328 + 1.329 + static void verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS); 1.330 + static void verify_BoundMethodHandle(Handle mh, Handle target, int argnum, 1.331 + bool direct_to_method, TRAPS); 1.332 + static void verify_BoundMethodHandle_with_receiver(Handle mh, methodHandle m, TRAPS); 1.333 + static void verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS); 1.334 + 1.335 + public: 1.336 + 1.337 + // Fill in the fields of a DirectMethodHandle mh. (MH.type must be pre-filled.) 1.338 + static void init_DirectMethodHandle(Handle mh, methodHandle method, bool do_dispatch, TRAPS); 1.339 + 1.340 + // Fill in the fields of a BoundMethodHandle mh. (MH.type, BMH.argument must be pre-filled.) 1.341 + static void init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS); 1.342 + static void init_BoundMethodHandle_with_receiver(Handle mh, 1.343 + methodHandle original_m, 1.344 + KlassHandle receiver_limit, 1.345 + int decode_flags, 1.346 + TRAPS); 1.347 + 1.348 + // Fill in the fields of an AdapterMethodHandle mh. (MH.type must be pre-filled.) 1.349 + static void init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS); 1.350 + 1.351 +#ifdef ASSERT 1.352 + static bool spot_check_entry_names(); 1.353 +#endif 1.354 + 1.355 + private: 1.356 + static methodHandle dispatch_decoded_method(methodHandle m, 1.357 + KlassHandle receiver_limit, 1.358 + int decode_flags, 1.359 + KlassHandle receiver_klass, 1.360 + TRAPS); 1.361 + 1.362 + static bool same_basic_type_for_arguments(BasicType src, BasicType dst, 1.363 + bool for_return = false); 1.364 + static bool same_basic_type_for_returns(BasicType src, BasicType dst) { 1.365 + return same_basic_type_for_arguments(src, dst, true); 1.366 + } 1.367 + 1.368 + enum { // arg_mask values 1.369 + _INSERT_NO_MASK = -1, 1.370 + _INSERT_REF_MASK = 0, 1.371 + _INSERT_INT_MASK = 1, 1.372 + _INSERT_LONG_MASK = 3 1.373 + }; 1.374 + static void insert_arg_slots(MacroAssembler* _masm, 1.375 + RegisterOrConstant arg_slots, 1.376 + int arg_mask, 1.377 + Register rax_argslot, 1.378 + Register rbx_temp, Register rdx_temp); 1.379 + 1.380 + static void remove_arg_slots(MacroAssembler* _masm, 1.381 + RegisterOrConstant arg_slots, 1.382 + Register rax_argslot, 1.383 + Register rbx_temp, Register rdx_temp); 1.384 +}; 1.385 + 1.386 + 1.387 +// Access methods for the "entry" field of a java.dyn.MethodHandle. 1.388 +// The field is primarily a jump target for compiled calls. 1.389 +// However, we squirrel away some nice pointers for other uses, 1.390 +// just before the jump target. 1.391 +// Aspects of a method handle entry: 1.392 +// - from_compiled_entry - stub used when compiled code calls the MH 1.393 +// - from_interpreted_entry - stub used when the interpreter calls the MH 1.394 +// - type_checking_entry - stub for runtime casting between MHForm siblings (NYI) 1.395 +class MethodHandleEntry { 1.396 + public: 1.397 + class Data { 1.398 + friend class MethodHandleEntry; 1.399 + size_t _total_size; // size including Data and code stub 1.400 + MethodHandleEntry* _type_checking_entry; 1.401 + address _from_interpreted_entry; 1.402 + MethodHandleEntry* method_entry() { return (MethodHandleEntry*)(this + 1); } 1.403 + }; 1.404 + 1.405 + Data* data() { return (Data*)this - 1; } 1.406 + 1.407 + address start_address() { return (address) data(); } 1.408 + address end_address() { return start_address() + data()->_total_size; } 1.409 + 1.410 + address from_compiled_entry() { return (address) this; } 1.411 + 1.412 + address from_interpreted_entry() { return data()->_from_interpreted_entry; } 1.413 + void set_from_interpreted_entry(address e) { data()->_from_interpreted_entry = e; } 1.414 + 1.415 + MethodHandleEntry* type_checking_entry() { return data()->_type_checking_entry; } 1.416 + void set_type_checking_entry(MethodHandleEntry* e) { data()->_type_checking_entry = e; } 1.417 + 1.418 + void set_end_address(address end_addr) { 1.419 + size_t total_size = end_addr - start_address(); 1.420 + assert(total_size > 0 && total_size < 0x1000, "reasonable end address"); 1.421 + data()->_total_size = total_size; 1.422 + } 1.423 + 1.424 + // Compiler support: 1.425 + static int from_interpreted_entry_offset_in_bytes() { 1.426 + return (int)( offset_of(Data, _from_interpreted_entry) - sizeof(Data) ); 1.427 + } 1.428 + static int type_checking_entry_offset_in_bytes() { 1.429 + return (int)( offset_of(Data, _from_interpreted_entry) - sizeof(Data) ); 1.430 + } 1.431 + 1.432 + static address start_compiled_entry(MacroAssembler* _masm, 1.433 + address interpreted_entry = NULL); 1.434 + static MethodHandleEntry* finish_compiled_entry(MacroAssembler* masm, address start_addr); 1.435 +}; 1.436 + 1.437 +address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); } 1.438 +address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }