mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
6939196: method handle signatures off the boot class path get linkage errors
Adjust MethodType lookup logic to search off the BCP, but not to cache those results Reviewed-by: twisti
This commit is contained in:
parent
4eb75c2df3
commit
973b1ef143
7 changed files with 150 additions and 47 deletions
|
@ -2343,12 +2343,9 @@ char* SystemDictionary::check_signature_loaders(symbolHandle signature,
|
||||||
|
|
||||||
methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
|
methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
|
||||||
symbolHandle signature,
|
symbolHandle signature,
|
||||||
Handle class_loader,
|
KlassHandle accessing_klass,
|
||||||
Handle protection_domain,
|
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
if (!EnableMethodHandles) return NULL;
|
if (!EnableMethodHandles) return NULL;
|
||||||
assert(class_loader.is_null() && protection_domain.is_null(),
|
|
||||||
"cannot load specialized versions of MethodHandle.invoke");
|
|
||||||
if (invoke_method_table() == NULL) {
|
if (invoke_method_table() == NULL) {
|
||||||
// create this side table lazily
|
// create this side table lazily
|
||||||
_invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
|
_invoke_method_table = new SymbolPropertyTable(_invoke_method_size);
|
||||||
|
@ -2358,30 +2355,36 @@ methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
|
||||||
unsigned int hash = invoke_method_table()->compute_hash(signature, name_id);
|
unsigned int hash = invoke_method_table()->compute_hash(signature, name_id);
|
||||||
int index = invoke_method_table()->hash_to_index(hash);
|
int index = invoke_method_table()->hash_to_index(hash);
|
||||||
SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
|
SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
|
||||||
|
methodHandle non_cached_result;
|
||||||
if (spe == NULL || spe->property_oop() == NULL) {
|
if (spe == NULL || spe->property_oop() == NULL) {
|
||||||
|
spe = NULL;
|
||||||
// Must create lots of stuff here, but outside of the SystemDictionary lock.
|
// Must create lots of stuff here, but outside of the SystemDictionary lock.
|
||||||
if (THREAD->is_Compiler_thread())
|
if (THREAD->is_Compiler_thread())
|
||||||
return NULL; // do not attempt from within compiler
|
return NULL; // do not attempt from within compiler
|
||||||
Handle mt = find_method_handle_type(signature(),
|
bool found_on_bcp = false;
|
||||||
class_loader, protection_domain,
|
Handle mt = find_method_handle_type(signature(), accessing_klass, found_on_bcp, CHECK_NULL);
|
||||||
CHECK_NULL);
|
|
||||||
KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass();
|
KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass();
|
||||||
methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature,
|
methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature,
|
||||||
mt, CHECK_NULL);
|
mt, CHECK_NULL);
|
||||||
// Now grab the lock. We might have to throw away the new method,
|
// Now grab the lock. We might have to throw away the new method,
|
||||||
// if a racing thread has managed to install one at the same time.
|
// if a racing thread has managed to install one at the same time.
|
||||||
{
|
if (found_on_bcp) {
|
||||||
MutexLocker ml(SystemDictionary_lock, Thread::current());
|
MutexLocker ml(SystemDictionary_lock, Thread::current());
|
||||||
spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
|
spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
|
||||||
if (spe == NULL)
|
if (spe == NULL)
|
||||||
spe = invoke_method_table()->add_entry(index, hash, signature, name_id);
|
spe = invoke_method_table()->add_entry(index, hash, signature, name_id);
|
||||||
if (spe->property_oop() == NULL)
|
if (spe->property_oop() == NULL)
|
||||||
spe->set_property_oop(m());
|
spe->set_property_oop(m());
|
||||||
|
} else {
|
||||||
|
non_cached_result = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
methodOop m = (methodOop) spe->property_oop();
|
if (spe != NULL && spe->property_oop() != NULL) {
|
||||||
assert(m->is_method(), "");
|
assert(spe->property_oop()->is_method(), "");
|
||||||
return m;
|
return (methodOop) spe->property_oop();
|
||||||
|
} else {
|
||||||
|
return non_cached_result();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ask Java code to find or construct a java.dyn.MethodType for the given
|
// Ask Java code to find or construct a java.dyn.MethodType for the given
|
||||||
|
@ -2389,30 +2392,50 @@ methodOop SystemDictionary::find_method_handle_invoke(symbolHandle name,
|
||||||
// Because of class loader constraints, all method handle usage must be
|
// Because of class loader constraints, all method handle usage must be
|
||||||
// consistent with this loader.
|
// consistent with this loader.
|
||||||
Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
|
Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
|
||||||
Handle class_loader,
|
KlassHandle accessing_klass,
|
||||||
Handle protection_domain,
|
bool& return_bcp_flag,
|
||||||
TRAPS) {
|
TRAPS) {
|
||||||
|
Handle class_loader, protection_domain;
|
||||||
|
bool is_on_bcp = true; // keep this true as long as we can materialize from the boot classloader
|
||||||
Handle empty;
|
Handle empty;
|
||||||
int npts = ArgumentCount(signature()).size();
|
int npts = ArgumentCount(signature()).size();
|
||||||
objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
|
objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
|
||||||
int arg = 0;
|
int arg = 0;
|
||||||
Handle rt; // the return type from the signature
|
Handle rt; // the return type from the signature
|
||||||
for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) {
|
for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) {
|
||||||
oop mirror;
|
oop mirror = NULL;
|
||||||
if (!ss.is_object()) {
|
if (is_on_bcp) {
|
||||||
mirror = Universe::java_mirror(ss.type());
|
mirror = ss.as_java_mirror(class_loader, protection_domain,
|
||||||
} else {
|
SignatureStream::ReturnNull, CHECK_(empty));
|
||||||
symbolOop name_oop = ss.as_symbol(CHECK_(empty));
|
if (mirror == NULL) {
|
||||||
symbolHandle name(THREAD, name_oop);
|
// fall back from BCP to accessing_klass
|
||||||
klassOop klass = resolve_or_fail(name,
|
if (accessing_klass.not_null()) {
|
||||||
class_loader, protection_domain,
|
class_loader = Handle(THREAD, instanceKlass::cast(accessing_klass())->class_loader());
|
||||||
true, CHECK_(empty));
|
protection_domain = Handle(THREAD, instanceKlass::cast(accessing_klass())->protection_domain());
|
||||||
mirror = Klass::cast(klass)->java_mirror();
|
}
|
||||||
|
is_on_bcp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_on_bcp) {
|
||||||
|
// Resolve, throwing a real error if it doesn't work.
|
||||||
|
mirror = ss.as_java_mirror(class_loader, protection_domain,
|
||||||
|
SignatureStream::NCDFError, CHECK_(empty));
|
||||||
}
|
}
|
||||||
if (ss.at_return_type())
|
if (ss.at_return_type())
|
||||||
rt = Handle(THREAD, mirror);
|
rt = Handle(THREAD, mirror);
|
||||||
else
|
else
|
||||||
pts->obj_at_put(arg++, mirror);
|
pts->obj_at_put(arg++, mirror);
|
||||||
|
// Check accessibility.
|
||||||
|
if (ss.is_object() && accessing_klass.not_null()) {
|
||||||
|
klassOop sel_klass = java_lang_Class::as_klassOop(mirror);
|
||||||
|
// Emulate constantPoolOopDesc::verify_constant_pool_resolve.
|
||||||
|
if (Klass::cast(sel_klass)->oop_is_objArray())
|
||||||
|
sel_klass = objArrayKlass::cast(sel_klass)->bottom_klass();
|
||||||
|
if (Klass::cast(sel_klass)->oop_is_instance()) {
|
||||||
|
KlassHandle sel_kh(THREAD, sel_klass);
|
||||||
|
LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(arg == npts, "");
|
assert(arg == npts, "");
|
||||||
|
|
||||||
|
@ -2425,6 +2448,9 @@ Handle SystemDictionary::find_method_handle_type(symbolHandle signature,
|
||||||
vmSymbols::findMethodHandleType_name(),
|
vmSymbols::findMethodHandleType_name(),
|
||||||
vmSymbols::findMethodHandleType_signature(),
|
vmSymbols::findMethodHandleType_signature(),
|
||||||
&args, CHECK_(empty));
|
&args, CHECK_(empty));
|
||||||
|
|
||||||
|
// report back to the caller with the MethodType and the "on_bcp" flag
|
||||||
|
return_bcp_flag = is_on_bcp;
|
||||||
return Handle(THREAD, (oop) result.get_jobject());
|
return Handle(THREAD, (oop) result.get_jobject());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -466,13 +466,12 @@ public:
|
||||||
// find the java.dyn.MethodHandles::invoke method for a given signature
|
// find the java.dyn.MethodHandles::invoke method for a given signature
|
||||||
static methodOop find_method_handle_invoke(symbolHandle name,
|
static methodOop find_method_handle_invoke(symbolHandle name,
|
||||||
symbolHandle signature,
|
symbolHandle signature,
|
||||||
Handle class_loader,
|
KlassHandle accessing_klass,
|
||||||
Handle protection_domain,
|
|
||||||
TRAPS);
|
TRAPS);
|
||||||
// ask Java to compute a java.dyn.MethodType object for a given signature
|
// ask Java to compute a java.dyn.MethodType object for a given signature
|
||||||
static Handle find_method_handle_type(symbolHandle signature,
|
static Handle find_method_handle_type(symbolHandle signature,
|
||||||
Handle class_loader,
|
KlassHandle accessing_klass,
|
||||||
Handle protection_domain,
|
bool& return_bcp_flag,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
// ask Java to create a dynamic call site, while linking an invokedynamic op
|
// ask Java to create a dynamic call site, while linking an invokedynamic op
|
||||||
static Handle make_dynamic_call_site(Handle bootstrap_method,
|
static Handle make_dynamic_call_site(Handle bootstrap_method,
|
||||||
|
|
|
@ -172,14 +172,16 @@ void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle
|
||||||
result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name(), signature()));
|
result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name(), signature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkResolver::lookup_implicit_method(methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS) {
|
void LinkResolver::lookup_implicit_method(methodHandle& result,
|
||||||
|
KlassHandle klass, symbolHandle name, symbolHandle signature,
|
||||||
|
KlassHandle current_klass,
|
||||||
|
TRAPS) {
|
||||||
if (EnableMethodHandles && MethodHandles::enabled() &&
|
if (EnableMethodHandles && MethodHandles::enabled() &&
|
||||||
klass() == SystemDictionary::MethodHandle_klass() &&
|
klass() == SystemDictionary::MethodHandle_klass() &&
|
||||||
methodOopDesc::is_method_handle_invoke_name(name())) {
|
methodOopDesc::is_method_handle_invoke_name(name())) {
|
||||||
methodOop result_oop = SystemDictionary::find_method_handle_invoke(name,
|
methodOop result_oop = SystemDictionary::find_method_handle_invoke(name,
|
||||||
signature,
|
signature,
|
||||||
Handle(),
|
current_klass,
|
||||||
Handle(),
|
|
||||||
CHECK);
|
CHECK);
|
||||||
if (result_oop != NULL) {
|
if (result_oop != NULL) {
|
||||||
assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature(), "consistent");
|
assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature(), "consistent");
|
||||||
|
@ -290,7 +292,7 @@ void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle res
|
||||||
|
|
||||||
if (resolved_method.is_null()) {
|
if (resolved_method.is_null()) {
|
||||||
// JSR 292: see if this is an implicitly generated method MethodHandle.invoke(*...)
|
// JSR 292: see if this is an implicitly generated method MethodHandle.invoke(*...)
|
||||||
lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, CHECK);
|
lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolved_method.is_null()) {
|
if (resolved_method.is_null()) {
|
||||||
|
@ -1058,7 +1060,8 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle po
|
||||||
// JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...)
|
// JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...)
|
||||||
// The extra MH receiver will be inserted into the stack on every call.
|
// The extra MH receiver will be inserted into the stack on every call.
|
||||||
methodHandle resolved_method;
|
methodHandle resolved_method;
|
||||||
lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, CHECK);
|
KlassHandle current_klass(THREAD, pool->pool_holder());
|
||||||
|
lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK);
|
||||||
if (resolved_method.is_null()) {
|
if (resolved_method.is_null()) {
|
||||||
THROW(vmSymbols::java_lang_InternalError());
|
THROW(vmSymbols::java_lang_InternalError());
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,8 @@ class LinkResolver: AllStatic {
|
||||||
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
||||||
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
||||||
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
||||||
static void lookup_implicit_method (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static void lookup_implicit_method (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature,
|
||||||
|
KlassHandle current_klass, TRAPS);
|
||||||
|
|
||||||
static int vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
static int vtable_index_of_miranda_method(KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
|
||||||
|
|
||||||
|
|
|
@ -475,16 +475,25 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
|
||||||
if (name.is_null()) return; // no such name
|
if (name.is_null()) return; // no such name
|
||||||
name_str = NULL; // safety
|
name_str = NULL; // safety
|
||||||
|
|
||||||
|
Handle polymorphic_method_type;
|
||||||
|
bool polymorphic_signature = false;
|
||||||
|
if ((flags & ALL_KINDS) == IS_METHOD &&
|
||||||
|
(defc() == SystemDictionary::InvokeDynamic_klass() ||
|
||||||
|
(defc() == SystemDictionary::MethodHandle_klass() &&
|
||||||
|
methodOopDesc::is_method_handle_invoke_name(name()))))
|
||||||
|
polymorphic_signature = true;
|
||||||
|
|
||||||
// convert the external string or reflective type to an internal signature
|
// convert the external string or reflective type to an internal signature
|
||||||
bool force_signature = methodOopDesc::is_method_handle_invoke_name(name());
|
|
||||||
symbolHandle type; {
|
symbolHandle type; {
|
||||||
symbolOop type_sym = NULL;
|
symbolOop type_sym = NULL;
|
||||||
if (java_dyn_MethodType::is_instance(type_str)) {
|
if (java_dyn_MethodType::is_instance(type_str)) {
|
||||||
type_sym = java_dyn_MethodType::as_signature(type_str, force_signature, CHECK);
|
type_sym = java_dyn_MethodType::as_signature(type_str, polymorphic_signature, CHECK);
|
||||||
|
if (polymorphic_signature)
|
||||||
|
polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly
|
||||||
} else if (java_lang_Class::is_instance(type_str)) {
|
} else if (java_lang_Class::is_instance(type_str)) {
|
||||||
type_sym = java_lang_Class::as_signature(type_str, force_signature, CHECK);
|
type_sym = java_lang_Class::as_signature(type_str, false, CHECK);
|
||||||
} else if (java_lang_String::is_instance(type_str)) {
|
} else if (java_lang_String::is_instance(type_str)) {
|
||||||
if (force_signature) {
|
if (polymorphic_signature) {
|
||||||
type = java_lang_String::as_symbol(type_str, CHECK);
|
type = java_lang_String::as_symbol(type_str, CHECK);
|
||||||
} else {
|
} else {
|
||||||
type_sym = java_lang_String::as_symbol_or_null(type_str);
|
type_sym = java_lang_String::as_symbol_or_null(type_str);
|
||||||
|
@ -517,7 +526,7 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
|
||||||
}
|
}
|
||||||
if (HAS_PENDING_EXCEPTION) {
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
CLEAR_PENDING_EXCEPTION;
|
CLEAR_PENDING_EXCEPTION;
|
||||||
return;
|
break; // go to second chance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
methodHandle m = result.resolved_method();
|
methodHandle m = result.resolved_method();
|
||||||
|
@ -591,8 +600,42 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
|
||||||
sun_dyn_MemberName::set_modifiers(mname(), mods);
|
sun_dyn_MemberName::set_modifiers(mname(), mods);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second chance.
|
||||||
|
if (polymorphic_method_type.not_null()) {
|
||||||
|
// Look on a non-null class loader.
|
||||||
|
Handle cur_class_loader;
|
||||||
|
const int nptypes = java_dyn_MethodType::ptype_count(polymorphic_method_type());
|
||||||
|
for (int i = 0; i <= nptypes; i++) {
|
||||||
|
oop type_mirror;
|
||||||
|
if (i < nptypes) type_mirror = java_dyn_MethodType::ptype(polymorphic_method_type(), i);
|
||||||
|
else type_mirror = java_dyn_MethodType::rtype(polymorphic_method_type());
|
||||||
|
klassOop example_type = java_lang_Class::as_klassOop(type_mirror);
|
||||||
|
if (example_type == NULL) continue;
|
||||||
|
oop class_loader = Klass::cast(example_type)->class_loader();
|
||||||
|
if (class_loader == NULL || class_loader == cur_class_loader()) continue;
|
||||||
|
cur_class_loader = Handle(THREAD, class_loader);
|
||||||
|
methodOop m = SystemDictionary::find_method_handle_invoke(name,
|
||||||
|
type,
|
||||||
|
KlassHandle(THREAD, example_type),
|
||||||
|
THREAD);
|
||||||
|
if (HAS_PENDING_EXCEPTION) {
|
||||||
|
CLEAR_PENDING_EXCEPTION;
|
||||||
|
m = NULL;
|
||||||
|
// try again with a different class loader...
|
||||||
|
}
|
||||||
|
if (m != NULL) {
|
||||||
|
int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
|
||||||
|
sun_dyn_MemberName::set_vmtarget(mname(), m);
|
||||||
|
sun_dyn_MemberName::set_vmindex(mname(), m->vtable_index());
|
||||||
|
sun_dyn_MemberName::set_modifiers(mname(), mods);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conversely, a member name which is only initialized from JVM internals
|
// Conversely, a member name which is only initialized from JVM internals
|
||||||
|
@ -993,6 +1036,13 @@ void MethodHandles::verify_method_signature(methodHandle m,
|
||||||
pnum += 1;
|
pnum += 1;
|
||||||
mnum += 1;
|
mnum += 1;
|
||||||
}
|
}
|
||||||
|
klassOop pklass = NULL;
|
||||||
|
BasicType ptype = T_OBJECT;
|
||||||
|
if (ptype_oop != NULL)
|
||||||
|
ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass);
|
||||||
|
else
|
||||||
|
// null does not match any non-reference; use Object to report the error
|
||||||
|
pklass = SystemDictionary::Object_klass();
|
||||||
klassOop mklass = NULL;
|
klassOop mklass = NULL;
|
||||||
BasicType mtype = ss.type();
|
BasicType mtype = ss.type();
|
||||||
if (mtype == T_ARRAY) mtype = T_OBJECT; // fold all refs to T_OBJECT
|
if (mtype == T_ARRAY) mtype = T_OBJECT; // fold all refs to T_OBJECT
|
||||||
|
@ -1001,21 +1051,22 @@ void MethodHandles::verify_method_signature(methodHandle m,
|
||||||
// null matches any reference
|
// null matches any reference
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
KlassHandle pklass_handle(THREAD, pklass); pklass = NULL;
|
||||||
// If we fail to resolve types at this point, we will throw an error.
|
// If we fail to resolve types at this point, we will throw an error.
|
||||||
symbolOop name_oop = ss.as_symbol(CHECK);
|
symbolOop name_oop = ss.as_symbol(CHECK);
|
||||||
symbolHandle name(THREAD, name_oop);
|
symbolHandle name(THREAD, name_oop);
|
||||||
instanceKlass* mk = instanceKlass::cast(m->method_holder());
|
instanceKlass* mk = instanceKlass::cast(m->method_holder());
|
||||||
Handle loader(THREAD, mk->class_loader());
|
Handle loader(THREAD, mk->class_loader());
|
||||||
Handle domain(THREAD, mk->protection_domain());
|
Handle domain(THREAD, mk->protection_domain());
|
||||||
mklass = SystemDictionary::resolve_or_fail(name, loader, domain,
|
mklass = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
|
||||||
true, CHECK);
|
pklass = pklass_handle();
|
||||||
|
if (mklass == NULL && pklass != NULL &&
|
||||||
|
Klass::cast(pklass)->name() == name() &&
|
||||||
|
m->is_method_handle_invoke()) {
|
||||||
|
// Assume a match. We can't really decode the signature of MH.invoke*.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ptype_oop == NULL) {
|
|
||||||
// null does not match any non-reference; use Object to report the error
|
|
||||||
ptype_oop = object_java_mirror();
|
|
||||||
}
|
|
||||||
klassOop pklass = NULL;
|
|
||||||
BasicType ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass);
|
|
||||||
if (!ss.at_return_type()) {
|
if (!ss.at_return_type()) {
|
||||||
err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum);
|
err = check_argument_type_change(ptype, pklass, mtype, mklass, mnum);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -327,6 +327,26 @@ symbolOop SignatureStream::as_symbol(TRAPS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain,
|
||||||
|
FailureMode failure_mode, TRAPS) {
|
||||||
|
if (!is_object()) return NULL;
|
||||||
|
symbolOop name = as_symbol(CHECK_NULL);
|
||||||
|
if (failure_mode == ReturnNull) {
|
||||||
|
return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD);
|
||||||
|
} else {
|
||||||
|
bool throw_error = (failure_mode == NCDFError);
|
||||||
|
return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain,
|
||||||
|
FailureMode failure_mode, TRAPS) {
|
||||||
|
if (!is_object())
|
||||||
|
return Universe::java_mirror(type());
|
||||||
|
klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
|
||||||
|
if (klass == NULL) return NULL;
|
||||||
|
return Klass::cast(klass)->java_mirror();
|
||||||
|
}
|
||||||
|
|
||||||
symbolOop SignatureStream::as_symbol_or_null() {
|
symbolOop SignatureStream::as_symbol_or_null() {
|
||||||
// Create a symbol from for string _begin _end
|
// Create a symbol from for string _begin _end
|
||||||
|
|
|
@ -402,6 +402,9 @@ class SignatureStream : public StackObj {
|
||||||
bool is_array() const; // True if this argument is an array
|
bool is_array() const; // True if this argument is an array
|
||||||
BasicType type() const { return _type; }
|
BasicType type() const { return _type; }
|
||||||
symbolOop as_symbol(TRAPS);
|
symbolOop as_symbol(TRAPS);
|
||||||
|
enum FailureMode { ReturnNull, CNFException, NCDFError };
|
||||||
|
klassOop as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
|
||||||
|
oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
|
||||||
|
|
||||||
// return same as_symbol except allocation of new symbols is avoided.
|
// return same as_symbol except allocation of new symbols is avoided.
|
||||||
symbolOop as_symbol_or_null();
|
symbolOop as_symbol_or_null();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue