diff -r 0b3b35f008f2 -r 0612a789929b src/share/vm/prims/methodHandles.cpp --- a/src/share/vm/prims/methodHandles.cpp Thu Feb 16 10:17:01 2017 -0800 +++ b/src/share/vm/prims/methodHandles.cpp Fri Feb 24 06:48:48 2017 -0800 @@ -173,7 +173,7 @@ return NULL; } -oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, bool intern) { assert(info.resolved_appendix().is_null(), "only normal methods here"); methodHandle m = info.resolved_method(); KlassHandle m_klass = m->method_holder(); @@ -270,13 +270,7 @@ // If relevant, the vtable or itable value is stored as vmindex. // This is done eagerly, since it is readily available without // constructing any new objects. - // TO DO: maybe intern mname_oop - if (m->method_holder()->add_member_name(mname)) { - return mname(); - } else { - // Redefinition caused this to fail. Return NULL (and an exception?) - return NULL; - } + return m->method_holder()->add_member_name(mname, intern); } oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { @@ -917,7 +911,9 @@ if (!java_lang_invoke_MemberName::is_instance(result())) return -99; // caller bug! CallInfo info(m); - oop saved = MethodHandles::init_method_MemberName(result, info); + // Since this is going through the methods to create MemberNames, don't search + // for matching methods already in the table + oop saved = MethodHandles::init_method_MemberName(result, info, /*intern*/false); if (saved != result()) results->obj_at_put(rfill-1, saved); // show saved instance to user } else if (++overflow >= overflow_limit) { @@ -949,9 +945,34 @@ } } -void MemberNameTable::add_member_name(jweak mem_name_wref) { +oop MemberNameTable::add_member_name(jweak mem_name_wref) { assert_locked_or_safepoint(MemberNameTable_lock); this->push(mem_name_wref); + return JNIHandles::resolve(mem_name_wref); +} + +oop MemberNameTable::find_or_add_member_name(jweak mem_name_wref) { + assert_locked_or_safepoint(MemberNameTable_lock); + oop new_mem_name = JNIHandles::resolve(mem_name_wref); + + // Find matching member name in the list. + // This is linear because these are short lists. + int len = this->length(); + int new_index = len; + for (int idx = 0; idx < len; idx++) { + oop mname = JNIHandles::resolve(this->at(idx)); + if (mname == NULL) { + new_index = idx; + continue; + } + if (java_lang_invoke_MemberName::equals(new_mem_name, mname)) { + JNIHandles::destroy_weak_global(mem_name_wref); + return mname; + } + } + // Not found, push the new one, or reuse empty slot + this->at_put_grow(new_index, mem_name_wref); + return new_mem_name; } #if INCLUDE_JVMTI