--- a/hotspot/src/share/vm/ci/ciEnv.cpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Thu Mar 24 11:21:49 2016 +0100
@@ -773,7 +773,7 @@
Symbol* sig_sym = cpool->signature_ref_at(index);
if (cpool->has_preresolution()
- || (holder == ciEnv::MethodHandle_klass() &&
+ || ((holder == ciEnv::MethodHandle_klass() || holder == ciEnv::VarHandle_klass()) &&
MethodHandles::is_signature_polymorphic_name(holder->get_Klass(), name_sym))) {
// Short-circuit lookups for JSR 292-related call sites.
// That is, do not rely only on name-based lookups, because they may fail
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Mar 24 11:21:49 2016 +0100
@@ -2405,7 +2405,8 @@
return empty;
}
-methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
+methodHandle SystemDictionary::find_method_handle_invoker(KlassHandle klass,
+ Symbol* name,
Symbol* signature,
KlassHandle accessing_klass,
Handle *appendix_result,
@@ -2416,7 +2417,6 @@
Handle method_type =
SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty));
- KlassHandle mh_klass = SystemDictionary::MethodHandle_klass();
int ref_kind = JVM_REF_invokeVirtual;
Handle name_str = StringTable::intern(name, CHECK_(empty));
objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
@@ -2431,7 +2431,7 @@
JavaCallArguments args;
args.push_oop(accessing_klass()->java_mirror());
args.push_int(ref_kind);
- args.push_oop(mh_klass()->java_mirror());
+ args.push_oop(klass()->java_mirror());
args.push_oop(name_str());
args.push_oop(method_type());
args.push_oop(appendix_box());
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Mar 24 11:21:49 2016 +0100
@@ -152,6 +152,7 @@
/* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \
do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre ) \
+ do_klass(VarHandle_klass, java_lang_invoke_VarHandle, Pre ) \
do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre ) \
do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre ) \
do_klass(LambdaForm_klass, java_lang_invoke_LambdaForm, Opt ) \
@@ -515,7 +516,8 @@
// JSR 292
// find a java.lang.invoke.MethodHandle.invoke* method for a given signature
// (asks Java to compute it if necessary, except in a compiler thread)
- static methodHandle find_method_handle_invoker(Symbol* name,
+ static methodHandle find_method_handle_invoker(KlassHandle klass,
+ Symbol* name,
Symbol* signature,
KlassHandle accessing_klass,
Handle *appendix_result,
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Mar 24 11:21:49 2016 +0100
@@ -279,6 +279,7 @@
template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \
template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \
template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \
+ template(java_lang_invoke_VarHandle, "java/lang/invoke/VarHandle") \
template(java_lang_invoke_MethodType, "java/lang/invoke/MethodType") \
template(java_lang_invoke_MethodType_signature, "Ljava/lang/invoke/MethodType;") \
template(java_lang_invoke_MemberName_signature, "Ljava/lang/invoke/MemberName;") \
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Mar 24 11:21:49 2016 +0100
@@ -90,10 +90,16 @@
void CallInfo::set_handle(const methodHandle& resolved_method,
Handle resolved_appendix,
Handle resolved_method_type, TRAPS) {
+ set_handle(SystemDictionary::MethodHandle_klass(), resolved_method, resolved_appendix, resolved_method_type, CHECK);
+}
+
+void CallInfo::set_handle(KlassHandle resolved_klass,
+ const methodHandle& resolved_method,
+ Handle resolved_appendix,
+ Handle resolved_method_type, TRAPS) {
if (resolved_method.is_null()) {
THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
}
- KlassHandle resolved_klass = SystemDictionary::MethodHandle_klass();
assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic ||
resolved_method->is_compiled_lambda_form(),
"linkMethod must return one of these");
@@ -426,7 +432,8 @@
vmIntrinsics::name_at(iid), klass->external_name(),
name->as_C_string(), full_signature->as_C_string());
}
- if (klass() == SystemDictionary::MethodHandle_klass() &&
+ if ((klass() == SystemDictionary::MethodHandle_klass() ||
+ klass() == SystemDictionary::VarHandle_klass()) &&
iid != vmIntrinsics::_none) {
if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) {
// Most of these do not need an up-call to Java to resolve, so can be done anywhere.
@@ -475,6 +482,7 @@
Handle appendix;
Handle method_type;
methodHandle result = SystemDictionary::find_method_handle_invoker(
+ klass,
name,
full_signature,
link_info.current_klass(),
@@ -1554,13 +1562,15 @@
const LinkInfo& link_info,
TRAPS) {
// JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
- assert(link_info.resolved_klass()() == SystemDictionary::MethodHandle_klass(), "");
+ KlassHandle resolved_klass = link_info.resolved_klass();
+ assert(resolved_klass() == SystemDictionary::MethodHandle_klass() ||
+ resolved_klass() == SystemDictionary::VarHandle_klass(), "");
assert(MethodHandles::is_signature_polymorphic_name(link_info.name()), "");
Handle resolved_appendix;
Handle resolved_method_type;
methodHandle resolved_method = lookup_polymorphic_method(link_info,
&resolved_appendix, &resolved_method_type, CHECK);
- result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
+ result.set_handle(resolved_klass, resolved_method, resolved_appendix, resolved_method_type, CHECK);
}
static void wrap_invokedynamic_exception(TRAPS) {
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Mar 24 11:21:49 2016 +0100
@@ -69,6 +69,9 @@
int vtable_index, TRAPS);
void set_handle(const methodHandle& resolved_method,
Handle resolved_appendix, Handle resolved_method_type, TRAPS);
+ void set_handle(KlassHandle resolved_klass,
+ const methodHandle& resolved_method,
+ Handle resolved_appendix, Handle resolved_method_type, TRAPS);
void set_common(KlassHandle resolved_klass, KlassHandle selected_klass,
const methodHandle& resolved_method,
const methodHandle& selected_method,
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Mar 24 11:21:49 2016 +0100
@@ -54,8 +54,10 @@
add_resolved_references_entry(i);
break;
case JVM_CONSTANT_Utf8:
- if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle())
+ if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle() ||
+ _pool->symbol_at(i) == vmSymbols::java_lang_invoke_VarHandle()) {
saw_mh_symbol = true;
+ }
break;
}
}
@@ -200,6 +202,12 @@
// we may need a resolved_refs entry for the appendix
add_invokedynamic_resolved_references_entries(cp_index, cache_index);
status = +1;
+ } else if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_VarHandle() &&
+ MethodHandles::is_signature_polymorphic_name(SystemDictionary::VarHandle_klass(),
+ _pool->name_ref_at(cp_index))) {
+ // we may need a resolved_refs entry for the appendix
+ add_invokedynamic_resolved_references_entries(cp_index, cache_index);
+ status = +1;
} else {
status = -1;
}
--- a/hotspot/src/share/vm/oops/method.cpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/oops/method.cpp Thu Mar 24 11:21:49 2016 +0100
@@ -1351,11 +1351,16 @@
// ditto for method and signature:
vmSymbols::SID name_id = vmSymbols::find_sid(name());
if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
- && name_id == vmSymbols::NO_SID)
+ && klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle)
+ && name_id == vmSymbols::NO_SID) {
return;
+ }
vmSymbols::SID sig_id = vmSymbols::find_sid(signature());
if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
- && sig_id == vmSymbols::NO_SID) return;
+ && klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle)
+ && sig_id == vmSymbols::NO_SID) {
+ return;
+ }
jshort flags = access_flags().as_short();
vmIntrinsics::ID id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
@@ -1383,8 +1388,9 @@
}
break;
- // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*.
+ // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*., VarHandle
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_VarHandle):
if (!is_native()) break;
id = MethodHandles::signature_polymorphic_name_id(method_holder(), name());
if (is_static() != MethodHandles::is_signature_polymorphic_static(id))
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Mar 24 11:21:49 2016 +0100
@@ -318,9 +318,9 @@
// JVM 2.9 Special Methods:
// A method is signature polymorphic if and only if all of the following conditions hold :
-// * It is declared in the java.lang.invoke.MethodHandle class.
+// * It is declared in the java.lang.invoke.MethodHandle/VarHandle classes.
// * It has a single formal parameter of type Object[].
-// * It has a return type of Object.
+// * It has a return type of Object for a polymorphic return type, otherwise a fixed return type.
// * It has the ACC_VARARGS and ACC_NATIVE flags set.
bool MethodHandles::is_method_handle_invoke_name(Klass* klass, Symbol* name) {
if (klass == NULL)
@@ -328,14 +328,36 @@
// The following test will fail spuriously during bootstrap of MethodHandle itself:
// if (klass != SystemDictionary::MethodHandle_klass())
// Test the name instead:
- if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle())
+ if (klass->name() != vmSymbols::java_lang_invoke_MethodHandle() &&
+ klass->name() != vmSymbols::java_lang_invoke_VarHandle()) {
return false;
+ }
+
+ // Look up signature polymorphic method with polymorphic return type
Symbol* poly_sig = vmSymbols::object_array_object_signature();
- Method* m = InstanceKlass::cast(klass)->find_method(name, poly_sig);
- if (m == NULL) return false;
- int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS;
- int flags = m->access_flags().as_int();
- return (flags & required) == required;
+ InstanceKlass* iklass = InstanceKlass::cast(klass);
+ Method* m = iklass->find_method(name, poly_sig);
+ if (m != NULL) {
+ int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS;
+ int flags = m->access_flags().as_int();
+ if ((flags & required) == required) {
+ return true;
+ }
+ }
+
+ // Look up signature polymorphic method with non-polymorphic (non Object) return type
+ int me;
+ int ms = iklass->find_method_by_name(name, &me);
+ if (ms == -1) return false;
+ for (; ms < me; ms++) {
+ Method* m = iklass->methods()->at(ms);
+ int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS;
+ int flags = m->access_flags().as_int();
+ if ((flags & required) == required && ArgumentCount(m->signature()).size() == 1) {
+ return true;
+ }
+ }
+ return false;
}
@@ -395,8 +417,16 @@
// Cover the case of invokeExact and any future variants of invokeFoo.
Klass* mh_klass = SystemDictionary::well_known_klass(
SystemDictionary::WK_KLASS_ENUM_NAME(MethodHandle_klass) );
- if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name))
+ if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name)) {
return vmIntrinsics::_invokeGeneric;
+ }
+
+ // Cover the case of methods on VarHandle.
+ Klass* vh_klass = SystemDictionary::well_known_klass(
+ SystemDictionary::WK_KLASS_ENUM_NAME(VarHandle_klass) );
+ if (vh_klass != NULL && is_method_handle_invoke_name(vh_klass, name)) {
+ return vmIntrinsics::_invokeGeneric;
+ }
// Note: The pseudo-intrinsic _compiledLambdaForm is never linked against.
// Instead it is used to mark lambda forms bound to invokehandle or invokedynamic.
@@ -405,7 +435,8 @@
vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Klass* klass, Symbol* name) {
if (klass != NULL &&
- klass->name() == vmSymbols::java_lang_invoke_MethodHandle()) {
+ (klass->name() == vmSymbols::java_lang_invoke_MethodHandle() ||
+ klass->name() == vmSymbols::java_lang_invoke_VarHandle())) {
vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
if (iid != vmIntrinsics::_none)
return iid;
--- a/hotspot/src/share/vm/prims/methodHandles.hpp Thu Mar 24 09:09:52 2016 +0100
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp Thu Mar 24 11:21:49 2016 +0100
@@ -120,7 +120,8 @@
iid <= vmIntrinsics::_linkToInterface);
}
static bool has_member_arg(Symbol* klass, Symbol* name) {
- if ((klass == vmSymbols::java_lang_invoke_MethodHandle()) &&
+ if ((klass == vmSymbols::java_lang_invoke_MethodHandle() ||
+ klass == vmSymbols::java_lang_invoke_VarHandle()) &&
is_signature_polymorphic_name(name)) {
vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
return has_member_arg(iid);