1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/methodHandles.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,254 @@ 1.4 +/* 1.5 + * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_PRIMS_METHODHANDLES_HPP 1.29 +#define SHARE_VM_PRIMS_METHODHANDLES_HPP 1.30 + 1.31 +#include "classfile/javaClasses.hpp" 1.32 +#include "classfile/vmSymbols.hpp" 1.33 +#include "runtime/frame.inline.hpp" 1.34 +#include "runtime/globals.hpp" 1.35 +#include "runtime/interfaceSupport.hpp" 1.36 + 1.37 +class MacroAssembler; 1.38 +class Label; 1.39 + 1.40 +class MethodHandles: AllStatic { 1.41 + // JVM support for MethodHandle, MethodType, and related types 1.42 + // in java.lang.invoke and sun.invoke. 1.43 + // See also javaClasses for layouts java_lang_invoke_Method{Handle,Type,Type::Form}. 1.44 + public: 1.45 + public: 1.46 + static bool enabled() { return _enabled; } 1.47 + static void set_enabled(bool z); 1.48 + 1.49 + private: 1.50 + static bool _enabled; 1.51 + 1.52 + // Adapters. 1.53 + static MethodHandlesAdapterBlob* _adapter_code; 1.54 + 1.55 + // utility functions for reifying names and types 1.56 + static oop field_name_or_null(Symbol* s); 1.57 + static oop field_signature_type_or_null(Symbol* s); 1.58 + 1.59 + public: 1.60 + // working with member names 1.61 + static Handle resolve_MemberName(Handle mname, KlassHandle caller, TRAPS); // compute vmtarget/vmindex from name/type 1.62 + static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing 1.63 + static Handle new_MemberName(TRAPS); // must be followed by init_MemberName 1.64 + static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target 1.65 + static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false); 1.66 + static oop init_method_MemberName(Handle mname_h, CallInfo& info); 1.67 + static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true); 1.68 + static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig, 1.69 + int mflags, KlassHandle caller, 1.70 + int skip, objArrayHandle results); 1.71 + // bit values for suppress argument to expand_MemberName: 1.72 + enum { _suppress_defc = 1, _suppress_name = 2, _suppress_type = 4 }; 1.73 + 1.74 + // Generate MethodHandles adapters. 1.75 + static void generate_adapters(); 1.76 + 1.77 + // Called from MethodHandlesAdapterGenerator. 1.78 + static address generate_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid); 1.79 + static void generate_method_handle_dispatch(MacroAssembler* _masm, 1.80 + vmIntrinsics::ID iid, 1.81 + Register receiver_reg, 1.82 + Register member_reg, 1.83 + bool for_compiler_entry); 1.84 + 1.85 + // Queries 1.86 + static bool is_signature_polymorphic(vmIntrinsics::ID iid) { 1.87 + return (iid >= vmIntrinsics::FIRST_MH_SIG_POLY && 1.88 + iid <= vmIntrinsics::LAST_MH_SIG_POLY); 1.89 + } 1.90 + 1.91 + static bool is_signature_polymorphic_intrinsic(vmIntrinsics::ID iid) { 1.92 + assert(is_signature_polymorphic(iid), ""); 1.93 + // Most sig-poly methods are intrinsics which do not require an 1.94 + // appeal to Java for adapter code. 1.95 + return (iid != vmIntrinsics::_invokeGeneric); 1.96 + } 1.97 + 1.98 + static bool is_signature_polymorphic_static(vmIntrinsics::ID iid) { 1.99 + assert(is_signature_polymorphic(iid), ""); 1.100 + return (iid >= vmIntrinsics::FIRST_MH_STATIC && 1.101 + iid <= vmIntrinsics::LAST_MH_SIG_POLY); 1.102 + } 1.103 + 1.104 + static bool has_member_arg(vmIntrinsics::ID iid) { 1.105 + assert(is_signature_polymorphic(iid), ""); 1.106 + return (iid >= vmIntrinsics::_linkToVirtual && 1.107 + iid <= vmIntrinsics::_linkToInterface); 1.108 + } 1.109 + static bool has_member_arg(Symbol* klass, Symbol* name) { 1.110 + if ((klass == vmSymbols::java_lang_invoke_MethodHandle()) && 1.111 + is_signature_polymorphic_name(name)) { 1.112 + vmIntrinsics::ID iid = signature_polymorphic_name_id(name); 1.113 + return has_member_arg(iid); 1.114 + } 1.115 + return false; 1.116 + } 1.117 + 1.118 + static Symbol* signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid); 1.119 + static int signature_polymorphic_intrinsic_ref_kind(vmIntrinsics::ID iid); 1.120 + 1.121 + static vmIntrinsics::ID signature_polymorphic_name_id(Klass* klass, Symbol* name); 1.122 + static vmIntrinsics::ID signature_polymorphic_name_id(Symbol* name); 1.123 + static bool is_signature_polymorphic_name(Symbol* name) { 1.124 + return signature_polymorphic_name_id(name) != vmIntrinsics::_none; 1.125 + } 1.126 + static bool is_method_handle_invoke_name(Klass* klass, Symbol* name); 1.127 + static bool is_signature_polymorphic_name(Klass* klass, Symbol* name) { 1.128 + return signature_polymorphic_name_id(klass, name) != vmIntrinsics::_none; 1.129 + } 1.130 + 1.131 + enum { 1.132 + // format of query to getConstant: 1.133 + GC_COUNT_GWT = 4, 1.134 + GC_LAMBDA_SUPPORT = 5 1.135 + }; 1.136 + static int get_named_constant(int which, Handle name_box, TRAPS); 1.137 + 1.138 +public: 1.139 + static Symbol* lookup_signature(oop type_str, bool polymorphic, TRAPS); // use TempNewSymbol 1.140 + static Symbol* lookup_basic_type_signature(Symbol* sig, bool keep_last_arg, TRAPS); // use TempNewSymbol 1.141 + static Symbol* lookup_basic_type_signature(Symbol* sig, TRAPS) { 1.142 + return lookup_basic_type_signature(sig, false, THREAD); 1.143 + } 1.144 + static bool is_basic_type_signature(Symbol* sig); 1.145 + 1.146 + static Symbol* lookup_method_type(Symbol* msig, Handle mtype, TRAPS); 1.147 + 1.148 + static void print_as_method_type_on(outputStream* st, Symbol* sig) { 1.149 + print_as_basic_type_signature_on(st, sig, true, true); 1.150 + } 1.151 + static void print_as_basic_type_signature_on(outputStream* st, Symbol* sig, bool keep_arrays = false, bool keep_basic_names = false); 1.152 + 1.153 + // decoding CONSTANT_MethodHandle constants 1.154 + enum { JVM_REF_MIN = JVM_REF_getField, JVM_REF_MAX = JVM_REF_invokeInterface }; 1.155 + static bool ref_kind_is_valid(int ref_kind) { 1.156 + return (ref_kind >= JVM_REF_MIN && ref_kind <= JVM_REF_MAX); 1.157 + } 1.158 + static bool ref_kind_is_field(int ref_kind) { 1.159 + assert(ref_kind_is_valid(ref_kind), ""); 1.160 + return (ref_kind <= JVM_REF_putStatic); 1.161 + } 1.162 + static bool ref_kind_is_getter(int ref_kind) { 1.163 + assert(ref_kind_is_valid(ref_kind), ""); 1.164 + return (ref_kind <= JVM_REF_getStatic); 1.165 + } 1.166 + static bool ref_kind_is_setter(int ref_kind) { 1.167 + return ref_kind_is_field(ref_kind) && !ref_kind_is_getter(ref_kind); 1.168 + } 1.169 + static bool ref_kind_is_method(int ref_kind) { 1.170 + return !ref_kind_is_field(ref_kind) && (ref_kind != JVM_REF_newInvokeSpecial); 1.171 + } 1.172 + static bool ref_kind_has_receiver(int ref_kind) { 1.173 + assert(ref_kind_is_valid(ref_kind), ""); 1.174 + return (ref_kind & 1) != 0; 1.175 + } 1.176 + static bool ref_kind_is_static(int ref_kind) { 1.177 + return !ref_kind_has_receiver(ref_kind) && (ref_kind != JVM_REF_newInvokeSpecial); 1.178 + } 1.179 + static bool ref_kind_does_dispatch(int ref_kind) { 1.180 + return (ref_kind == JVM_REF_invokeVirtual || 1.181 + ref_kind == JVM_REF_invokeInterface); 1.182 + } 1.183 + 1.184 + 1.185 +#ifdef TARGET_ARCH_x86 1.186 +# include "methodHandles_x86.hpp" 1.187 +#endif 1.188 +#ifdef TARGET_ARCH_sparc 1.189 +# include "methodHandles_sparc.hpp" 1.190 +#endif 1.191 +#ifdef TARGET_ARCH_zero 1.192 +# include "methodHandles_zero.hpp" 1.193 +#endif 1.194 +#ifdef TARGET_ARCH_arm 1.195 +# include "methodHandles_arm.hpp" 1.196 +#endif 1.197 +#ifdef TARGET_ARCH_ppc 1.198 +# include "methodHandles_ppc.hpp" 1.199 +#endif 1.200 + 1.201 + // Tracing 1.202 + static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN; 1.203 + static void trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) { 1.204 + if (TraceMethodHandles) { 1.205 + const char* name = vmIntrinsics::name_at(iid); 1.206 + if (*name == '_') name += 1; 1.207 + const size_t len = strlen(name) + 50; 1.208 + char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal); 1.209 + const char* suffix = ""; 1.210 + if (is_signature_polymorphic(iid)) { 1.211 + if (is_signature_polymorphic_static(iid)) 1.212 + suffix = "/static"; 1.213 + else 1.214 + suffix = "/private"; 1.215 + } 1.216 + jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix); 1.217 + trace_method_handle(_masm, qname); 1.218 + // Note: Don't free the allocated char array because it's used 1.219 + // during runtime. 1.220 + } 1.221 + } 1.222 +}; 1.223 + 1.224 +//------------------------------------------------------------------------------ 1.225 +// MethodHandlesAdapterGenerator 1.226 +// 1.227 +class MethodHandlesAdapterGenerator : public StubCodeGenerator { 1.228 +public: 1.229 + MethodHandlesAdapterGenerator(CodeBuffer* code) : StubCodeGenerator(code, PrintMethodHandleStubs) {} 1.230 + 1.231 + void generate(); 1.232 +}; 1.233 + 1.234 +//------------------------------------------------------------------------------ 1.235 +// MemberNameTable 1.236 +// 1.237 + 1.238 +class MemberNameTable : public GrowableArray<jweak> { 1.239 + public: 1.240 + MemberNameTable(int methods_cnt); 1.241 + ~MemberNameTable(); 1.242 + void add_member_name(int index, jweak mem_name_ref); 1.243 + oop get_member_name(int index); 1.244 + 1.245 +#if INCLUDE_JVMTI 1.246 + public: 1.247 + // RedefineClasses() API support: 1.248 + // If a MemberName refers to old_method then update it 1.249 + // to refer to new_method. 1.250 + void adjust_method_entries(Method** old_methods, Method** new_methods, 1.251 + int methods_length, bool *trace_name_printed); 1.252 + private: 1.253 + oop find_member_name_by_method(Method* old_method); 1.254 +#endif // INCLUDE_JVMTI 1.255 +}; 1.256 + 1.257 +#endif // SHARE_VM_PRIMS_METHODHANDLES_HPP