< 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,
! REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
! REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
! SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
! SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
! 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,
! FLATTENED = java_lang_invoke_MemberName::MN_FLATTENED,
! REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
! REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
! SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
! SEARCH_INTERFACES = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
! 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;
case CallInfo::direct_call:
vmindex = Method::nonvirtual_vtable_index;
if (m->is_static()) {
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
! } else if (m->is_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);
case CallInfo::direct_call:
vmindex = Method::nonvirtual_vtable_index;
if (m->is_static()) {
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);
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 (fd.is_inlined()) flags |= FLATTENED;;
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) {
if (speculative_resolve) {
}
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 if (name == vmSymbols::inline_factory_name()) {
+ LinkResolver::resolve_static_call(result, link_info, false, THREAD);
} else {
break; // will throw after end of switch
}
if (HAS_PENDING_EXCEPTION) {
if (speculative_resolve) {
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 == NULL) {
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 == NULL) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
}
}
if (sig != NULL) {
if (sig->starts_with(JVM_SIGNATURE_FUNC))
match_flags &= ~(IS_FIELD | IS_TYPE);
else
! match_flags &= ~(IS_CONSTRUCTOR | IS_METHOD);
}
if ((match_flags & IS_TYPE) != 0) {
// NYI, and Core Reflection works quite well for this query
}
}
if (sig != NULL) {
if (sig->starts_with(JVM_SIGNATURE_FUNC))
match_flags &= ~(IS_FIELD | IS_TYPE);
else
! match_flags &= ~(IS_OBJECT_CONSTRUCTOR | IS_METHOD);
}
if ((match_flags & IS_TYPE) != 0) {
// NYI, and Core Reflection works quite well for this query
}
match_flags = 0; break; // got tired of looking at overflow
}
}
}
! if ((match_flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
// watch out for these guys:
Symbol* init_name = vmSymbols::object_initializer_name();
Symbol* clinit_name = vmSymbols::class_initializer_name();
if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit>
! bool negate_name_test = false;
! // fix name so that it captures the intention of IS_CONSTRUCTOR
if (!(match_flags & IS_METHOD)) {
// constructors only
if (name == NULL) {
name = init_name;
} else if (name != init_name) {
return 0; // no constructors of this method name
}
! } else if (!(match_flags & IS_CONSTRUCTOR)) {
// methods only
! if (name == NULL) {
- name = init_name;
- negate_name_test = true; // if we see the name, we *omit* the entry
- } else if (name == init_name) {
- return 0; // no methods of this constructor name
- }
} else {
// caller will accept either sort; no need to adjust name
}
InstanceKlass* ik = InstanceKlass::cast(k);
for (MethodStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) {
Method* m = st.method();
Symbol* m_name = m->name();
if (m_name == clinit_name)
continue;
! if (name != NULL && ((m_name != name) ^ negate_name_test))
continue;
if (sig != NULL && m->signature() != sig)
continue;
// passed the filters
if (rskip > 0) {
--rskip;
} else if (rfill < rlimit) {
Handle result(THREAD, results->obj_at(rfill++));
match_flags = 0; break; // got tired of looking at overflow
}
}
}
! if ((match_flags & (IS_METHOD | IS_OBJECT_CONSTRUCTOR)) != 0) {
// watch out for these guys:
Symbol* init_name = vmSymbols::object_initializer_name();
Symbol* clinit_name = vmSymbols::class_initializer_name();
+ Symbol* factory_name = vmSymbols::inline_factory_name();
if (name == clinit_name) clinit_name = NULL; // hack for exposing <clinit>
! bool ctor_ok = true, sfac_ok = true;
! // fix name so that it captures the intention of IS_OBJECT_CONSTRUCTOR
if (!(match_flags & IS_METHOD)) {
// constructors only
if (name == NULL) {
name = init_name;
} else if (name != init_name) {
return 0; // no constructors of this method name
}
! sfac_ok = false;
+ } else if (!(match_flags & IS_OBJECT_CONSTRUCTOR)) {
// methods only
! ctor_ok = false; // but sfac_ok is true
} else {
// caller will accept either sort; no need to adjust name
}
InstanceKlass* ik = InstanceKlass::cast(k);
for (MethodStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) {
Method* m = st.method();
Symbol* m_name = m->name();
if (m_name == clinit_name)
continue;
! if (name != NULL && m_name != name)
continue;
if (sig != NULL && m->signature() != sig)
continue;
+ if (m_name == init_name) { // might be ctor
+ if (m->is_object_constructor() && !ctor_ok) continue;
+ }
+ if (m_name == factory_name) { // might be sfac
+ if (m->is_static_vnew_factory() && !sfac_ok) continue;
+ }
// passed the filters
if (rskip > 0) {
--rskip;
} else if (rfill < rlimit) {
Handle result(THREAD, results->obj_at(rfill++));
//
#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_SEARCH_SUPERCLASSES) \
template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
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) \
//
#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_FLATTENED) \
template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
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) \
return NULL;
}
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 NULL;
}
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 >