< prev index next >
src/share/vm/prims/methodHandles.cpp
Print this page
*** 122,132 ****
ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
};
Handle MethodHandles::new_MemberName(TRAPS) {
Handle empty;
! instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass());
if (!k->is_initialized()) k->initialize(CHECK_(empty));
return Handle(THREAD, k->allocate_instance(THREAD));
}
oop MethodHandles::init_MemberName(Handle mname, Handle target) {
--- 122,132 ----
ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
};
Handle MethodHandles::new_MemberName(TRAPS) {
Handle empty;
! InstanceKlass* k = SystemDictionary::MemberName_klass();
if (!k->is_initialized()) k->initialize(CHECK_(empty));
return Handle(THREAD, k->allocate_instance(THREAD));
}
oop MethodHandles::init_MemberName(Handle mname, Handle target) {
*** 136,148 ****
oop target_oop = target();
Klass* target_klass = target_oop->klass();
if (target_klass == SystemDictionary::reflect_Field_klass()) {
oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
! KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
! if (!k.is_null() && k->is_instance_klass()) {
! fieldDescriptor fd(InstanceKlass::cast(k()), slot);
oop mname2 = init_field_MemberName(mname, fd);
if (mname2 != NULL) {
// Since we have the reified name and type handy, add them to the result.
if (java_lang_invoke_MemberName::name(mname2) == NULL)
java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop));
--- 136,148 ----
oop target_oop = target();
Klass* target_klass = target_oop->klass();
if (target_klass == SystemDictionary::reflect_Field_klass()) {
oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
! Klass* k = java_lang_Class::as_Klass(clazz);
! if (k != NULL && k->is_instance_klass()) {
! fieldDescriptor fd(InstanceKlass::cast(k), slot);
oop mname2 = init_field_MemberName(mname, fd);
if (mname2 != NULL) {
// Since we have the reified name and type handy, add them to the result.
if (java_lang_invoke_MemberName::name(mname2) == NULL)
java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop));
*** 152,189 ****
return mname2;
}
} else if (target_klass == SystemDictionary::reflect_Method_klass()) {
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
! KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
! if (!k.is_null() && k->is_instance_klass()) {
! Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
if (m == NULL || is_signature_polymorphic(m->intrinsic_id()))
return NULL; // do not resolve unless there is a concrete signature
! CallInfo info(m, k());
return init_method_MemberName(mname, info);
}
} else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
int slot = java_lang_reflect_Constructor::slot(target_oop);
! KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
! if (!k.is_null() && k->is_instance_klass()) {
! Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
if (m == NULL) return NULL;
! CallInfo info(m, k());
return init_method_MemberName(mname, info);
}
}
return NULL;
}
oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
assert(info.resolved_appendix().is_null(), "only normal methods here");
methodHandle m = info.resolved_method();
assert(m.not_null(), "null method handle");
! KlassHandle m_klass = m->method_holder();
! assert(m.not_null(), "null holder for method handle");
int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
int vmindex = Method::invalid_vtable_index;
switch (info.call_kind()) {
case CallInfo::itable_call:
--- 152,189 ----
return mname2;
}
} else if (target_klass == SystemDictionary::reflect_Method_klass()) {
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
! Klass* k = java_lang_Class::as_Klass(clazz);
! if (k != NULL && k->is_instance_klass()) {
! Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
if (m == NULL || is_signature_polymorphic(m->intrinsic_id()))
return NULL; // do not resolve unless there is a concrete signature
! CallInfo info(m, k);
return init_method_MemberName(mname, info);
}
} else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
int slot = java_lang_reflect_Constructor::slot(target_oop);
! Klass* k = java_lang_Class::as_Klass(clazz);
! if (k != NULL && k->is_instance_klass()) {
! Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
if (m == NULL) return NULL;
! CallInfo info(m, k);
return init_method_MemberName(mname, info);
}
}
return NULL;
}
oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
assert(info.resolved_appendix().is_null(), "only normal methods here");
methodHandle m = info.resolved_method();
assert(m.not_null(), "null method handle");
! Klass* m_klass = m->method_holder();
! assert(m_klass != NULL, "null holder for method handle");
int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
int vmindex = Method::invalid_vtable_index;
switch (info.call_kind()) {
case CallInfo::itable_call:
*** 206,221 ****
break;
case CallInfo::vtable_call:
vmindex = info.vtable_index();
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
! assert(info.resolved_klass()->is_subtype_of(m_klass()), "virtual call must be type-safe");
if (m_klass->is_interface()) {
// This is a vtable call to an interface method (abstract "miranda method" or default method).
// The vtable index is meaningless without a class (not interface) receiver type, so get one.
// (LinkResolver should help us figure this out.)
! KlassHandle m_klass_non_interface = info.resolved_klass();
if (m_klass_non_interface->is_interface()) {
m_klass_non_interface = SystemDictionary::Object_klass();
#ifdef ASSERT
{ ResourceMark rm;
Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex);
--- 206,221 ----
break;
case CallInfo::vtable_call:
vmindex = info.vtable_index();
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
! assert(info.resolved_klass()->is_subtype_of(m_klass), "virtual call must be type-safe");
if (m_klass->is_interface()) {
// This is a vtable call to an interface method (abstract "miranda method" or default method).
// The vtable index is meaningless without a class (not interface) receiver type, so get one.
// (LinkResolver should help us figure this out.)
! Klass* m_klass_non_interface = info.resolved_klass();
if (m_klass_non_interface->is_interface()) {
m_klass_non_interface = SystemDictionary::Object_klass();
#ifdef ASSERT
{ ResourceMark rm;
Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex);
*** 227,237 ****
}
if (!m->is_public()) {
assert(m->is_public(), "virtual call must be to public interface method");
return NULL; // elicit an error later in product build
}
! assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface()), "virtual call must be type-safe");
m_klass = m_klass_non_interface;
}
if (TraceInvokeDynamic) {
ttyLocker ttyl;
ResourceMark rm;
--- 227,237 ----
}
if (!m->is_public()) {
assert(m->is_public(), "virtual call must be to public interface method");
return NULL; // elicit an error later in product build
}
! assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface), "virtual call must be type-safe");
m_klass = m_klass_non_interface;
}
if (TraceInvokeDynamic) {
ttyLocker ttyl;
ResourceMark rm;
*** 641,651 ****
// An unresolved member name is a mere symbolic reference.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
! Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS) {
Handle empty;
assert(java_lang_invoke_MemberName::is_instance(mname()), "");
if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
// Already resolved.
--- 641,651 ----
// An unresolved member name is a mere symbolic reference.
// Resolving it plants a vmtarget/vmindex in it,
// which refers directly to JVM internals.
! Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller, TRAPS) {
Handle empty;
assert(java_lang_invoke_MemberName::is_instance(mname()), "");
if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
// Already resolved.
*** 668,688 ****
if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) {
THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty);
}
! instanceKlassHandle defc;
{
Klass* defc_klass = java_lang_Class::as_Klass(defc_oop());
if (defc_klass == NULL) return empty; // a primitive; no resolution possible
if (!defc_klass->is_instance_klass()) {
if (!defc_klass->is_array_klass()) return empty;
defc_klass = SystemDictionary::Object_klass();
}
! defc = instanceKlassHandle(THREAD, defc_klass);
}
! if (defc.is_null()) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty);
}
defc->link_class(CHECK_(empty)); // possible safepoint
// convert the external string name to an internal symbol
--- 668,688 ----
if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) {
THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty);
}
! InstanceKlass* defc = NULL;
{
Klass* defc_klass = java_lang_Class::as_Klass(defc_oop());
if (defc_klass == NULL) return empty; // a primitive; no resolution possible
if (!defc_klass->is_instance_klass()) {
if (!defc_klass->is_array_klass()) return empty;
defc_klass = SystemDictionary::Object_klass();
}
! defc = InstanceKlass::cast(defc_klass);
}
! if (defc == NULL) {
THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty);
}
defc->link_class(CHECK_(empty)); // possible safepoint
// convert the external string name to an internal symbol
*** 691,701 ****
if (name == vmSymbols::class_initializer_name())
return empty; // illegal name
vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none;
if ((flags & ALL_KINDS) == IS_METHOD &&
! (defc() == SystemDictionary::MethodHandle_klass()) &&
(ref_kind == JVM_REF_invokeVirtual ||
ref_kind == JVM_REF_invokeSpecial ||
// static invocation mode is required for _linkToVirtual, etc.:
ref_kind == JVM_REF_invokeStatic)) {
vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
--- 691,701 ----
if (name == vmSymbols::class_initializer_name())
return empty; // illegal name
vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none;
if ((flags & ALL_KINDS) == IS_METHOD &&
! (defc == SystemDictionary::MethodHandle_klass()) &&
(ref_kind == JVM_REF_invokeVirtual ||
ref_kind == JVM_REF_invokeSpecial ||
// static invocation mode is required for _linkToVirtual, etc.:
ref_kind == JVM_REF_invokeStatic)) {
vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
*** 709,719 ****
// convert the external string or reflective type to an internal signature
TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty));
if (type == NULL) return empty; // no such signature exists in the VM
! LinkInfo::AccessCheck access_check = caller.not_null() ?
LinkInfo::needs_access_check :
LinkInfo::skip_access_check;
// Time to do the lookup.
switch (flags & ALL_KINDS) {
--- 709,719 ----
// convert the external string or reflective type to an internal signature
TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty));
if (type == NULL) return empty; // no such signature exists in the VM
! LinkInfo::AccessCheck access_check = caller != NULL ?
LinkInfo::needs_access_check :
LinkInfo::skip_access_check;
// Time to do the lookup.
switch (flags & ALL_KINDS) {
*** 844,854 ****
}
case IS_FIELD:
{
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
if (!((Klass*) vmtarget)->is_instance_klass()) break;
! instanceKlassHandle defc(THREAD, (Klass*) vmtarget);
DEBUG_ONLY(vmtarget = NULL); // safety
bool is_static = ((flags & JVM_ACC_STATIC) != 0);
fieldDescriptor fd; // find_field initializes fd if found
if (!defc->find_field_from_offset(vmindex, is_static, &fd))
break; // cannot expand
--- 844,854 ----
}
case IS_FIELD:
{
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
if (!((Klass*) vmtarget)->is_instance_klass()) break;
! InstanceKlass* defc = InstanceKlass::cast((Klass*) vmtarget);
DEBUG_ONLY(vmtarget = NULL); // safety
bool is_static = ((flags & JVM_ACC_STATIC) != 0);
fieldDescriptor fd; // find_field initializes fd if found
if (!defc->find_field_from_offset(vmindex, is_static, &fd))
break; // cannot expand
*** 872,890 ****
}
}
THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
}
! int MethodHandles::find_MemberNames(KlassHandle k,
Symbol* name, Symbol* sig,
! int mflags, KlassHandle caller,
int skip, objArrayHandle results) {
// %%% take caller into account!
Thread* thread = Thread::current();
! if (k.is_null() || !k->is_instance_klass()) return -1;
int rfill = 0, rlimit = results->length(), rskip = skip;
// overflow measurement:
int overflow = 0, overflow_limit = MAX2(1000, rlimit);
--- 872,890 ----
}
}
THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
}
! int MethodHandles::find_MemberNames(Klass* k,
Symbol* name, Symbol* sig,
! int mflags, Klass* caller,
int skip, objArrayHandle results) {
// %%% take caller into account!
Thread* thread = Thread::current();
! if (k == NULL || !k->is_instance_klass()) return -1;
int rfill = 0, rlimit = results->length(), rskip = skip;
// overflow measurement:
int overflow = 0, overflow_limit = MAX2(1000, rlimit);
*** 908,918 ****
if ((match_flags & IS_TYPE) != 0) {
// NYI, and Core Reflection works quite well for this query
}
if ((match_flags & IS_FIELD) != 0) {
! for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) {
if (name != NULL && st.name() != name)
continue;
if (sig != NULL && st.signature() != sig)
continue;
// passed the filters
--- 908,919 ----
if ((match_flags & IS_TYPE) != 0) {
// NYI, and Core Reflection works quite well for this query
}
if ((match_flags & IS_FIELD) != 0) {
! InstanceKlass* ik = InstanceKlass::cast(k);
! for (FieldStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) {
if (name != NULL && st.name() != name)
continue;
if (sig != NULL && st.signature() != sig)
continue;
// passed the filters
*** 954,964 ****
return 0; // no methods of this constructor name
}
} else {
// caller will accept either sort; no need to adjust name
}
! for (MethodStream st(k(), 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))
--- 955,966 ----
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))
*** 1215,1227 ****
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
}
}
}
! KlassHandle caller(THREAD,
! caller_jh == NULL ? (Klass*) NULL :
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh)));
Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
if (resolved.is_null()) {
int flags = java_lang_invoke_MemberName::flags(mname());
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
--- 1217,1228 ----
THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name());
}
}
}
! Klass* caller = caller_jh == NULL ? NULL :
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
if (resolved.is_null()) {
int flags = java_lang_invoke_MemberName::flags(mname());
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
*** 1307,1317 ****
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
jclass clazz_jh, jstring name_jh, jstring sig_jh,
int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
if (clazz_jh == NULL || results_jh == NULL) return -1;
! KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz_jh)));
objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh));
if (results.is_null() || !results->is_objArray()) return -1;
TempNewSymbol name = NULL;
--- 1308,1318 ----
// int matchFlags, Class<?> caller, int skip, MemberName[] results);
JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
jclass clazz_jh, jstring name_jh, jstring sig_jh,
int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) {
if (clazz_jh == NULL || results_jh == NULL) return -1;
! Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz_jh));
objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh));
if (results.is_null() || !results->is_objArray()) return -1;
TempNewSymbol name = NULL;
*** 1323,1337 ****
if (sig_jh != NULL) {
sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh));
if (sig == NULL) return 0; // a match is not possible
}
! KlassHandle caller;
if (caller_jh != NULL) {
oop caller_oop = JNIHandles::resolve_non_null(caller_jh);
if (!java_lang_Class::is_instance(caller_oop)) return -1;
! caller = KlassHandle(THREAD, java_lang_Class::as_Klass(caller_oop));
}
if (name != NULL && sig != NULL && results.not_null()) {
// try a direct resolve
// %%% TO DO
--- 1324,1338 ----
if (sig_jh != NULL) {
sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh));
if (sig == NULL) return 0; // a match is not possible
}
! Klass* caller = NULL;
if (caller_jh != NULL) {
oop caller_oop = JNIHandles::resolve_non_null(caller_jh);
if (!java_lang_Class::is_instance(caller_oop)) return -1;
! caller = java_lang_Class::as_Klass(caller_oop);
}
if (name != NULL && sig != NULL && results.not_null()) {
// try a direct resolve
// %%% TO DO
< prev index next >