Fri, 24 Feb 2017 06:48:48 -0800
8162795: [REDO] MemberNameTable doesn't purge stale entries
Summary: Re-application of the change in JDK-8152271.
Reviewed-by: coleenp, sspitsyn
1.1 --- a/src/share/vm/classfile/javaClasses.cpp Thu Feb 16 10:17:01 2017 -0800 1.2 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Feb 24 06:48:48 2017 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -2852,6 +2852,15 @@ 1.11 mname->address_field_put(_vmindex_offset, (address) index); 1.12 } 1.13 1.14 +bool java_lang_invoke_MemberName::equals(oop mn1, oop mn2) { 1.15 + if (mn1 == mn2) { 1.16 + return true; 1.17 + } 1.18 + return (vmtarget(mn1) == vmtarget(mn2) && flags(mn1) == flags(mn2) && 1.19 + vmindex(mn1) == vmindex(mn2) && 1.20 + clazz(mn1) == clazz(mn2)); 1.21 +} 1.22 + 1.23 oop java_lang_invoke_LambdaForm::vmentry(oop lform) { 1.24 assert(is_instance(lform), "wrong type"); 1.25 return lform->obj_field(_vmentry_offset);
2.1 --- a/src/share/vm/classfile/javaClasses.hpp Thu Feb 16 10:17:01 2017 -0800 2.2 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Feb 24 06:48:48 2017 -0800 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -1132,6 +1132,8 @@ 2.11 static int flags_offset_in_bytes() { return _flags_offset; } 2.12 static int vmtarget_offset_in_bytes() { return _vmtarget_offset; } 2.13 static int vmindex_offset_in_bytes() { return _vmindex_offset; } 2.14 + 2.15 + static bool equals(oop mt1, oop mt2); 2.16 }; 2.17 2.18
3.1 --- a/src/share/vm/oops/instanceKlass.cpp Thu Feb 16 10:17:01 2017 -0800 3.2 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Feb 24 06:48:48 2017 -0800 3.3 @@ -3018,7 +3018,7 @@ 3.4 return NULL; 3.5 } 3.6 3.7 -bool InstanceKlass::add_member_name(Handle mem_name) { 3.8 +oop InstanceKlass::add_member_name(Handle mem_name, bool intern) { 3.9 jweak mem_name_wref = JNIHandles::make_weak_global(mem_name); 3.10 MutexLocker ml(MemberNameTable_lock); 3.11 DEBUG_ONLY(No_Safepoint_Verifier nsv); 3.12 @@ -3028,7 +3028,7 @@ 3.13 // is called! 3.14 Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name()); 3.15 if (method->is_obsolete()) { 3.16 - return false; 3.17 + return NULL; 3.18 } else if (method->is_old()) { 3.19 // Replace method with redefined version 3.20 java_lang_invoke_MemberName::set_vmtarget(mem_name(), method_with_idnum(method->method_idnum())); 3.21 @@ -3037,8 +3037,11 @@ 3.22 if (_member_names == NULL) { 3.23 _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count()); 3.24 } 3.25 - _member_names->add_member_name(mem_name_wref); 3.26 - return true; 3.27 + if (intern) { 3.28 + return _member_names->find_or_add_member_name(mem_name_wref); 3.29 + } else { 3.30 + return _member_names->add_member_name(mem_name_wref); 3.31 + } 3.32 } 3.33 3.34 // -----------------------------------------------------------------------------------------------------
4.1 --- a/src/share/vm/oops/instanceKlass.hpp Thu Feb 16 10:17:01 2017 -0800 4.2 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Feb 24 06:48:48 2017 -0800 4.3 @@ -1105,7 +1105,7 @@ 4.4 // JSR-292 support 4.5 MemberNameTable* member_names() { return _member_names; } 4.6 void set_member_names(MemberNameTable* member_names) { _member_names = member_names; } 4.7 - bool add_member_name(Handle member_name); 4.8 + oop add_member_name(Handle member_name, bool intern); 4.9 4.10 public: 4.11 // JVMTI support
5.1 --- a/src/share/vm/prims/jvm.cpp Thu Feb 16 10:17:01 2017 -0800 5.2 +++ b/src/share/vm/prims/jvm.cpp Fri Feb 24 06:48:48 2017 -0800 5.3 @@ -643,7 +643,7 @@ 5.4 // This can safepoint and redefine method, so need both new_obj and method 5.5 // in a handle, for two different reasons. new_obj can move, method can be 5.6 // deleted if nothing is using it on the stack. 5.7 - m->method_holder()->add_member_name(new_obj()); 5.8 + m->method_holder()->add_member_name(new_obj(), false); 5.9 } 5.10 } 5.11
6.1 --- a/src/share/vm/prims/methodHandles.cpp Thu Feb 16 10:17:01 2017 -0800 6.2 +++ b/src/share/vm/prims/methodHandles.cpp Fri Feb 24 06:48:48 2017 -0800 6.3 @@ -173,7 +173,7 @@ 6.4 return NULL; 6.5 } 6.6 6.7 -oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { 6.8 +oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, bool intern) { 6.9 assert(info.resolved_appendix().is_null(), "only normal methods here"); 6.10 methodHandle m = info.resolved_method(); 6.11 KlassHandle m_klass = m->method_holder(); 6.12 @@ -270,13 +270,7 @@ 6.13 // If relevant, the vtable or itable value is stored as vmindex. 6.14 // This is done eagerly, since it is readily available without 6.15 // constructing any new objects. 6.16 - // TO DO: maybe intern mname_oop 6.17 - if (m->method_holder()->add_member_name(mname)) { 6.18 - return mname(); 6.19 - } else { 6.20 - // Redefinition caused this to fail. Return NULL (and an exception?) 6.21 - return NULL; 6.22 - } 6.23 + return m->method_holder()->add_member_name(mname, intern); 6.24 } 6.25 6.26 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { 6.27 @@ -917,7 +911,9 @@ 6.28 if (!java_lang_invoke_MemberName::is_instance(result())) 6.29 return -99; // caller bug! 6.30 CallInfo info(m); 6.31 - oop saved = MethodHandles::init_method_MemberName(result, info); 6.32 + // Since this is going through the methods to create MemberNames, don't search 6.33 + // for matching methods already in the table 6.34 + oop saved = MethodHandles::init_method_MemberName(result, info, /*intern*/false); 6.35 if (saved != result()) 6.36 results->obj_at_put(rfill-1, saved); // show saved instance to user 6.37 } else if (++overflow >= overflow_limit) { 6.38 @@ -949,9 +945,34 @@ 6.39 } 6.40 } 6.41 6.42 -void MemberNameTable::add_member_name(jweak mem_name_wref) { 6.43 +oop MemberNameTable::add_member_name(jweak mem_name_wref) { 6.44 assert_locked_or_safepoint(MemberNameTable_lock); 6.45 this->push(mem_name_wref); 6.46 + return JNIHandles::resolve(mem_name_wref); 6.47 +} 6.48 + 6.49 +oop MemberNameTable::find_or_add_member_name(jweak mem_name_wref) { 6.50 + assert_locked_or_safepoint(MemberNameTable_lock); 6.51 + oop new_mem_name = JNIHandles::resolve(mem_name_wref); 6.52 + 6.53 + // Find matching member name in the list. 6.54 + // This is linear because these are short lists. 6.55 + int len = this->length(); 6.56 + int new_index = len; 6.57 + for (int idx = 0; idx < len; idx++) { 6.58 + oop mname = JNIHandles::resolve(this->at(idx)); 6.59 + if (mname == NULL) { 6.60 + new_index = idx; 6.61 + continue; 6.62 + } 6.63 + if (java_lang_invoke_MemberName::equals(new_mem_name, mname)) { 6.64 + JNIHandles::destroy_weak_global(mem_name_wref); 6.65 + return mname; 6.66 + } 6.67 + } 6.68 + // Not found, push the new one, or reuse empty slot 6.69 + this->at_put_grow(new_index, mem_name_wref); 6.70 + return new_mem_name; 6.71 } 6.72 6.73 #if INCLUDE_JVMTI
7.1 --- a/src/share/vm/prims/methodHandles.hpp Thu Feb 16 10:17:01 2017 -0800 7.2 +++ b/src/share/vm/prims/methodHandles.hpp Fri Feb 24 06:48:48 2017 -0800 7.3 @@ -1,5 +1,5 @@ 7.4 /* 7.5 - * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. 7.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 * 7.9 * This code is free software; you can redistribute it and/or modify it 7.10 @@ -60,7 +60,7 @@ 7.11 static Handle new_MemberName(TRAPS); // must be followed by init_MemberName 7.12 static oop init_MemberName(Handle mname_h, Handle target_h); // compute vmtarget/vmindex from target 7.13 static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false); 7.14 - static oop init_method_MemberName(Handle mname_h, CallInfo& info); 7.15 + static oop init_method_MemberName(Handle mname_h, CallInfo& info, bool intern = true); 7.16 static int method_ref_kind(Method* m, bool do_dispatch_if_possible = true); 7.17 static int find_MemberNames(KlassHandle k, Symbol* name, Symbol* sig, 7.18 int mflags, KlassHandle caller, 7.19 @@ -236,7 +236,8 @@ 7.20 public: 7.21 MemberNameTable(int methods_cnt); 7.22 ~MemberNameTable(); 7.23 - void add_member_name(jweak mem_name_ref); 7.24 + oop add_member_name(jweak mem_name_ref); 7.25 + oop find_or_add_member_name(jweak mem_name_ref); 7.26 7.27 #if INCLUDE_JVMTI 7.28 // RedefineClasses() API support: