< prev index next > src/hotspot/share/prims/methodHandles.cpp
Print this page
// MemberName support
// import java_lang_invoke_MemberName.*
enum {
! IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD,
! IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
! IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD,
! IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE,
! CALLER_SENSITIVE = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
! TRUSTED_FINAL = java_lang_invoke_MemberName::MN_TRUSTED_FINAL,
HIDDEN_MEMBER = java_lang_invoke_MemberName::MN_HIDDEN_MEMBER,
! REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
! REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
! LM_UNCONDITIONAL = java_lang_invoke_MemberName::MN_UNCONDITIONAL_MODE,
! LM_MODULE = java_lang_invoke_MemberName::MN_MODULE_MODE,
! LM_TRUSTED = java_lang_invoke_MemberName::MN_TRUSTED_MODE,
! ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
};
int MethodHandles::ref_kind_to_flags(int ref_kind) {
assert(ref_kind_is_valid(ref_kind), "%d", ref_kind);
int flags = (ref_kind << REFERENCE_KIND_SHIFT);
if (ref_kind_is_field(ref_kind)) {
flags |= IS_FIELD;
} else if (ref_kind_is_method(ref_kind)) {
flags |= IS_METHOD;
} else if (ref_kind == JVM_REF_newInvokeSpecial) {
! flags |= IS_CONSTRUCTOR;
}
return flags;
}
Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
// MemberName support
// import java_lang_invoke_MemberName.*
enum {
! IS_METHOD = java_lang_invoke_MemberName::MN_IS_METHOD,
! IS_OBJECT_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_OBJECT_CONSTRUCTOR,
! IS_FIELD = java_lang_invoke_MemberName::MN_IS_FIELD,
! IS_TYPE = java_lang_invoke_MemberName::MN_IS_TYPE,
! CALLER_SENSITIVE = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
! TRUSTED_FINAL = java_lang_invoke_MemberName::MN_TRUSTED_FINAL,
HIDDEN_MEMBER = java_lang_invoke_MemberName::MN_HIDDEN_MEMBER,
! FLAT_FIELD = java_lang_invoke_MemberName::MN_FLAT_FIELD,
! NULL_RESTRICTED = java_lang_invoke_MemberName::MN_NULL_RESTRICTED_FIELD,
! REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
! REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
! LM_UNCONDITIONAL = java_lang_invoke_MemberName::MN_UNCONDITIONAL_MODE,
! LM_MODULE = java_lang_invoke_MemberName::MN_MODULE_MODE,
+ LM_TRUSTED = java_lang_invoke_MemberName::MN_TRUSTED_MODE,
+ ALL_KINDS = IS_METHOD | IS_OBJECT_CONSTRUCTOR | IS_FIELD | IS_TYPE
};
int MethodHandles::ref_kind_to_flags(int ref_kind) {
assert(ref_kind_is_valid(ref_kind), "%d", ref_kind);
int flags = (ref_kind << REFERENCE_KIND_SHIFT);
if (ref_kind_is_field(ref_kind)) {
flags |= IS_FIELD;
} else if (ref_kind_is_method(ref_kind)) {
flags |= IS_METHOD;
} else if (ref_kind == JVM_REF_newInvokeSpecial) {
! flags |= IS_OBJECT_CONSTRUCTOR;
}
return flags;
}
Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS) {
}
Handle resolved;
int flags = java_lang_invoke_MemberName::flags(mname());
switch (flags & ALL_KINDS) {
case IS_METHOD:
! case IS_CONSTRUCTOR:
resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
break;
case IS_FIELD:
resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
break;
}
Handle resolved;
int flags = java_lang_invoke_MemberName::flags(mname());
switch (flags & ALL_KINDS) {
case IS_METHOD:
! case IS_OBJECT_CONSTRUCTOR:
resolved = SystemDictionary::find_method_handle_type(signature, caller, CHECK_(empty));
break;
case IS_FIELD:
resolved = SystemDictionary::find_field_handle_type(signature, caller, CHECK_(empty));
break;
break;
case CallInfo::direct_call:
vmindex = Method::nonvirtual_vtable_index;
if (m->is_static()) {
! assert(!m->is_static_initializer(), "Cannot be static initializer");
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
! } else if (m->is_object_initializer()) {
! flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
} else {
// "special" reflects that this is a direct call, not that it
// necessarily originates from an invokespecial. We can also do
// direct calls for private and/or final non-static methods.
flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
break;
case CallInfo::direct_call:
vmindex = Method::nonvirtual_vtable_index;
if (m->is_static()) {
! assert(!m->is_class_initializer(), "Cannot be static initializer");
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
! } else if (m->is_object_constructor()) {
! flags |= IS_OBJECT_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
} else {
// "special" reflects that this is a direct call, not that it
// necessarily originates from an invokespecial. We can also do
// direct calls for private and/or final non-static methods.
flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
return mname();
}
oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
InstanceKlass* ik = fd.field_holder();
! int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
if (fd.is_trusted_final()) flags |= TRUSTED_FINAL;
if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
int vmindex = fd.offset(); // determines the field uniquely when combined with static bit
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags (mname_oop, flags);
return mname();
}
oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) {
InstanceKlass* ik = fd.field_holder();
! int flags = (jushort)( fd.access_flags().as_short());
flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
if (fd.is_trusted_final()) flags |= TRUSTED_FINAL;
+ if (fd.is_flat()) flags |= FLAT_FIELD;
+ if (fd.is_null_free_inline_type()) flags |= NULL_RESTRICTED;
if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
int vmindex = fd.offset(); // determines the field uniquely when combined with static bit
oop mname_oop = mname();
java_lang_invoke_MemberName::set_flags (mname_oop, flags);
}
result.set_resolved_method_name(CHECK_(empty));
oop mname2 = init_method_MemberName(mname, result);
return Handle(THREAD, mname2);
}
! case IS_CONSTRUCTOR:
{
CallInfo result;
LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
{
assert(!HAS_PENDING_EXCEPTION, "");
! if (name == vmSymbols::object_initializer_name()) {
LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
} else {
break; // will throw after end of switch
}
if (HAS_PENDING_EXCEPTION) {
}
result.set_resolved_method_name(CHECK_(empty));
oop mname2 = init_method_MemberName(mname, result);
return Handle(THREAD, mname2);
}
! case IS_OBJECT_CONSTRUCTOR:
{
CallInfo result;
LinkInfo link_info(defc, name, type, caller, access_check, loader_constraint_check);
{
assert(!HAS_PENDING_EXCEPTION, "");
! if (name == vmSymbols::object_initializer_name() && type->is_void_method_signature()) {
LinkResolver::resolve_special_call(result, Handle(), link_info, THREAD);
} else {
break; // will throw after end of switch
}
if (HAS_PENDING_EXCEPTION) {
if (have_defc && have_name && have_type) return; // nothing needed
switch (flags & ALL_KINDS) {
case IS_METHOD:
! case IS_CONSTRUCTOR:
{
Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
if (vmtarget == nullptr) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
}
if (have_defc && have_name && have_type) return; // nothing needed
switch (flags & ALL_KINDS) {
case IS_METHOD:
! case IS_OBJECT_CONSTRUCTOR:
{
Method* vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
if (vmtarget == nullptr) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
}
//
#ifndef PRODUCT
#define EACH_NAMED_CON(template, requirement) \
template(java_lang_invoke_MemberName,MN_IS_METHOD) \
! template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
template(java_lang_invoke_MemberName,MN_IS_FIELD) \
template(java_lang_invoke_MemberName,MN_IS_TYPE) \
template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
template(java_lang_invoke_MemberName,MN_TRUSTED_FINAL) \
template(java_lang_invoke_MemberName,MN_HIDDEN_MEMBER) \
template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
template(java_lang_invoke_MemberName,MN_NESTMATE_CLASS) \
template(java_lang_invoke_MemberName,MN_HIDDEN_CLASS) \
template(java_lang_invoke_MemberName,MN_STRONG_LOADER_LINK) \
//
#ifndef PRODUCT
#define EACH_NAMED_CON(template, requirement) \
template(java_lang_invoke_MemberName,MN_IS_METHOD) \
! template(java_lang_invoke_MemberName,MN_IS_OBJECT_CONSTRUCTOR) \
template(java_lang_invoke_MemberName,MN_IS_FIELD) \
template(java_lang_invoke_MemberName,MN_IS_TYPE) \
template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
template(java_lang_invoke_MemberName,MN_TRUSTED_FINAL) \
template(java_lang_invoke_MemberName,MN_HIDDEN_MEMBER) \
+ template(java_lang_invoke_MemberName,MN_FLAT_FIELD) \
template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
template(java_lang_invoke_MemberName,MN_NESTMATE_CLASS) \
template(java_lang_invoke_MemberName,MN_HIDDEN_CLASS) \
template(java_lang_invoke_MemberName,MN_STRONG_LOADER_LINK) \
return nullptr;
}
if ((flags & ALL_KINDS) == IS_FIELD) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
} else if ((flags & ALL_KINDS) == IS_METHOD ||
! (flags & ALL_KINDS) == IS_CONSTRUCTOR) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
} else {
THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
}
}
return nullptr;
}
if ((flags & ALL_KINDS) == IS_FIELD) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "field resolution failed");
} else if ((flags & ALL_KINDS) == IS_METHOD ||
! (flags & ALL_KINDS) == IS_OBJECT_CONSTRUCTOR) {
THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "method resolution failed");
} else {
THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
}
}
< prev index next >