1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/methodHandles.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,1413 @@ 1.4 +/* 1.5 + * Copyright (c) 2008, 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 "classfile/symbolTable.hpp" 1.30 +#include "compiler/compileBroker.hpp" 1.31 +#include "interpreter/interpreter.hpp" 1.32 +#include "interpreter/oopMapCache.hpp" 1.33 +#include "memory/allocation.inline.hpp" 1.34 +#include "memory/oopFactory.hpp" 1.35 +#include "prims/jvmtiRedefineClassesTrace.hpp" 1.36 +#include "prims/methodHandles.hpp" 1.37 +#include "runtime/compilationPolicy.hpp" 1.38 +#include "runtime/javaCalls.hpp" 1.39 +#include "runtime/reflection.hpp" 1.40 +#include "runtime/signature.hpp" 1.41 +#include "runtime/stubRoutines.hpp" 1.42 + 1.43 + 1.44 +/* 1.45 + * JSR 292 reference implementation: method handles 1.46 + * The JDK 7 reference implementation represented method handle 1.47 + * combinations as chains. Each link in the chain had a "vmentry" 1.48 + * field which pointed at a bit of assembly code which performed 1.49 + * one transformation before dispatching to the next link in the chain. 1.50 + * 1.51 + * The current reference implementation pushes almost all code generation 1.52 + * responsibility to (trusted) Java code. A method handle contains a 1.53 + * pointer to its "LambdaForm", which embodies all details of the method 1.54 + * handle's behavior. The LambdaForm is a normal Java object, managed 1.55 + * by a runtime coded in Java. 1.56 + */ 1.57 + 1.58 +bool MethodHandles::_enabled = false; // set true after successful native linkage 1.59 +MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL; 1.60 + 1.61 +//------------------------------------------------------------------------------ 1.62 +// MethodHandles::generate_adapters 1.63 +// 1.64 +void MethodHandles::generate_adapters() { 1.65 + if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL) return; 1.66 + 1.67 + assert(_adapter_code == NULL, "generate only once"); 1.68 + 1.69 + ResourceMark rm; 1.70 + TraceTime timer("MethodHandles adapters generation", TraceStartupTime); 1.71 + _adapter_code = MethodHandlesAdapterBlob::create(adapter_code_size); 1.72 + if (_adapter_code == NULL) 1.73 + vm_exit_out_of_memory(adapter_code_size, OOM_MALLOC_ERROR, 1.74 + "CodeCache: no room for MethodHandles adapters"); 1.75 + { 1.76 + CodeBuffer code(_adapter_code); 1.77 + MethodHandlesAdapterGenerator g(&code); 1.78 + g.generate(); 1.79 + code.log_section_sizes("MethodHandlesAdapterBlob"); 1.80 + } 1.81 +} 1.82 + 1.83 +//------------------------------------------------------------------------------ 1.84 +// MethodHandlesAdapterGenerator::generate 1.85 +// 1.86 +void MethodHandlesAdapterGenerator::generate() { 1.87 + // Generate generic method handle adapters. 1.88 + // Generate interpreter entries 1.89 + for (Interpreter::MethodKind mk = Interpreter::method_handle_invoke_FIRST; 1.90 + mk <= Interpreter::method_handle_invoke_LAST; 1.91 + mk = Interpreter::MethodKind(1 + (int)mk)) { 1.92 + vmIntrinsics::ID iid = Interpreter::method_handle_intrinsic(mk); 1.93 + StubCodeMark mark(this, "MethodHandle::interpreter_entry", vmIntrinsics::name_at(iid)); 1.94 + address entry = MethodHandles::generate_method_handle_interpreter_entry(_masm, iid); 1.95 + if (entry != NULL) { 1.96 + Interpreter::set_entry_for_kind(mk, entry); 1.97 + } 1.98 + // If the entry is not set, it will throw AbstractMethodError. 1.99 + } 1.100 +} 1.101 + 1.102 +void MethodHandles::set_enabled(bool z) { 1.103 + if (_enabled != z) { 1.104 + guarantee(z && EnableInvokeDynamic, "can only enable once, and only if -XX:+EnableInvokeDynamic"); 1.105 + _enabled = z; 1.106 + } 1.107 +} 1.108 + 1.109 +// MemberName support 1.110 + 1.111 +// import java_lang_invoke_MemberName.* 1.112 +enum { 1.113 + IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD, 1.114 + IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR, 1.115 + IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD, 1.116 + IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE, 1.117 + CALLER_SENSITIVE = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE, 1.118 + REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT, 1.119 + REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK, 1.120 + SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES, 1.121 + SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES, 1.122 + ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE 1.123 +}; 1.124 + 1.125 +Handle MethodHandles::new_MemberName(TRAPS) { 1.126 + Handle empty; 1.127 + instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); 1.128 + if (!k->is_initialized()) k->initialize(CHECK_(empty)); 1.129 + return Handle(THREAD, k->allocate_instance(THREAD)); 1.130 +} 1.131 + 1.132 +oop MethodHandles::init_MemberName(Handle mname, Handle target) { 1.133 + // This method is used from java.lang.invoke.MemberName constructors. 1.134 + // It fills in the new MemberName from a java.lang.reflect.Member. 1.135 + Thread* thread = Thread::current(); 1.136 + oop target_oop = target(); 1.137 + Klass* target_klass = target_oop->klass(); 1.138 + if (target_klass == SystemDictionary::reflect_Field_klass()) { 1.139 + oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() 1.140 + int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() 1.141 + KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.142 + if (!k.is_null() && k->oop_is_instance()) { 1.143 + fieldDescriptor fd(InstanceKlass::cast(k()), slot); 1.144 + oop mname2 = init_field_MemberName(mname, fd); 1.145 + if (mname2 != NULL) { 1.146 + // Since we have the reified name and type handy, add them to the result. 1.147 + if (java_lang_invoke_MemberName::name(mname2) == NULL) 1.148 + java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); 1.149 + if (java_lang_invoke_MemberName::type(mname2) == NULL) 1.150 + java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop)); 1.151 + } 1.152 + return mname2; 1.153 + } 1.154 + } else if (target_klass == SystemDictionary::reflect_Method_klass()) { 1.155 + oop clazz = java_lang_reflect_Method::clazz(target_oop); 1.156 + int slot = java_lang_reflect_Method::slot(target_oop); 1.157 + KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.158 + if (!k.is_null() && k->oop_is_instance()) { 1.159 + Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); 1.160 + if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) 1.161 + return NULL; // do not resolve unless there is a concrete signature 1.162 + CallInfo info(m, k()); 1.163 + return init_method_MemberName(mname, info); 1.164 + } 1.165 + } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { 1.166 + oop clazz = java_lang_reflect_Constructor::clazz(target_oop); 1.167 + int slot = java_lang_reflect_Constructor::slot(target_oop); 1.168 + KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); 1.169 + if (!k.is_null() && k->oop_is_instance()) { 1.170 + Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); 1.171 + if (m == NULL) return NULL; 1.172 + CallInfo info(m, k()); 1.173 + return init_method_MemberName(mname, info); 1.174 + } 1.175 + } 1.176 + return NULL; 1.177 +} 1.178 + 1.179 +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { 1.180 + assert(info.resolved_appendix().is_null(), "only normal methods here"); 1.181 + methodHandle m = info.resolved_method(); 1.182 + KlassHandle m_klass = m->method_holder(); 1.183 + int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); 1.184 + int vmindex = Method::invalid_vtable_index; 1.185 + 1.186 + switch (info.call_kind()) { 1.187 + case CallInfo::itable_call: 1.188 + vmindex = info.itable_index(); 1.189 + // More importantly, the itable index only works with the method holder. 1.190 + assert(m_klass->verify_itable_index(vmindex), ""); 1.191 + flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); 1.192 + if (TraceInvokeDynamic) { 1.193 + ResourceMark rm; 1.194 + tty->print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:", 1.195 + Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()), 1.196 + vmindex); 1.197 + m->access_flags().print_on(tty); 1.198 + if (!m->is_abstract()) { 1.199 + tty->print("default"); 1.200 + } 1.201 + tty->cr(); 1.202 + } 1.203 + break; 1.204 + 1.205 + case CallInfo::vtable_call: 1.206 + vmindex = info.vtable_index(); 1.207 + flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); 1.208 + assert(info.resolved_klass()->is_subtype_of(m_klass()), "virtual call must be type-safe"); 1.209 + if (m_klass->is_interface()) { 1.210 + // This is a vtable call to an interface method (abstract "miranda method" or default method). 1.211 + // The vtable index is meaningless without a class (not interface) receiver type, so get one. 1.212 + // (LinkResolver should help us figure this out.) 1.213 + KlassHandle m_klass_non_interface = info.resolved_klass(); 1.214 + if (m_klass_non_interface->is_interface()) { 1.215 + m_klass_non_interface = SystemDictionary::Object_klass(); 1.216 +#ifdef ASSERT 1.217 + { ResourceMark rm; 1.218 + Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex); 1.219 + assert(m->name() == m2->name() && m->signature() == m2->signature(), 1.220 + err_msg("at %d, %s != %s", vmindex, 1.221 + m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string())); 1.222 + } 1.223 +#endif //ASSERT 1.224 + } 1.225 + if (!m->is_public()) { 1.226 + assert(m->is_public(), "virtual call must be to public interface method"); 1.227 + return NULL; // elicit an error later in product build 1.228 + } 1.229 + assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface()), "virtual call must be type-safe"); 1.230 + m_klass = m_klass_non_interface; 1.231 + } 1.232 + if (TraceInvokeDynamic) { 1.233 + ResourceMark rm; 1.234 + tty->print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:", 1.235 + Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()), 1.236 + m_klass->internal_name(), vmindex); 1.237 + m->access_flags().print_on(tty); 1.238 + if (m->is_default_method()) { 1.239 + tty->print("default"); 1.240 + } 1.241 + tty->cr(); 1.242 + } 1.243 + break; 1.244 + 1.245 + case CallInfo::direct_call: 1.246 + vmindex = Method::nonvirtual_vtable_index; 1.247 + if (m->is_static()) { 1.248 + flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); 1.249 + } else if (m->is_initializer()) { 1.250 + flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.251 + } else { 1.252 + flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 1.253 + } 1.254 + break; 1.255 + 1.256 + default: assert(false, "bad CallInfo"); return NULL; 1.257 + } 1.258 + 1.259 + // @CallerSensitive annotation detected 1.260 + if (m->caller_sensitive()) { 1.261 + flags |= CALLER_SENSITIVE; 1.262 + } 1.263 + 1.264 + oop mname_oop = mname(); 1.265 + java_lang_invoke_MemberName::set_flags( mname_oop, flags); 1.266 + java_lang_invoke_MemberName::set_vmtarget(mname_oop, m()); 1.267 + java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index 1.268 + java_lang_invoke_MemberName::set_clazz( mname_oop, m_klass->java_mirror()); 1.269 + // Note: name and type can be lazily computed by resolve_MemberName, 1.270 + // if Java code needs them as resolved String and MethodType objects. 1.271 + // The clazz must be eagerly stored, because it provides a GC 1.272 + // root to help keep alive the Method*. 1.273 + // If relevant, the vtable or itable value is stored as vmindex. 1.274 + // This is done eagerly, since it is readily available without 1.275 + // constructing any new objects. 1.276 + // TO DO: maybe intern mname_oop 1.277 + m->method_holder()->add_member_name(m->method_idnum(), mname); 1.278 + 1.279 + return mname(); 1.280 +} 1.281 + 1.282 +oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { 1.283 + int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); 1.284 + flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); 1.285 + if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); 1.286 + Metadata* vmtarget = fd.field_holder(); 1.287 + int vmindex = fd.offset(); // determines the field uniquely when combined with static bit 1.288 + oop mname_oop = mname(); 1.289 + java_lang_invoke_MemberName::set_flags(mname_oop, flags); 1.290 + java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); 1.291 + java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); 1.292 + java_lang_invoke_MemberName::set_clazz(mname_oop, fd.field_holder()->java_mirror()); 1.293 + oop type = field_signature_type_or_null(fd.signature()); 1.294 + oop name = field_name_or_null(fd.name()); 1.295 + if (name != NULL) 1.296 + java_lang_invoke_MemberName::set_name(mname_oop, name); 1.297 + if (type != NULL) 1.298 + java_lang_invoke_MemberName::set_type(mname_oop, type); 1.299 + // Note: name and type can be lazily computed by resolve_MemberName, 1.300 + // if Java code needs them as resolved String and Class objects. 1.301 + // Note that the incoming type oop might be pre-resolved (non-null). 1.302 + // The base clazz and field offset (vmindex) must be eagerly stored, 1.303 + // because they unambiguously identify the field. 1.304 + // Although the fieldDescriptor::_index would also identify the field, 1.305 + // we do not use it, because it is harder to decode. 1.306 + // TO DO: maybe intern mname_oop 1.307 + return mname(); 1.308 +} 1.309 + 1.310 +// JVM 2.9 Special Methods: 1.311 +// A method is signature polymorphic if and only if all of the following conditions hold : 1.312 +// * It is declared in the java.lang.invoke.MethodHandle class. 1.313 +// * It has a single formal parameter of type Object[]. 1.314 +// * It has a return type of Object. 1.315 +// * It has the ACC_VARARGS and ACC_NATIVE flags set. 1.316 +bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) { 1.317 + if (klass == NULL) 1.318 + return false; 1.319 + // The following test will fail spuriously during bootstrap of MethodHandle itself: 1.320 + // if (klass != SystemDictionary::MethodHandle_klass()) 1.321 + // Test the name instead: 1.322 + if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle()) 1.323 + return false; 1.324 + Symbol* poly_sig = vmSymbols::object_array_object_signature(); 1.325 + Method* m = InstanceKlass::cast(klass)->find_method(name, poly_sig); 1.326 + if (m == NULL) return false; 1.327 + int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS; 1.328 + int flags = m->access_flags().as_int(); 1.329 + return (flags & required) == required; 1.330 +} 1.331 + 1.332 + 1.333 +Symbol* MethodHandles::signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid) { 1.334 + assert(is_signature_polymorphic_intrinsic(iid), err_msg("iid=%d", iid)); 1.335 + switch (iid) { 1.336 + case vmIntrinsics::_invokeBasic: return vmSymbols::invokeBasic_name(); 1.337 + case vmIntrinsics::_linkToVirtual: return vmSymbols::linkToVirtual_name(); 1.338 + case vmIntrinsics::_linkToStatic: return vmSymbols::linkToStatic_name(); 1.339 + case vmIntrinsics::_linkToSpecial: return vmSymbols::linkToSpecial_name(); 1.340 + case vmIntrinsics::_linkToInterface: return vmSymbols::linkToInterface_name(); 1.341 + } 1.342 + assert(false, ""); 1.343 + return 0; 1.344 +} 1.345 + 1.346 +int MethodHandles::signature_polymorphic_intrinsic_ref_kind(vmIntrinsics::ID iid) { 1.347 + switch (iid) { 1.348 + case vmIntrinsics::_invokeBasic: return 0; 1.349 + case vmIntrinsics::_linkToVirtual: return JVM_REF_invokeVirtual; 1.350 + case vmIntrinsics::_linkToStatic: return JVM_REF_invokeStatic; 1.351 + case vmIntrinsics::_linkToSpecial: return JVM_REF_invokeSpecial; 1.352 + case vmIntrinsics::_linkToInterface: return JVM_REF_invokeInterface; 1.353 + } 1.354 + assert(false, err_msg("iid=%d", iid)); 1.355 + return 0; 1.356 +} 1.357 + 1.358 +vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Symbol* name) { 1.359 + vmSymbols::SID name_id = vmSymbols::find_sid(name); 1.360 + switch (name_id) { 1.361 + // The ID _invokeGeneric stands for all non-static signature-polymorphic methods, except built-ins. 1.362 + case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name): return vmIntrinsics::_invokeGeneric; 1.363 + // The only built-in non-static signature-polymorphic method is MethodHandle.invokeBasic: 1.364 + case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeBasic_name): return vmIntrinsics::_invokeBasic; 1.365 + 1.366 + // There is one static signature-polymorphic method for each JVM invocation mode. 1.367 + case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToVirtual_name): return vmIntrinsics::_linkToVirtual; 1.368 + case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToStatic_name): return vmIntrinsics::_linkToStatic; 1.369 + case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToSpecial_name): return vmIntrinsics::_linkToSpecial; 1.370 + case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToInterface_name): return vmIntrinsics::_linkToInterface; 1.371 + } 1.372 + 1.373 + // Cover the case of invokeExact and any future variants of invokeFoo. 1.374 + Klass* mh_klass = SystemDictionary::well_known_klass( 1.375 + SystemDictionary::WK_KLASS_ENUM_NAME(MethodHandle_klass) ); 1.376 + if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name)) 1.377 + return vmIntrinsics::_invokeGeneric; 1.378 + 1.379 + // Note: The pseudo-intrinsic _compiledLambdaForm is never linked against. 1.380 + // Instead it is used to mark lambda forms bound to invokehandle or invokedynamic. 1.381 + return vmIntrinsics::_none; 1.382 +} 1.383 + 1.384 +vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Klass* klass, Symbol* name) { 1.385 + if (klass != NULL && 1.386 + klass->name() == vmSymbols::java_lang_invoke_MethodHandle()) { 1.387 + vmIntrinsics::ID iid = signature_polymorphic_name_id(name); 1.388 + if (iid != vmIntrinsics::_none) 1.389 + return iid; 1.390 + if (is_method_handle_invoke_name(klass, name)) 1.391 + return vmIntrinsics::_invokeGeneric; 1.392 + } 1.393 + return vmIntrinsics::_none; 1.394 +} 1.395 + 1.396 + 1.397 +// convert the external string or reflective type to an internal signature 1.398 +Symbol* MethodHandles::lookup_signature(oop type_str, bool intern_if_not_found, TRAPS) { 1.399 + if (java_lang_invoke_MethodType::is_instance(type_str)) { 1.400 + return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found, CHECK_NULL); 1.401 + } else if (java_lang_Class::is_instance(type_str)) { 1.402 + return java_lang_Class::as_signature(type_str, false, CHECK_NULL); 1.403 + } else if (java_lang_String::is_instance(type_str)) { 1.404 + if (intern_if_not_found) { 1.405 + return java_lang_String::as_symbol(type_str, CHECK_NULL); 1.406 + } else { 1.407 + return java_lang_String::as_symbol_or_null(type_str); 1.408 + } 1.409 + } else { 1.410 + THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized type", NULL); 1.411 + } 1.412 +} 1.413 + 1.414 +static const char OBJ_SIG[] = "Ljava/lang/Object;"; 1.415 +enum { OBJ_SIG_LEN = 18 }; 1.416 + 1.417 +bool MethodHandles::is_basic_type_signature(Symbol* sig) { 1.418 + assert(vmSymbols::object_signature()->utf8_length() == (int)OBJ_SIG_LEN, ""); 1.419 + assert(vmSymbols::object_signature()->equals(OBJ_SIG), ""); 1.420 + const int len = sig->utf8_length(); 1.421 + for (int i = 0; i < len; i++) { 1.422 + switch (sig->byte_at(i)) { 1.423 + case 'L': 1.424 + // only java/lang/Object is valid here 1.425 + if (sig->index_of_at(i, OBJ_SIG, OBJ_SIG_LEN) != i) 1.426 + return false; 1.427 + i += OBJ_SIG_LEN-1; //-1 because of i++ in loop 1.428 + continue; 1.429 + case '(': case ')': case 'V': 1.430 + case 'I': case 'J': case 'F': case 'D': 1.431 + continue; 1.432 + //case '[': 1.433 + //case 'Z': case 'B': case 'C': case 'S': 1.434 + default: 1.435 + return false; 1.436 + } 1.437 + } 1.438 + return true; 1.439 +} 1.440 + 1.441 +Symbol* MethodHandles::lookup_basic_type_signature(Symbol* sig, bool keep_last_arg, TRAPS) { 1.442 + Symbol* bsig = NULL; 1.443 + if (sig == NULL) { 1.444 + return sig; 1.445 + } else if (is_basic_type_signature(sig)) { 1.446 + sig->increment_refcount(); 1.447 + return sig; // that was easy 1.448 + } else if (sig->byte_at(0) != '(') { 1.449 + BasicType bt = char2type(sig->byte_at(0)); 1.450 + if (is_subword_type(bt)) { 1.451 + bsig = vmSymbols::int_signature(); 1.452 + } else { 1.453 + assert(bt == T_OBJECT || bt == T_ARRAY, "is_basic_type_signature was false"); 1.454 + bsig = vmSymbols::object_signature(); 1.455 + } 1.456 + } else { 1.457 + ResourceMark rm; 1.458 + stringStream buffer(128); 1.459 + buffer.put('('); 1.460 + int arg_pos = 0, keep_arg_pos = -1; 1.461 + if (keep_last_arg) 1.462 + keep_arg_pos = ArgumentCount(sig).size() - 1; 1.463 + for (SignatureStream ss(sig); !ss.is_done(); ss.next()) { 1.464 + BasicType bt = ss.type(); 1.465 + size_t this_arg_pos = buffer.size(); 1.466 + if (ss.at_return_type()) { 1.467 + buffer.put(')'); 1.468 + } 1.469 + if (arg_pos == keep_arg_pos) { 1.470 + buffer.write((char*) ss.raw_bytes(), 1.471 + (int) ss.raw_length()); 1.472 + } else if (bt == T_OBJECT || bt == T_ARRAY) { 1.473 + buffer.write(OBJ_SIG, OBJ_SIG_LEN); 1.474 + } else { 1.475 + if (is_subword_type(bt)) 1.476 + bt = T_INT; 1.477 + buffer.put(type2char(bt)); 1.478 + } 1.479 + arg_pos++; 1.480 + } 1.481 + const char* sigstr = buffer.base(); 1.482 + int siglen = (int) buffer.size(); 1.483 + bsig = SymbolTable::new_symbol(sigstr, siglen, THREAD); 1.484 + } 1.485 + assert(is_basic_type_signature(bsig) || 1.486 + // detune assert in case the injected argument is not a basic type: 1.487 + keep_last_arg, ""); 1.488 + return bsig; 1.489 +} 1.490 + 1.491 +void MethodHandles::print_as_basic_type_signature_on(outputStream* st, 1.492 + Symbol* sig, 1.493 + bool keep_arrays, 1.494 + bool keep_basic_names) { 1.495 + st = st ? st : tty; 1.496 + int len = sig->utf8_length(); 1.497 + int array = 0; 1.498 + bool prev_type = false; 1.499 + for (int i = 0; i < len; i++) { 1.500 + char ch = sig->byte_at(i); 1.501 + switch (ch) { 1.502 + case '(': case ')': 1.503 + prev_type = false; 1.504 + st->put(ch); 1.505 + continue; 1.506 + case '[': 1.507 + if (!keep_basic_names && keep_arrays) 1.508 + st->put(ch); 1.509 + array++; 1.510 + continue; 1.511 + case 'L': 1.512 + { 1.513 + if (prev_type) st->put(','); 1.514 + int start = i+1, slash = start; 1.515 + while (++i < len && (ch = sig->byte_at(i)) != ';') { 1.516 + if (ch == '/' || ch == '.' || ch == '$') slash = i+1; 1.517 + } 1.518 + if (slash < i) start = slash; 1.519 + if (!keep_basic_names) { 1.520 + st->put('L'); 1.521 + } else { 1.522 + for (int j = start; j < i; j++) 1.523 + st->put(sig->byte_at(j)); 1.524 + prev_type = true; 1.525 + } 1.526 + break; 1.527 + } 1.528 + default: 1.529 + { 1.530 + if (array && char2type(ch) != T_ILLEGAL && !keep_arrays) { 1.531 + ch = '['; 1.532 + array = 0; 1.533 + } 1.534 + if (prev_type) st->put(','); 1.535 + const char* n = NULL; 1.536 + if (keep_basic_names) 1.537 + n = type2name(char2type(ch)); 1.538 + if (n == NULL) { 1.539 + // unknown letter, or we don't want to know its name 1.540 + st->put(ch); 1.541 + } else { 1.542 + st->print("%s", n); 1.543 + prev_type = true; 1.544 + } 1.545 + break; 1.546 + } 1.547 + } 1.548 + // Switch break goes here to take care of array suffix: 1.549 + if (prev_type) { 1.550 + while (array > 0) { 1.551 + st->print("[]"); 1.552 + --array; 1.553 + } 1.554 + } 1.555 + array = 0; 1.556 + } 1.557 +} 1.558 + 1.559 + 1.560 + 1.561 +static oop object_java_mirror() { 1.562 + return SystemDictionary::Object_klass()->java_mirror(); 1.563 +} 1.564 + 1.565 +oop MethodHandles::field_name_or_null(Symbol* s) { 1.566 + if (s == NULL) return NULL; 1.567 + return StringTable::lookup(s); 1.568 +} 1.569 + 1.570 +oop MethodHandles::field_signature_type_or_null(Symbol* s) { 1.571 + if (s == NULL) return NULL; 1.572 + BasicType bt = FieldType::basic_type(s); 1.573 + if (is_java_primitive(bt)) { 1.574 + assert(s->utf8_length() == 1, ""); 1.575 + return java_lang_Class::primitive_mirror(bt); 1.576 + } 1.577 + // Here are some more short cuts for common types. 1.578 + // They are optional, since reference types can be resolved lazily. 1.579 + if (bt == T_OBJECT) { 1.580 + if (s == vmSymbols::object_signature()) { 1.581 + return object_java_mirror(); 1.582 + } else if (s == vmSymbols::class_signature()) { 1.583 + return SystemDictionary::Class_klass()->java_mirror(); 1.584 + } else if (s == vmSymbols::string_signature()) { 1.585 + return SystemDictionary::String_klass()->java_mirror(); 1.586 + } 1.587 + } 1.588 + return NULL; 1.589 +} 1.590 + 1.591 + 1.592 +// An unresolved member name is a mere symbolic reference. 1.593 +// Resolving it plants a vmtarget/vmindex in it, 1.594 +// which refers directly to JVM internals. 1.595 +Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS) { 1.596 + Handle empty; 1.597 + assert(java_lang_invoke_MemberName::is_instance(mname()), ""); 1.598 + 1.599 + if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) { 1.600 + // Already resolved. 1.601 + DEBUG_ONLY(int vmindex = java_lang_invoke_MemberName::vmindex(mname())); 1.602 + assert(vmindex >= Method::nonvirtual_vtable_index, ""); 1.603 + return mname; 1.604 + } 1.605 + 1.606 + Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname())); 1.607 + Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname())); 1.608 + Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname())); 1.609 + int flags = java_lang_invoke_MemberName::flags(mname()); 1.610 + int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; 1.611 + if (!ref_kind_is_valid(ref_kind)) { 1.612 + THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty); 1.613 + } 1.614 + 1.615 + DEBUG_ONLY(int old_vmindex); 1.616 + assert((old_vmindex = java_lang_invoke_MemberName::vmindex(mname())) == 0, "clean input"); 1.617 + 1.618 + if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) { 1.619 + THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty); 1.620 + } 1.621 + 1.622 + instanceKlassHandle defc; 1.623 + { 1.624 + Klass* defc_klass = java_lang_Class::as_Klass(defc_oop()); 1.625 + if (defc_klass == NULL) return empty; // a primitive; no resolution possible 1.626 + if (!defc_klass->oop_is_instance()) { 1.627 + if (!defc_klass->oop_is_array()) return empty; 1.628 + defc_klass = SystemDictionary::Object_klass(); 1.629 + } 1.630 + defc = instanceKlassHandle(THREAD, defc_klass); 1.631 + } 1.632 + if (defc.is_null()) { 1.633 + THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty); 1.634 + } 1.635 + defc->link_class(CHECK_(empty)); // possible safepoint 1.636 + 1.637 + // convert the external string name to an internal symbol 1.638 + TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str()); 1.639 + if (name == NULL) return empty; // no such name 1.640 + if (name == vmSymbols::class_initializer_name()) 1.641 + return empty; // illegal name 1.642 + 1.643 + vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none; 1.644 + if ((flags & ALL_KINDS) == IS_METHOD && 1.645 + (defc() == SystemDictionary::MethodHandle_klass()) && 1.646 + (ref_kind == JVM_REF_invokeVirtual || 1.647 + ref_kind == JVM_REF_invokeSpecial || 1.648 + // static invocation mode is required for _linkToVirtual, etc.: 1.649 + ref_kind == JVM_REF_invokeStatic)) { 1.650 + vmIntrinsics::ID iid = signature_polymorphic_name_id(name); 1.651 + if (iid != vmIntrinsics::_none && 1.652 + ((ref_kind == JVM_REF_invokeStatic) == is_signature_polymorphic_static(iid))) { 1.653 + // Virtual methods invoke and invokeExact, plus internal invokers like _invokeBasic. 1.654 + // For a static reference it could an internal linkage routine like _linkToVirtual, etc. 1.655 + mh_invoke_id = iid; 1.656 + } 1.657 + } 1.658 + 1.659 + // convert the external string or reflective type to an internal signature 1.660 + TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty)); 1.661 + if (type == NULL) return empty; // no such signature exists in the VM 1.662 + 1.663 + // Time to do the lookup. 1.664 + switch (flags & ALL_KINDS) { 1.665 + case IS_METHOD: 1.666 + { 1.667 + CallInfo result; 1.668 + { 1.669 + assert(!HAS_PENDING_EXCEPTION, ""); 1.670 + if (ref_kind == JVM_REF_invokeStatic) { 1.671 + LinkResolver::resolve_static_call(result, 1.672 + defc, name, type, caller, caller.not_null(), false, THREAD); 1.673 + } else if (ref_kind == JVM_REF_invokeInterface) { 1.674 + LinkResolver::resolve_interface_call(result, Handle(), defc, 1.675 + defc, name, type, caller, caller.not_null(), false, THREAD); 1.676 + } else if (mh_invoke_id != vmIntrinsics::_none) { 1.677 + assert(!is_signature_polymorphic_static(mh_invoke_id), ""); 1.678 + LinkResolver::resolve_handle_call(result, 1.679 + defc, name, type, caller, THREAD); 1.680 + } else if (ref_kind == JVM_REF_invokeSpecial) { 1.681 + LinkResolver::resolve_special_call(result, 1.682 + defc, name, type, caller, caller.not_null(), THREAD); 1.683 + } else if (ref_kind == JVM_REF_invokeVirtual) { 1.684 + LinkResolver::resolve_virtual_call(result, Handle(), defc, 1.685 + defc, name, type, caller, caller.not_null(), false, THREAD); 1.686 + } else { 1.687 + assert(false, err_msg("ref_kind=%d", ref_kind)); 1.688 + } 1.689 + if (HAS_PENDING_EXCEPTION) { 1.690 + return empty; 1.691 + } 1.692 + } 1.693 + if (result.resolved_appendix().not_null()) { 1.694 + // The resolved MemberName must not be accompanied by an appendix argument, 1.695 + // since there is no way to bind this value into the MemberName. 1.696 + // Caller is responsible to prevent this from happening. 1.697 + THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); 1.698 + } 1.699 + oop mname2 = init_method_MemberName(mname, result); 1.700 + return Handle(THREAD, mname2); 1.701 + } 1.702 + case IS_CONSTRUCTOR: 1.703 + { 1.704 + CallInfo result; 1.705 + { 1.706 + assert(!HAS_PENDING_EXCEPTION, ""); 1.707 + if (name == vmSymbols::object_initializer_name()) { 1.708 + LinkResolver::resolve_special_call(result, 1.709 + defc, name, type, caller, caller.not_null(), THREAD); 1.710 + } else { 1.711 + break; // will throw after end of switch 1.712 + } 1.713 + if (HAS_PENDING_EXCEPTION) { 1.714 + return empty; 1.715 + } 1.716 + } 1.717 + assert(result.is_statically_bound(), ""); 1.718 + oop mname2 = init_method_MemberName(mname, result); 1.719 + return Handle(THREAD, mname2); 1.720 + } 1.721 + case IS_FIELD: 1.722 + { 1.723 + fieldDescriptor result; // find_field initializes fd if found 1.724 + { 1.725 + assert(!HAS_PENDING_EXCEPTION, ""); 1.726 + LinkResolver::resolve_field(result, defc, name, type, caller, Bytecodes::_nop, false, false, THREAD); 1.727 + if (HAS_PENDING_EXCEPTION) { 1.728 + return empty; 1.729 + } 1.730 + } 1.731 + oop mname2 = init_field_MemberName(mname, result, ref_kind_is_setter(ref_kind)); 1.732 + return Handle(THREAD, mname2); 1.733 + } 1.734 + default: 1.735 + THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty); 1.736 + } 1.737 + 1.738 + return empty; 1.739 +} 1.740 + 1.741 +// Conversely, a member name which is only initialized from JVM internals 1.742 +// may have null defc, name, and type fields. 1.743 +// Resolving it plants a vmtarget/vmindex in it, 1.744 +// which refers directly to JVM internals. 1.745 +void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { 1.746 + assert(java_lang_invoke_MemberName::is_instance(mname()), ""); 1.747 + Metadata* vmtarget = java_lang_invoke_MemberName::vmtarget(mname()); 1.748 + int vmindex = java_lang_invoke_MemberName::vmindex(mname()); 1.749 + if (vmtarget == NULL) { 1.750 + THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand"); 1.751 + } 1.752 + 1.753 + bool have_defc = (java_lang_invoke_MemberName::clazz(mname()) != NULL); 1.754 + bool have_name = (java_lang_invoke_MemberName::name(mname()) != NULL); 1.755 + bool have_type = (java_lang_invoke_MemberName::type(mname()) != NULL); 1.756 + int flags = java_lang_invoke_MemberName::flags(mname()); 1.757 + 1.758 + if (suppress != 0) { 1.759 + if (suppress & _suppress_defc) have_defc = true; 1.760 + if (suppress & _suppress_name) have_name = true; 1.761 + if (suppress & _suppress_type) have_type = true; 1.762 + } 1.763 + 1.764 + if (have_defc && have_name && have_type) return; // nothing needed 1.765 + 1.766 + switch (flags & ALL_KINDS) { 1.767 + case IS_METHOD: 1.768 + case IS_CONSTRUCTOR: 1.769 + { 1.770 + assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); 1.771 + methodHandle m(THREAD, (Method*)vmtarget); 1.772 + DEBUG_ONLY(vmtarget = NULL); // safety 1.773 + if (m.is_null()) break; 1.774 + if (!have_defc) { 1.775 + InstanceKlass* defc = m->method_holder(); 1.776 + java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror()); 1.777 + } 1.778 + if (!have_name) { 1.779 + //not java_lang_String::create_from_symbol; let's intern member names 1.780 + Handle name = StringTable::intern(m->name(), CHECK); 1.781 + java_lang_invoke_MemberName::set_name(mname(), name()); 1.782 + } 1.783 + if (!have_type) { 1.784 + Handle type = java_lang_String::create_from_symbol(m->signature(), CHECK); 1.785 + java_lang_invoke_MemberName::set_type(mname(), type()); 1.786 + } 1.787 + return; 1.788 + } 1.789 + case IS_FIELD: 1.790 + { 1.791 + assert(vmtarget->is_klass(), "field vmtarget is Klass*"); 1.792 + if (!((Klass*) vmtarget)->oop_is_instance()) break; 1.793 + instanceKlassHandle defc(THREAD, (Klass*) vmtarget); 1.794 + DEBUG_ONLY(vmtarget = NULL); // safety 1.795 + bool is_static = ((flags & JVM_ACC_STATIC) != 0); 1.796 + fieldDescriptor fd; // find_field initializes fd if found 1.797 + if (!defc->find_field_from_offset(vmindex, is_static, &fd)) 1.798 + break; // cannot expand 1.799 + if (!have_defc) { 1.800 + java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror()); 1.801 + } 1.802 + if (!have_name) { 1.803 + //not java_lang_String::create_from_symbol; let's intern member names 1.804 + Handle name = StringTable::intern(fd.name(), CHECK); 1.805 + java_lang_invoke_MemberName::set_name(mname(), name()); 1.806 + } 1.807 + if (!have_type) { 1.808 + // If it is a primitive field type, don't mess with short strings like "I". 1.809 + Handle type = field_signature_type_or_null(fd.signature()); 1.810 + if (type.is_null()) { 1.811 + java_lang_String::create_from_symbol(fd.signature(), CHECK); 1.812 + } 1.813 + java_lang_invoke_MemberName::set_type(mname(), type()); 1.814 + } 1.815 + return; 1.816 + } 1.817 + } 1.818 + THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); 1.819 +} 1.820 + 1.821 +int MethodHandles::find_MemberNames(KlassHandle k, 1.822 + Symbol* name, Symbol* sig, 1.823 + int mflags, KlassHandle caller, 1.824 + int skip, objArrayHandle results) { 1.825 + // %%% take caller into account! 1.826 + 1.827 + Thread* thread = Thread::current(); 1.828 + 1.829 + if (k.is_null() || !k->oop_is_instance()) return -1; 1.830 + 1.831 + int rfill = 0, rlimit = results->length(), rskip = skip; 1.832 + // overflow measurement: 1.833 + int overflow = 0, overflow_limit = MAX2(1000, rlimit); 1.834 + 1.835 + int match_flags = mflags; 1.836 + bool search_superc = ((match_flags & SEARCH_SUPERCLASSES) != 0); 1.837 + bool search_intfc = ((match_flags & SEARCH_INTERFACES) != 0); 1.838 + bool local_only = !(search_superc | search_intfc); 1.839 + bool classes_only = false; 1.840 + 1.841 + if (name != NULL) { 1.842 + if (name->utf8_length() == 0) return 0; // a match is not possible 1.843 + } 1.844 + if (sig != NULL) { 1.845 + if (sig->utf8_length() == 0) return 0; // a match is not possible 1.846 + if (sig->byte_at(0) == '(') 1.847 + match_flags &= ~(IS_FIELD | IS_TYPE); 1.848 + else 1.849 + match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD); 1.850 + } 1.851 + 1.852 + if ((match_flags & IS_TYPE) != 0) { 1.853 + // NYI, and Core Reflection works quite well for this query 1.854 + } 1.855 + 1.856 + if ((match_flags & IS_FIELD) != 0) { 1.857 + for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) { 1.858 + if (name != NULL && st.name() != name) 1.859 + continue; 1.860 + if (sig != NULL && st.signature() != sig) 1.861 + continue; 1.862 + // passed the filters 1.863 + if (rskip > 0) { 1.864 + --rskip; 1.865 + } else if (rfill < rlimit) { 1.866 + Handle result(thread, results->obj_at(rfill++)); 1.867 + if (!java_lang_invoke_MemberName::is_instance(result())) 1.868 + return -99; // caller bug! 1.869 + oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor()); 1.870 + if (saved != result()) 1.871 + results->obj_at_put(rfill-1, saved); // show saved instance to user 1.872 + } else if (++overflow >= overflow_limit) { 1.873 + match_flags = 0; break; // got tired of looking at overflow 1.874 + } 1.875 + } 1.876 + } 1.877 + 1.878 + if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { 1.879 + // watch out for these guys: 1.880 + Symbol* init_name = vmSymbols::object_initializer_name(); 1.881 + Symbol* clinit_name = vmSymbols::class_initializer_name(); 1.882 + if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit> 1.883 + bool negate_name_test = false; 1.884 + // fix name so that it captures the intention of IS_CONSTRUCTOR 1.885 + if (!(match_flags & IS_METHOD)) { 1.886 + // constructors only 1.887 + if (name == NULL) { 1.888 + name = init_name; 1.889 + } else if (name != init_name) { 1.890 + return 0; // no constructors of this method name 1.891 + } 1.892 + } else if (!(match_flags & IS_CONSTRUCTOR)) { 1.893 + // methods only 1.894 + if (name == NULL) { 1.895 + name = init_name; 1.896 + negate_name_test = true; // if we see the name, we *omit* the entry 1.897 + } else if (name == init_name) { 1.898 + return 0; // no methods of this constructor name 1.899 + } 1.900 + } else { 1.901 + // caller will accept either sort; no need to adjust name 1.902 + } 1.903 + for (MethodStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) { 1.904 + Method* m = st.method(); 1.905 + Symbol* m_name = m->name(); 1.906 + if (m_name == clinit_name) 1.907 + continue; 1.908 + if (name != NULL && ((m_name != name) ^ negate_name_test)) 1.909 + continue; 1.910 + if (sig != NULL && m->signature() != sig) 1.911 + continue; 1.912 + // passed the filters 1.913 + if (rskip > 0) { 1.914 + --rskip; 1.915 + } else if (rfill < rlimit) { 1.916 + Handle result(thread, results->obj_at(rfill++)); 1.917 + if (!java_lang_invoke_MemberName::is_instance(result())) 1.918 + return -99; // caller bug! 1.919 + CallInfo info(m); 1.920 + oop saved = MethodHandles::init_method_MemberName(result, info); 1.921 + if (saved != result()) 1.922 + results->obj_at_put(rfill-1, saved); // show saved instance to user 1.923 + } else if (++overflow >= overflow_limit) { 1.924 + match_flags = 0; break; // got tired of looking at overflow 1.925 + } 1.926 + } 1.927 + } 1.928 + 1.929 + // return number of elements we at leasted wanted to initialize 1.930 + return rfill + overflow; 1.931 +} 1.932 + 1.933 +//------------------------------------------------------------------------------ 1.934 +// MemberNameTable 1.935 +// 1.936 + 1.937 +MemberNameTable::MemberNameTable(int methods_cnt) 1.938 + : GrowableArray<jweak>(methods_cnt, true) { 1.939 + assert_locked_or_safepoint(MemberNameTable_lock); 1.940 +} 1.941 + 1.942 +MemberNameTable::~MemberNameTable() { 1.943 + assert_locked_or_safepoint(MemberNameTable_lock); 1.944 + int len = this->length(); 1.945 + 1.946 + for (int idx = 0; idx < len; idx++) { 1.947 + jweak ref = this->at(idx); 1.948 + JNIHandles::destroy_weak_global(ref); 1.949 + } 1.950 +} 1.951 + 1.952 +void MemberNameTable::add_member_name(int index, jweak mem_name_wref) { 1.953 + assert_locked_or_safepoint(MemberNameTable_lock); 1.954 + this->at_put_grow(index, mem_name_wref); 1.955 +} 1.956 + 1.957 +// Return a member name oop or NULL. 1.958 +oop MemberNameTable::get_member_name(int index) { 1.959 + assert_locked_or_safepoint(MemberNameTable_lock); 1.960 + 1.961 + jweak ref = this->at(index); 1.962 + oop mem_name = JNIHandles::resolve(ref); 1.963 + return mem_name; 1.964 +} 1.965 + 1.966 +#if INCLUDE_JVMTI 1.967 +oop MemberNameTable::find_member_name_by_method(Method* old_method) { 1.968 + assert_locked_or_safepoint(MemberNameTable_lock); 1.969 + oop found = NULL; 1.970 + int len = this->length(); 1.971 + 1.972 + for (int idx = 0; idx < len; idx++) { 1.973 + oop mem_name = JNIHandles::resolve(this->at(idx)); 1.974 + if (mem_name == NULL) { 1.975 + continue; 1.976 + } 1.977 + Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name); 1.978 + if (method == old_method) { 1.979 + found = mem_name; 1.980 + break; 1.981 + } 1.982 + } 1.983 + return found; 1.984 +} 1.985 + 1.986 +// It is called at safepoint only 1.987 +void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods, 1.988 + int methods_length, bool *trace_name_printed) { 1.989 + assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); 1.990 + // search the MemberNameTable for uses of either obsolete or EMCP methods 1.991 + for (int j = 0; j < methods_length; j++) { 1.992 + Method* old_method = old_methods[j]; 1.993 + Method* new_method = new_methods[j]; 1.994 + oop mem_name = find_member_name_by_method(old_method); 1.995 + if (mem_name != NULL) { 1.996 + java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method); 1.997 + 1.998 + if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { 1.999 + if (!(*trace_name_printed)) { 1.1000 + // RC_TRACE_MESG macro has an embedded ResourceMark 1.1001 + RC_TRACE_MESG(("adjust: name=%s", 1.1002 + old_method->method_holder()->external_name())); 1.1003 + *trace_name_printed = true; 1.1004 + } 1.1005 + // RC_TRACE macro has an embedded ResourceMark 1.1006 + RC_TRACE(0x00400000, ("MemberName method update: %s(%s)", 1.1007 + new_method->name()->as_C_string(), 1.1008 + new_method->signature()->as_C_string())); 1.1009 + } 1.1010 + } 1.1011 + } 1.1012 +} 1.1013 +#endif // INCLUDE_JVMTI 1.1014 + 1.1015 +// 1.1016 +// Here are the native methods in java.lang.invoke.MethodHandleNatives 1.1017 +// They are the private interface between this JVM and the HotSpot-specific 1.1018 +// Java code that implements JSR 292 method handles. 1.1019 +// 1.1020 +// Note: We use a JVM_ENTRY macro to define each of these, for this is the way 1.1021 +// that intrinsic (non-JNI) native methods are defined in HotSpot. 1.1022 +// 1.1023 + 1.1024 +JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) { 1.1025 + switch (which) { 1.1026 + case MethodHandles::GC_COUNT_GWT: 1.1027 +#ifdef COMPILER2 1.1028 + return true; 1.1029 +#else 1.1030 + return false; 1.1031 +#endif 1.1032 + } 1.1033 + return 0; 1.1034 +} 1.1035 +JVM_END 1.1036 + 1.1037 +#ifndef PRODUCT 1.1038 +#define EACH_NAMED_CON(template, requirement) \ 1.1039 + template(MethodHandles,GC_COUNT_GWT) \ 1.1040 + template(java_lang_invoke_MemberName,MN_IS_METHOD) \ 1.1041 + template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \ 1.1042 + template(java_lang_invoke_MemberName,MN_IS_FIELD) \ 1.1043 + template(java_lang_invoke_MemberName,MN_IS_TYPE) \ 1.1044 + template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \ 1.1045 + template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \ 1.1046 + template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \ 1.1047 + template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \ 1.1048 + template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \ 1.1049 + template(MethodHandles,GC_LAMBDA_SUPPORT) \ 1.1050 + /*end*/ 1.1051 + 1.1052 +#define IGNORE_REQ(req_expr) /* req_expr */ 1.1053 +#define ONE_PLUS(scope,value) 1+ 1.1054 +static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0; 1.1055 +#define VALUE_COMMA(scope,value) scope::value, 1.1056 +static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 }; 1.1057 +#define STRING_NULL(scope,value) #value "\0" 1.1058 +static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) }; 1.1059 + 1.1060 +static bool advertise_con_value(int which) { 1.1061 + if (which < 0) return false; 1.1062 + bool ok = true; 1.1063 + int count = 0; 1.1064 +#define INC_COUNT(scope,value) \ 1.1065 + ++count; 1.1066 +#define CHECK_REQ(req_expr) \ 1.1067 + if (which < count) return ok; \ 1.1068 + ok = (req_expr); 1.1069 + EACH_NAMED_CON(INC_COUNT, CHECK_REQ); 1.1070 +#undef INC_COUNT 1.1071 +#undef CHECK_REQ 1.1072 + assert(count == con_value_count, ""); 1.1073 + if (which < count) return ok; 1.1074 + return false; 1.1075 +} 1.1076 + 1.1077 +#undef ONE_PLUS 1.1078 +#undef VALUE_COMMA 1.1079 +#undef STRING_NULL 1.1080 +#undef EACH_NAMED_CON 1.1081 +#endif // PRODUCT 1.1082 + 1.1083 +JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) { 1.1084 +#ifndef PRODUCT 1.1085 + if (advertise_con_value(which)) { 1.1086 + assert(which >= 0 && which < con_value_count, ""); 1.1087 + int con = con_values[which]; 1.1088 + objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh)); 1.1089 + if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { 1.1090 + const char* str = &con_names[0]; 1.1091 + for (int i = 0; i < which; i++) 1.1092 + str += strlen(str) + 1; // skip name and null 1.1093 + oop name = java_lang_String::create_oop_from_str(str, CHECK_0); // possible safepoint 1.1094 + box->obj_at_put(0, name); 1.1095 + } 1.1096 + return con; 1.1097 + } 1.1098 +#endif 1.1099 + return 0; 1.1100 +} 1.1101 +JVM_END 1.1102 + 1.1103 +// void init(MemberName self, AccessibleObject ref) 1.1104 +JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { 1.1105 + if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } 1.1106 + if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } 1.1107 + Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); 1.1108 + Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); 1.1109 + MethodHandles::init_MemberName(mname, target); 1.1110 +} 1.1111 +JVM_END 1.1112 + 1.1113 +// void expand(MemberName self) 1.1114 +JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { 1.1115 + if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } 1.1116 + Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); 1.1117 + MethodHandles::expand_MemberName(mname, 0, CHECK); 1.1118 +} 1.1119 +JVM_END 1.1120 + 1.1121 +// void resolve(MemberName self, Class<?> caller) 1.1122 +JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) { 1.1123 + if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); } 1.1124 + Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); 1.1125 + 1.1126 + // The trusted Java code that calls this method should already have performed 1.1127 + // access checks on behalf of the given caller. But, we can verify this. 1.1128 + if (VerifyMethodHandles && caller_jh != NULL && 1.1129 + java_lang_invoke_MemberName::clazz(mname()) != NULL) { 1.1130 + Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname())); 1.1131 + if (reference_klass != NULL && reference_klass->oop_is_objArray()) { 1.1132 + reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass(); 1.1133 + } 1.1134 + 1.1135 + // Reflection::verify_class_access can only handle instance classes. 1.1136 + if (reference_klass != NULL && reference_klass->oop_is_instance()) { 1.1137 + // Emulate LinkResolver::check_klass_accessability. 1.1138 + Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh)); 1.1139 + if (!Reflection::verify_class_access(caller, 1.1140 + reference_klass, 1.1141 + true)) { 1.1142 + THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name()); 1.1143 + } 1.1144 + } 1.1145 + } 1.1146 + 1.1147 + KlassHandle caller(THREAD, 1.1148 + caller_jh == NULL ? (Klass*) NULL : 1.1149 + java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh))); 1.1150 + Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL); 1.1151 + 1.1152 + if (resolved.is_null()) { 1.1153 + int flags = java_lang_invoke_MemberName::flags(mname()); 1.1154 + int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; 1.1155 + if (!MethodHandles::ref_kind_is_valid(ref_kind)) { 1.1156 + THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format"); 1.1157 + } 1.1158 + if ((flags & ALL_KINDS) == IS_FIELD) { 1.1159 + THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "field resolution failed"); 1.1160 + } else if ((flags & ALL_KINDS) == IS_METHOD || 1.1161 + (flags & ALL_KINDS) == IS_CONSTRUCTOR) { 1.1162 + THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "method resolution failed"); 1.1163 + } else { 1.1164 + THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed"); 1.1165 + } 1.1166 + } 1.1167 + 1.1168 + return JNIHandles::make_local(THREAD, resolved()); 1.1169 +} 1.1170 +JVM_END 1.1171 + 1.1172 +static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) { 1.1173 + if (mname == NULL || 1.1174 + java_lang_invoke_MemberName::vmtarget(mname) == NULL) { 1.1175 + THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved"); 1.1176 + } else { 1.1177 + int flags = java_lang_invoke_MemberName::flags(mname); 1.1178 + if ((flags & IS_FIELD) != 0 && 1.1179 + (must_be_static 1.1180 + ? (flags & JVM_ACC_STATIC) != 0 1.1181 + : (flags & JVM_ACC_STATIC) == 0)) { 1.1182 + int vmindex = java_lang_invoke_MemberName::vmindex(mname); 1.1183 + return (jlong) vmindex; 1.1184 + } 1.1185 + } 1.1186 + const char* msg = (must_be_static ? "static field required" : "non-static field required"); 1.1187 + THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg); 1.1188 + return 0; 1.1189 +} 1.1190 + 1.1191 +JVM_ENTRY(jlong, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) { 1.1192 + return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD); 1.1193 +} 1.1194 +JVM_END 1.1195 + 1.1196 +JVM_ENTRY(jlong, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) { 1.1197 + return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD); 1.1198 +} 1.1199 +JVM_END 1.1200 + 1.1201 +JVM_ENTRY(jobject, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) { 1.1202 + // use the other function to perform sanity checks: 1.1203 + jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL); 1.1204 + oop clazz = java_lang_invoke_MemberName::clazz(JNIHandles::resolve_non_null(mname_jh)); 1.1205 + return JNIHandles::make_local(THREAD, clazz); 1.1206 +} 1.1207 +JVM_END 1.1208 + 1.1209 +JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname_jh)) { 1.1210 + if (mname_jh == NULL) return NULL; 1.1211 + Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); 1.1212 + intptr_t vmindex = java_lang_invoke_MemberName::vmindex(mname()); 1.1213 + Metadata* vmtarget = java_lang_invoke_MemberName::vmtarget(mname()); 1.1214 + objArrayHandle result = oopFactory::new_objArray(SystemDictionary::Object_klass(), 2, CHECK_NULL); 1.1215 + jvalue vmindex_value; vmindex_value.j = (long)vmindex; 1.1216 + oop x = java_lang_boxing_object::create(T_LONG, &vmindex_value, CHECK_NULL); 1.1217 + result->obj_at_put(0, x); 1.1218 + x = NULL; 1.1219 + if (vmtarget == NULL) { 1.1220 + x = NULL; 1.1221 + } else if (vmtarget->is_klass()) { 1.1222 + x = ((Klass*) vmtarget)->java_mirror(); 1.1223 + } else if (vmtarget->is_method()) { 1.1224 + x = mname(); 1.1225 + } 1.1226 + result->obj_at_put(1, x); 1.1227 + return JNIHandles::make_local(env, result()); 1.1228 +} 1.1229 +JVM_END 1.1230 + 1.1231 + 1.1232 + 1.1233 +// static native int getMembers(Class<?> defc, String matchName, String matchSig, 1.1234 +// int matchFlags, Class<?> caller, int skip, MemberName[] results); 1.1235 +JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, 1.1236 + jclass clazz_jh, jstring name_jh, jstring sig_jh, 1.1237 + int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { 1.1238 + if (clazz_jh == NULL || results_jh == NULL) return -1; 1.1239 + KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz_jh))); 1.1240 + 1.1241 + objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); 1.1242 + if (results.is_null() || !results->is_objArray()) return -1; 1.1243 + 1.1244 + TempNewSymbol name = NULL; 1.1245 + TempNewSymbol sig = NULL; 1.1246 + if (name_jh != NULL) { 1.1247 + name = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(name_jh)); 1.1248 + if (name == NULL) return 0; // a match is not possible 1.1249 + } 1.1250 + if (sig_jh != NULL) { 1.1251 + sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh)); 1.1252 + if (sig == NULL) return 0; // a match is not possible 1.1253 + } 1.1254 + 1.1255 + KlassHandle caller; 1.1256 + if (caller_jh != NULL) { 1.1257 + oop caller_oop = JNIHandles::resolve_non_null(caller_jh); 1.1258 + if (!java_lang_Class::is_instance(caller_oop)) return -1; 1.1259 + caller = KlassHandle(THREAD, java_lang_Class::as_Klass(caller_oop)); 1.1260 + } 1.1261 + 1.1262 + if (name != NULL && sig != NULL && results.not_null()) { 1.1263 + // try a direct resolve 1.1264 + // %%% TO DO 1.1265 + } 1.1266 + 1.1267 + int res = MethodHandles::find_MemberNames(k, name, sig, mflags, 1.1268 + caller, skip, results); 1.1269 + // TO DO: expand at least some of the MemberNames, to avoid massive callbacks 1.1270 + return res; 1.1271 +} 1.1272 +JVM_END 1.1273 + 1.1274 +JVM_ENTRY(void, MHN_setCallSiteTargetNormal(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) { 1.1275 + Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh)); 1.1276 + Handle target (THREAD, JNIHandles::resolve(target_jh)); 1.1277 + { 1.1278 + // Walk all nmethods depending on this call site. 1.1279 + MutexLocker mu(Compile_lock, thread); 1.1280 + Universe::flush_dependents_on(call_site, target); 1.1281 + java_lang_invoke_CallSite::set_target(call_site(), target()); 1.1282 + } 1.1283 +} 1.1284 +JVM_END 1.1285 + 1.1286 +JVM_ENTRY(void, MHN_setCallSiteTargetVolatile(JNIEnv* env, jobject igcls, jobject call_site_jh, jobject target_jh)) { 1.1287 + Handle call_site(THREAD, JNIHandles::resolve_non_null(call_site_jh)); 1.1288 + Handle target (THREAD, JNIHandles::resolve(target_jh)); 1.1289 + { 1.1290 + // Walk all nmethods depending on this call site. 1.1291 + MutexLocker mu(Compile_lock, thread); 1.1292 + Universe::flush_dependents_on(call_site, target); 1.1293 + java_lang_invoke_CallSite::set_target_volatile(call_site(), target()); 1.1294 + } 1.1295 +} 1.1296 +JVM_END 1.1297 + 1.1298 +/** 1.1299 + * Throws a java/lang/UnsupportedOperationException unconditionally. 1.1300 + * This is required by the specification of MethodHandle.invoke if 1.1301 + * invoked directly. 1.1302 + */ 1.1303 +JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) { 1.1304 + THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively"); 1.1305 + return NULL; 1.1306 +} 1.1307 +JVM_END 1.1308 + 1.1309 +/** 1.1310 + * Throws a java/lang/UnsupportedOperationException unconditionally. 1.1311 + * This is required by the specification of MethodHandle.invokeExact if 1.1312 + * invoked directly. 1.1313 + */ 1.1314 +JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) { 1.1315 + THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively"); 1.1316 + return NULL; 1.1317 +} 1.1318 +JVM_END 1.1319 + 1.1320 +/// JVM_RegisterMethodHandleMethods 1.1321 + 1.1322 +#undef CS // Solaris builds complain 1.1323 + 1.1324 +#define LANG "Ljava/lang/" 1.1325 +#define JLINV "Ljava/lang/invoke/" 1.1326 + 1.1327 +#define OBJ LANG"Object;" 1.1328 +#define CLS LANG"Class;" 1.1329 +#define STRG LANG"String;" 1.1330 +#define CS JLINV"CallSite;" 1.1331 +#define MT JLINV"MethodType;" 1.1332 +#define MH JLINV"MethodHandle;" 1.1333 +#define MEM JLINV"MemberName;" 1.1334 + 1.1335 +#define CC (char*) /*cast a literal from (const char*)*/ 1.1336 +#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) 1.1337 + 1.1338 +// These are the native methods on java.lang.invoke.MethodHandleNatives. 1.1339 +static JNINativeMethod MHN_methods[] = { 1.1340 + {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)}, 1.1341 + {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)}, 1.1342 + {CC"resolve", CC"("MEM""CLS")"MEM, FN_PTR(MHN_resolve_Mem)}, 1.1343 + {CC"getConstant", CC"(I)I", FN_PTR(MHN_getConstant)}, 1.1344 + // static native int getNamedCon(int which, Object[] name) 1.1345 + {CC"getNamedCon", CC"(I["OBJ")I", FN_PTR(MHN_getNamedCon)}, 1.1346 + // static native int getMembers(Class<?> defc, String matchName, String matchSig, 1.1347 + // int matchFlags, Class<?> caller, int skip, MemberName[] results); 1.1348 + {CC"getMembers", CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}, 1.1349 + {CC"objectFieldOffset", CC"("MEM")J", FN_PTR(MHN_objectFieldOffset)}, 1.1350 + {CC"setCallSiteTargetNormal", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetNormal)}, 1.1351 + {CC"setCallSiteTargetVolatile", CC"("CS""MH")V", FN_PTR(MHN_setCallSiteTargetVolatile)}, 1.1352 + {CC"staticFieldOffset", CC"("MEM")J", FN_PTR(MHN_staticFieldOffset)}, 1.1353 + {CC"staticFieldBase", CC"("MEM")"OBJ, FN_PTR(MHN_staticFieldBase)}, 1.1354 + {CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)} 1.1355 +}; 1.1356 + 1.1357 +static JNINativeMethod MH_methods[] = { 1.1358 + // UnsupportedOperationException throwers 1.1359 + {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)}, 1.1360 + {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)} 1.1361 +}; 1.1362 + 1.1363 +/** 1.1364 + * Helper method to register native methods. 1.1365 + */ 1.1366 +static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) { 1.1367 + int status = env->RegisterNatives(clazz, methods, nMethods); 1.1368 + if (status != JNI_OK || env->ExceptionOccurred()) { 1.1369 + warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); 1.1370 + env->ExceptionClear(); 1.1371 + return false; 1.1372 + } 1.1373 + return true; 1.1374 +} 1.1375 + 1.1376 +/** 1.1377 + * This one function is exported, used by NativeLookup. 1.1378 + */ 1.1379 +JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) { 1.1380 + if (!EnableInvokeDynamic) { 1.1381 + warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable."); 1.1382 + return; // bind nothing 1.1383 + } 1.1384 + 1.1385 + assert(!MethodHandles::enabled(), "must not be enabled"); 1.1386 + bool enable_MH = true; 1.1387 + 1.1388 + jclass MH_class = NULL; 1.1389 + if (SystemDictionary::MethodHandle_klass() == NULL) { 1.1390 + enable_MH = false; 1.1391 + } else { 1.1392 + oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror(); 1.1393 + MH_class = (jclass) JNIHandles::make_local(env, mirror); 1.1394 + } 1.1395 + 1.1396 + if (enable_MH) { 1.1397 + ThreadToNativeFromVM ttnfv(thread); 1.1398 + 1.1399 + if (enable_MH) { 1.1400 + enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod)); 1.1401 + } 1.1402 + if (enable_MH) { 1.1403 + enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod)); 1.1404 + } 1.1405 + } 1.1406 + 1.1407 + if (TraceInvokeDynamic) { 1.1408 + tty->print_cr("MethodHandle support loaded (using LambdaForms)"); 1.1409 + } 1.1410 + 1.1411 + if (enable_MH) { 1.1412 + MethodHandles::generate_adapters(); 1.1413 + MethodHandles::set_enabled(true); 1.1414 + } 1.1415 +} 1.1416 +JVM_END