7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path

Reviewed-by: never
This commit is contained in:
John R Rose 2011-06-23 17:14:06 -07:00
parent 15161b8cd1
commit 8df44305c7
26 changed files with 512 additions and 58 deletions

View file

@ -24,12 +24,14 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "compiler/compileBroker.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/oopMapCache.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/oopFactory.hpp"
#include "prims/methodHandles.hpp"
#include "prims/methodHandleWalk.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
@ -767,7 +769,9 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
m = NULL;
// try again with a different class loader...
}
if (m != NULL) {
if (m != NULL &&
m->is_method_handle_invoke() &&
java_lang_invoke_MethodType::equals(polymorphic_method_type(), m->method_handle_type())) {
int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
java_lang_invoke_MemberName::set_vmtarget(mname(), m);
java_lang_invoke_MemberName::set_vmindex(mname(), m->vtable_index());
@ -986,6 +990,48 @@ instanceKlassHandle MethodHandles::resolve_instance_klass(oop java_mirror_oop, T
// This is for debugging and reflection.
oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH");
if (format == ETF_FORCE_DIRECT_HANDLE ||
format == ETF_COMPILE_DIRECT_HANDLE) {
// Internal function for stress testing.
Handle mt = java_lang_invoke_MethodHandle::type(mh());
int invocation_count = 10000;
TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK_NULL);
bool omit_receiver_argument = true;
MethodHandleCompiler mhc(mh, vmSymbols::invoke_name(), signature, invocation_count, omit_receiver_argument, CHECK_NULL);
methodHandle m = mhc.compile(CHECK_NULL);
if (StressMethodHandleWalk && Verbose || PrintMiscellaneous) {
tty->print_cr("MethodHandleNatives.getTarget(%s)",
format == ETF_FORCE_DIRECT_HANDLE ? "FORCE_DIRECT" : "COMPILE_DIRECT");
if (Verbose) {
m->print_codes();
}
}
if (StressMethodHandleWalk) {
InterpreterOopMap mask;
OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask);
}
if ((format == ETF_COMPILE_DIRECT_HANDLE ||
CompilationPolicy::must_be_compiled(m))
&& !instanceKlass::cast(m->method_holder())->is_not_initialized()
&& CompilationPolicy::can_be_compiled(m)) {
// Force compilation
CompileBroker::compile_method(m, InvocationEntryBci,
CompLevel_initial_compile,
methodHandle(), 0, "MethodHandleNatives.getTarget",
CHECK_NULL);
}
// Now wrap m in a DirectMethodHandle.
instanceKlassHandle dmh_klass(THREAD, SystemDictionary::DirectMethodHandle_klass());
Handle dmh = dmh_klass->allocate_instance_handle(CHECK_NULL);
JavaValue ignore_result(T_VOID);
Symbol* init_name = vmSymbols::object_initializer_name();
Symbol* init_sig = vmSymbols::notifyGenericMethodType_signature();
JavaCalls::call_special(&ignore_result, dmh,
SystemDictionaryHandles::MethodHandle_klass(), init_name, init_sig,
java_lang_invoke_MethodHandle::type(mh()), CHECK_NULL);
MethodHandles::init_DirectMethodHandle(dmh, m, false, CHECK_NULL);
return dmh();
}
if (format == ETF_HANDLE_OR_METHOD_NAME) {
oop target = java_lang_invoke_MethodHandle::vmtarget(mh());
if (target == NULL) {
@ -1221,6 +1267,12 @@ void MethodHandles::verify_method_signature(methodHandle m,
klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
if (aklass_oop != NULL)
aklass = KlassHandle(THREAD, aklass_oop);
if (aklass.is_null() &&
pklass.not_null() &&
loader.is_null() &&
pklass->name() == name)
// accept name equivalence here, since that's the best we can do
aklass = pklass;
}
} else {
// for method handle invokers we don't look at the name in the signature
@ -2654,6 +2706,17 @@ static void stress_method_handle_walk_impl(Handle mh, TRAPS) {
}
InterpreterOopMap mask;
OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask);
// compile to object code if -Xcomp or WizardMode
if ((WizardMode ||
CompilationPolicy::must_be_compiled(m))
&& !instanceKlass::cast(m->method_holder())->is_not_initialized()
&& CompilationPolicy::can_be_compiled(m)) {
// Force compilation
CompileBroker::compile_method(m, InvocationEntryBci,
CompLevel_initial_compile,
methodHandle(), 0, "StressMethodHandleWalk",
CHECK);
}
}
}
@ -2773,7 +2836,12 @@ JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
// Build a BMH on top of a DMH or another BMH:
MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
}
stress_method_handle_walk(mh, CHECK);
if (StressMethodHandleWalk) {
if (mh->klass() == SystemDictionary::BoundMethodHandle_klass())
stress_method_handle_walk(mh, CHECK);
// else don't, since the subclass has not yet initialized its own fields
}
}
JVM_END