diff -r 43d4a6542551 -r d84de97ad847 hotspot/src/share/vm/prims/methodHandles.cpp --- a/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jun 22 14:45:37 2011 -0700 +++ b/hotspot/src/share/vm/prims/methodHandles.cpp Thu Jun 23 17:14:06 2011 -0700 @@ -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 @@ 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 @@ // 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 @@ 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 @@ } 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 @@ // 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