Mercurial > hg > truffle
comparison src/share/vm/prims/methodHandles.cpp @ 10133:6337ca4dcad8
8008511: JSR 292: MemberName vmtarget refs to methods must be updated at class redefinition
Summary: Lazily create and maintain the MemberNameTable to be able to update MemberName's
Reviewed-by: coleenp, jrose, dholmes
Contributed-by: serguei.spitsyn@oracle.com
author | sspitsyn |
---|---|
date | Sat, 20 Apr 2013 04:07:08 -0700 |
parents | 41ed397cc0cd |
children | ce6d7e43501c |
comparison
equal
deleted
inserted
replaced
10132:5b6512efcdc4 | 10133:6337ca4dcad8 |
---|---|
27 #include "compiler/compileBroker.hpp" | 27 #include "compiler/compileBroker.hpp" |
28 #include "interpreter/interpreter.hpp" | 28 #include "interpreter/interpreter.hpp" |
29 #include "interpreter/oopMapCache.hpp" | 29 #include "interpreter/oopMapCache.hpp" |
30 #include "memory/allocation.inline.hpp" | 30 #include "memory/allocation.inline.hpp" |
31 #include "memory/oopFactory.hpp" | 31 #include "memory/oopFactory.hpp" |
32 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
32 #include "prims/methodHandles.hpp" | 33 #include "prims/methodHandles.hpp" |
33 #include "runtime/compilationPolicy.hpp" | 34 #include "runtime/compilationPolicy.hpp" |
34 #include "runtime/javaCalls.hpp" | 35 #include "runtime/javaCalls.hpp" |
35 #include "runtime/reflection.hpp" | 36 #include "runtime/reflection.hpp" |
36 #include "runtime/signature.hpp" | 37 #include "runtime/signature.hpp" |
122 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); | 123 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); |
123 if (!k->is_initialized()) k->initialize(CHECK_(empty)); | 124 if (!k->is_initialized()) k->initialize(CHECK_(empty)); |
124 return Handle(THREAD, k->allocate_instance(THREAD)); | 125 return Handle(THREAD, k->allocate_instance(THREAD)); |
125 } | 126 } |
126 | 127 |
127 oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) { | 128 oop MethodHandles::init_MemberName(Handle mname, Handle target) { |
129 Thread* thread = Thread::current(); | |
130 oop target_oop = target(); | |
128 Klass* target_klass = target_oop->klass(); | 131 Klass* target_klass = target_oop->klass(); |
129 if (target_klass == SystemDictionary::reflect_Field_klass()) { | 132 if (target_klass == SystemDictionary::reflect_Field_klass()) { |
130 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() | 133 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() |
131 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() | 134 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() |
132 int mods = java_lang_reflect_Field::modifiers(target_oop); | 135 int mods = java_lang_reflect_Field::modifiers(target_oop); |
133 oop type = java_lang_reflect_Field::type(target_oop); | 136 oop type = java_lang_reflect_Field::type(target_oop); |
134 oop name = java_lang_reflect_Field::name(target_oop); | 137 oop name = java_lang_reflect_Field::name(target_oop); |
135 Klass* k = java_lang_Class::as_Klass(clazz); | 138 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
136 intptr_t offset = InstanceKlass::cast(k)->field_offset(slot); | 139 intptr_t offset = InstanceKlass::cast(k())->field_offset(slot); |
137 return init_field_MemberName(mname_oop, k, accessFlags_from(mods), type, name, offset); | 140 return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset); |
138 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { | 141 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { |
139 oop clazz = java_lang_reflect_Method::clazz(target_oop); | 142 oop clazz = java_lang_reflect_Method::clazz(target_oop); |
140 int slot = java_lang_reflect_Method::slot(target_oop); | 143 int slot = java_lang_reflect_Method::slot(target_oop); |
141 Klass* k = java_lang_Class::as_Klass(clazz); | 144 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
142 if (k != NULL && k->oop_is_instance()) { | 145 if (!k.is_null() && k->oop_is_instance()) { |
143 Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); | 146 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
144 return init_method_MemberName(mname_oop, m, true, k); | 147 return init_method_MemberName(mname, m, true, k); |
145 } | 148 } |
146 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { | 149 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { |
147 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); | 150 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); |
148 int slot = java_lang_reflect_Constructor::slot(target_oop); | 151 int slot = java_lang_reflect_Constructor::slot(target_oop); |
149 Klass* k = java_lang_Class::as_Klass(clazz); | 152 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
150 if (k != NULL && k->oop_is_instance()) { | 153 if (!k.is_null() && k->oop_is_instance()) { |
151 Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); | 154 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
152 return init_method_MemberName(mname_oop, m, false, k); | 155 return init_method_MemberName(mname, m, false, k); |
153 } | 156 } |
154 } else if (target_klass == SystemDictionary::MemberName_klass()) { | 157 } else if (target_klass == SystemDictionary::MemberName_klass()) { |
155 // Note: This only works if the MemberName has already been resolved. | 158 // Note: This only works if the MemberName has already been resolved. |
156 oop clazz = java_lang_invoke_MemberName::clazz(target_oop); | 159 oop clazz = java_lang_invoke_MemberName::clazz(target_oop); |
157 int flags = java_lang_invoke_MemberName::flags(target_oop); | 160 int flags = java_lang_invoke_MemberName::flags(target_oop); |
158 Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop); | 161 Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop); |
159 intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop); | 162 intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop); |
160 Klass* k = java_lang_Class::as_Klass(clazz); | 163 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
161 int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; | 164 int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; |
162 if (vmtarget == NULL) return NULL; // not resolved | 165 if (vmtarget == NULL) return NULL; // not resolved |
163 if ((flags & IS_FIELD) != 0) { | 166 if ((flags & IS_FIELD) != 0) { |
164 assert(vmtarget->is_klass(), "field vmtarget is Klass*"); | 167 assert(vmtarget->is_klass(), "field vmtarget is Klass*"); |
165 int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0); | 168 int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0); |
166 // FIXME: how does k (receiver_limit) contribute? | 169 // FIXME: how does k (receiver_limit) contribute? |
167 return init_field_MemberName(mname_oop, (Klass*)vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex); | 170 KlassHandle k_vmtarget(thread, (Klass*)vmtarget); |
171 return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex); | |
168 } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { | 172 } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { |
169 assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); | 173 assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); |
170 return init_method_MemberName(mname_oop, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k); | 174 return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k); |
171 } else { | 175 } else { |
172 return NULL; | 176 return NULL; |
173 } | 177 } |
174 } | 178 } |
175 return NULL; | 179 return NULL; |
176 } | 180 } |
177 | 181 |
178 oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_dispatch, | 182 oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch, |
179 Klass* receiver_limit) { | 183 KlassHandle receiver_limit_h) { |
184 Klass* receiver_limit = receiver_limit_h(); | |
180 AccessFlags mods = m->access_flags(); | 185 AccessFlags mods = m->access_flags(); |
181 int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); | 186 int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); |
182 int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch | 187 int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch |
183 Klass* mklass = m->method_holder(); | 188 Klass* mklass = m->method_holder(); |
184 if (receiver_limit == NULL) | 189 if (receiver_limit == NULL) |
216 // @CallerSensitive annotation detected | 221 // @CallerSensitive annotation detected |
217 if (m->caller_sensitive()) { | 222 if (m->caller_sensitive()) { |
218 flags |= CALLER_SENSITIVE; | 223 flags |= CALLER_SENSITIVE; |
219 } | 224 } |
220 | 225 |
226 oop mname_oop = mname(); | |
221 java_lang_invoke_MemberName::set_flags( mname_oop, flags); | 227 java_lang_invoke_MemberName::set_flags( mname_oop, flags); |
222 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m); | 228 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m); |
223 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index | 229 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index |
224 java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); | 230 java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); |
225 // Note: name and type can be lazily computed by resolve_MemberName, | 231 // Note: name and type can be lazily computed by resolve_MemberName, |
228 // root to help keep alive the Method*. | 234 // root to help keep alive the Method*. |
229 // If relevant, the vtable or itable value is stored as vmindex. | 235 // If relevant, the vtable or itable value is stored as vmindex. |
230 // This is done eagerly, since it is readily available without | 236 // This is done eagerly, since it is readily available without |
231 // constructing any new objects. | 237 // constructing any new objects. |
232 // TO DO: maybe intern mname_oop | 238 // TO DO: maybe intern mname_oop |
233 return mname_oop; | 239 m->method_holder()->add_member_name(mname); |
234 } | 240 return mname(); |
235 | 241 } |
236 Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) { | 242 |
243 Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) { | |
237 Handle empty; | 244 Handle empty; |
238 if (info.resolved_appendix().not_null()) { | 245 if (info.resolved_appendix().not_null()) { |
239 // The resolved MemberName must not be accompanied by an appendix argument, | 246 // The resolved MemberName must not be accompanied by an appendix argument, |
240 // since there is no way to bind this value into the MemberName. | 247 // since there is no way to bind this value into the MemberName. |
241 // Caller is responsible to prevent this from happening. | 248 // Caller is responsible to prevent this from happening. |
251 // LinkResolver reports vtable index even for final methods! | 258 // LinkResolver reports vtable index even for final methods! |
252 vmindex = Method::nonvirtual_vtable_index; | 259 vmindex = Method::nonvirtual_vtable_index; |
253 } else { | 260 } else { |
254 vmindex = info.vtable_index(); | 261 vmindex = info.vtable_index(); |
255 } | 262 } |
256 oop res = init_method_MemberName(mname_oop, m(), (vmindex >= 0), defc()); | 263 oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc()); |
257 assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), ""); | 264 assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), ""); |
258 return Handle(THREAD, res); | 265 return Handle(THREAD, res); |
259 } | 266 } |
260 | 267 |
261 oop MethodHandles::init_field_MemberName(oop mname_oop, Klass* field_holder, | 268 oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, |
262 AccessFlags mods, oop type, oop name, | 269 AccessFlags mods, oop type, oop name, |
263 intptr_t offset, bool is_setter) { | 270 intptr_t offset, bool is_setter) { |
264 int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); | 271 int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); |
265 flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); | 272 flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
266 if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); | 273 if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
267 Metadata* vmtarget = field_holder; | 274 Metadata* vmtarget = field_holder(); |
268 int vmindex = offset; // determines the field uniquely when combined with static bit | 275 int vmindex = offset; // determines the field uniquely when combined with static bit |
276 oop mname_oop = mname(); | |
269 java_lang_invoke_MemberName::set_flags(mname_oop, flags); | 277 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
270 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); | 278 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
271 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); | 279 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
272 java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror()); | 280 java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror()); |
273 if (name != NULL) | 281 if (name != NULL) |
280 // The base clazz and field offset (vmindex) must be eagerly stored, | 288 // The base clazz and field offset (vmindex) must be eagerly stored, |
281 // because they unambiguously identify the field. | 289 // because they unambiguously identify the field. |
282 // Although the fieldDescriptor::_index would also identify the field, | 290 // Although the fieldDescriptor::_index would also identify the field, |
283 // we do not use it, because it is harder to decode. | 291 // we do not use it, because it is harder to decode. |
284 // TO DO: maybe intern mname_oop | 292 // TO DO: maybe intern mname_oop |
285 return mname_oop; | 293 InstanceKlass::cast(field_holder())->add_member_name(mname); |
286 } | 294 return mname(); |
287 | 295 } |
288 Handle MethodHandles::init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS) { | 296 |
297 Handle MethodHandles::init_field_MemberName(Handle mname, FieldAccessInfo& info, TRAPS) { | |
289 return Handle(); | 298 return Handle(); |
290 #if 0 // FIXME | 299 #if 0 // FIXME |
291 KlassHandle field_holder = info.klass(); | 300 KlassHandle field_holder = info.klass(); |
292 intptr_t field_offset = info.field_offset(); | 301 intptr_t field_offset = info.field_offset(); |
293 return init_field_MemberName(mname_oop, field_holder(), | 302 return init_field_MemberName(mname_oop, field_holder(), |
682 } | 691 } |
683 if (HAS_PENDING_EXCEPTION) { | 692 if (HAS_PENDING_EXCEPTION) { |
684 return empty; | 693 return empty; |
685 } | 694 } |
686 } | 695 } |
687 return init_method_MemberName(mname(), result, THREAD); | 696 return init_method_MemberName(mname, result, THREAD); |
688 } | 697 } |
689 case IS_CONSTRUCTOR: | 698 case IS_CONSTRUCTOR: |
690 { | 699 { |
691 CallInfo result; | 700 CallInfo result; |
692 { | 701 { |
700 if (HAS_PENDING_EXCEPTION) { | 709 if (HAS_PENDING_EXCEPTION) { |
701 return empty; | 710 return empty; |
702 } | 711 } |
703 } | 712 } |
704 assert(result.is_statically_bound(), ""); | 713 assert(result.is_statically_bound(), ""); |
705 return init_method_MemberName(mname(), result, THREAD); | 714 return init_method_MemberName(mname, result, THREAD); |
706 } | 715 } |
707 case IS_FIELD: | 716 case IS_FIELD: |
708 { | 717 { |
709 // This is taken from LinkResolver::resolve_field, sans access checks. | 718 // This is taken from LinkResolver::resolve_field, sans access checks. |
710 fieldDescriptor fd; // find_field initializes fd if found | 719 fieldDescriptor fd; // find_field initializes fd if found |
713 if (sel_klass.is_null()) return empty; // should not happen | 722 if (sel_klass.is_null()) return empty; // should not happen |
714 oop type = field_signature_type_or_null(fd.signature()); | 723 oop type = field_signature_type_or_null(fd.signature()); |
715 oop name = field_name_or_null(fd.name()); | 724 oop name = field_name_or_null(fd.name()); |
716 bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind)); | 725 bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind)); |
717 mname = Handle(THREAD, | 726 mname = Handle(THREAD, |
718 init_field_MemberName(mname(), sel_klass(), | 727 init_field_MemberName(mname, sel_klass, |
719 fd.access_flags(), type, name, fd.offset(), is_setter)); | 728 fd.access_flags(), type, name, fd.offset(), is_setter)); |
720 return mname; | 729 return mname; |
721 } | 730 } |
722 default: | 731 default: |
723 THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty); | 732 THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty); |
805 } | 814 } |
806 } | 815 } |
807 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); | 816 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
808 } | 817 } |
809 | 818 |
810 int MethodHandles::find_MemberNames(Klass* k, | 819 int MethodHandles::find_MemberNames(KlassHandle k, |
811 Symbol* name, Symbol* sig, | 820 Symbol* name, Symbol* sig, |
812 int mflags, Klass* caller, | 821 int mflags, KlassHandle caller, |
813 int skip, objArrayOop results) { | 822 int skip, objArrayHandle results) { |
814 DEBUG_ONLY(No_Safepoint_Verifier nsv); | |
815 // this code contains no safepoints! | |
816 | |
817 // %%% take caller into account! | 823 // %%% take caller into account! |
818 | 824 |
819 if (k == NULL || !k->oop_is_instance()) return -1; | 825 Thread* thread = Thread::current(); |
826 | |
827 if (k.is_null() || !k->oop_is_instance()) return -1; | |
820 | 828 |
821 int rfill = 0, rlimit = results->length(), rskip = skip; | 829 int rfill = 0, rlimit = results->length(), rskip = skip; |
822 // overflow measurement: | 830 // overflow measurement: |
823 int overflow = 0, overflow_limit = MAX2(1000, rlimit); | 831 int overflow = 0, overflow_limit = MAX2(1000, rlimit); |
824 | 832 |
842 if ((match_flags & IS_TYPE) != 0) { | 850 if ((match_flags & IS_TYPE) != 0) { |
843 // NYI, and Core Reflection works quite well for this query | 851 // NYI, and Core Reflection works quite well for this query |
844 } | 852 } |
845 | 853 |
846 if ((match_flags & IS_FIELD) != 0) { | 854 if ((match_flags & IS_FIELD) != 0) { |
847 for (FieldStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { | 855 for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) { |
848 if (name != NULL && st.name() != name) | 856 if (name != NULL && st.name() != name) |
849 continue; | 857 continue; |
850 if (sig != NULL && st.signature() != sig) | 858 if (sig != NULL && st.signature() != sig) |
851 continue; | 859 continue; |
852 // passed the filters | 860 // passed the filters |
853 if (rskip > 0) { | 861 if (rskip > 0) { |
854 --rskip; | 862 --rskip; |
855 } else if (rfill < rlimit) { | 863 } else if (rfill < rlimit) { |
856 oop result = results->obj_at(rfill++); | 864 Handle result(thread, results->obj_at(rfill++)); |
857 if (!java_lang_invoke_MemberName::is_instance(result)) | 865 if (!java_lang_invoke_MemberName::is_instance(result())) |
858 return -99; // caller bug! | 866 return -99; // caller bug! |
859 oop type = field_signature_type_or_null(st.signature()); | 867 oop type = field_signature_type_or_null(st.signature()); |
860 oop name = field_name_or_null(st.name()); | 868 oop name = field_name_or_null(st.name()); |
861 oop saved = MethodHandles::init_field_MemberName(result, st.klass()(), | 869 oop saved = MethodHandles::init_field_MemberName(result, st.klass(), |
862 st.access_flags(), type, name, | 870 st.access_flags(), type, name, |
863 st.offset()); | 871 st.offset()); |
864 if (saved != result) | 872 if (saved != result()) |
865 results->obj_at_put(rfill-1, saved); // show saved instance to user | 873 results->obj_at_put(rfill-1, saved); // show saved instance to user |
866 } else if (++overflow >= overflow_limit) { | 874 } else if (++overflow >= overflow_limit) { |
867 match_flags = 0; break; // got tired of looking at overflow | 875 match_flags = 0; break; // got tired of looking at overflow |
868 } | 876 } |
869 } | 877 } |
892 return 0; // no methods of this constructor name | 900 return 0; // no methods of this constructor name |
893 } | 901 } |
894 } else { | 902 } else { |
895 // caller will accept either sort; no need to adjust name | 903 // caller will accept either sort; no need to adjust name |
896 } | 904 } |
897 for (MethodStream st(k, local_only, !search_intfc); !st.eos(); st.next()) { | 905 for (MethodStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) { |
898 Method* m = st.method(); | 906 Method* m = st.method(); |
899 Symbol* m_name = m->name(); | 907 Symbol* m_name = m->name(); |
900 if (m_name == clinit_name) | 908 if (m_name == clinit_name) |
901 continue; | 909 continue; |
902 if (name != NULL && ((m_name != name) ^ negate_name_test)) | 910 if (name != NULL && ((m_name != name) ^ negate_name_test)) |
905 continue; | 913 continue; |
906 // passed the filters | 914 // passed the filters |
907 if (rskip > 0) { | 915 if (rskip > 0) { |
908 --rskip; | 916 --rskip; |
909 } else if (rfill < rlimit) { | 917 } else if (rfill < rlimit) { |
910 oop result = results->obj_at(rfill++); | 918 Handle result(thread, results->obj_at(rfill++)); |
911 if (!java_lang_invoke_MemberName::is_instance(result)) | 919 if (!java_lang_invoke_MemberName::is_instance(result())) |
912 return -99; // caller bug! | 920 return -99; // caller bug! |
913 oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL); | 921 oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL); |
914 if (saved != result) | 922 if (saved != result()) |
915 results->obj_at_put(rfill-1, saved); // show saved instance to user | 923 results->obj_at_put(rfill-1, saved); // show saved instance to user |
916 } else if (++overflow >= overflow_limit) { | 924 } else if (++overflow >= overflow_limit) { |
917 match_flags = 0; break; // got tired of looking at overflow | 925 match_flags = 0; break; // got tired of looking at overflow |
918 } | 926 } |
919 } | 927 } |
920 } | 928 } |
921 | 929 |
922 // return number of elements we at leasted wanted to initialize | 930 // return number of elements we at leasted wanted to initialize |
923 return rfill + overflow; | 931 return rfill + overflow; |
924 } | 932 } |
933 | |
934 //------------------------------------------------------------------------------ | |
935 // MemberNameTable | |
936 // | |
937 | |
938 MemberNameTable::MemberNameTable() : GrowableArray<jweak>(10, true) { | |
939 assert_locked_or_safepoint(MemberNameTable_lock); | |
940 } | |
941 | |
942 MemberNameTable::~MemberNameTable() { | |
943 assert_locked_or_safepoint(MemberNameTable_lock); | |
944 int len = this->length(); | |
945 | |
946 for (int idx = 0; idx < len; idx++) { | |
947 jweak ref = this->at(idx); | |
948 JNIHandles::destroy_weak_global(ref); | |
949 } | |
950 } | |
951 | |
952 // Return entry index if found, return -1 otherwise. | |
953 int MemberNameTable::find_member_name(oop mem_name) { | |
954 assert_locked_or_safepoint(MemberNameTable_lock); | |
955 int len = this->length(); | |
956 | |
957 for (int idx = 0; idx < len; idx++) { | |
958 jweak ref = this->at(idx); | |
959 oop entry = JNIHandles::resolve(ref); | |
960 if (entry == mem_name) { | |
961 return idx; | |
962 } | |
963 } | |
964 return -1; | |
965 } | |
966 | |
967 void MemberNameTable::add_member_name(jweak mem_name_wref) { | |
968 assert_locked_or_safepoint(MemberNameTable_lock); | |
969 oop mem_name = JNIHandles::resolve(mem_name_wref); | |
970 | |
971 // Each member name may appear just once: add only if not found | |
972 if (find_member_name(mem_name) == -1) { | |
973 this->append(mem_name_wref); | |
974 } | |
975 } | |
976 | |
977 #if INCLUDE_JVMTI | |
978 oop MemberNameTable::find_member_name_by_method(Method* old_method) { | |
979 assert_locked_or_safepoint(MemberNameTable_lock); | |
980 oop found = NULL; | |
981 int len = this->length(); | |
982 | |
983 for (int idx = 0; idx < len; idx++) { | |
984 oop mem_name = JNIHandles::resolve(this->at(idx)); | |
985 if (mem_name == NULL) { | |
986 continue; | |
987 } | |
988 Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mem_name); | |
989 if (method == old_method) { | |
990 found = mem_name; | |
991 break; | |
992 } | |
993 } | |
994 return found; | |
995 } | |
996 | |
997 // It is called at safepoint only | |
998 void MemberNameTable::adjust_method_entries(Method** old_methods, Method** new_methods, | |
999 int methods_length, bool *trace_name_printed) { | |
1000 assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint"); | |
1001 // search the MemberNameTable for uses of either obsolete or EMCP methods | |
1002 for (int j = 0; j < methods_length; j++) { | |
1003 Method* old_method = old_methods[j]; | |
1004 Method* new_method = new_methods[j]; | |
1005 oop mem_name = find_member_name_by_method(old_method); | |
1006 if (mem_name != NULL) { | |
1007 java_lang_invoke_MemberName::adjust_vmtarget(mem_name, new_method); | |
1008 | |
1009 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { | |
1010 if (!(*trace_name_printed)) { | |
1011 // RC_TRACE_MESG macro has an embedded ResourceMark | |
1012 RC_TRACE_MESG(("adjust: name=%s", | |
1013 old_method->method_holder()->external_name())); | |
1014 *trace_name_printed = true; | |
1015 } | |
1016 // RC_TRACE macro has an embedded ResourceMark | |
1017 RC_TRACE(0x00400000, ("MemberName method update: %s(%s)", | |
1018 new_method->name()->as_C_string(), | |
1019 new_method->signature()->as_C_string())); | |
1020 } | |
1021 } | |
1022 } | |
1023 } | |
1024 #endif // INCLUDE_JVMTI | |
1025 | |
925 // | 1026 // |
926 // Here are the native methods in java.lang.invoke.MethodHandleNatives | 1027 // Here are the native methods in java.lang.invoke.MethodHandleNatives |
927 // They are the private interface between this JVM and the HotSpot-specific | 1028 // They are the private interface between this JVM and the HotSpot-specific |
928 // Java code that implements JSR 292 method handles. | 1029 // Java code that implements JSR 292 method handles. |
929 // | 1030 // |
1013 // void init(MemberName self, AccessibleObject ref) | 1114 // void init(MemberName self, AccessibleObject ref) |
1014 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { | 1115 JVM_ENTRY(void, MHN_init_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jobject target_jh)) { |
1015 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } | 1116 if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); } |
1016 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } | 1117 if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); } |
1017 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); | 1118 Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh)); |
1018 oop target_oop = JNIHandles::resolve_non_null(target_jh); | 1119 Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); |
1019 MethodHandles::init_MemberName(mname(), target_oop); | 1120 MethodHandles::init_MemberName(mname, target); |
1020 } | 1121 } |
1021 JVM_END | 1122 JVM_END |
1022 | 1123 |
1023 // void expand(MemberName self) | 1124 // void expand(MemberName self) |
1024 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { | 1125 JVM_ENTRY(void, MHN_expand_Mem(JNIEnv *env, jobject igcls, jobject mname_jh)) { |
1121 x = NULL; | 1222 x = NULL; |
1122 } else if (vmtarget->is_klass()) { | 1223 } else if (vmtarget->is_klass()) { |
1123 x = ((Klass*) vmtarget)->java_mirror(); | 1224 x = ((Klass*) vmtarget)->java_mirror(); |
1124 } else if (vmtarget->is_method()) { | 1225 } else if (vmtarget->is_method()) { |
1125 Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL); | 1226 Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL); |
1126 x = MethodHandles::init_method_MemberName(mname2(), (Method*)vmtarget, false, NULL); | 1227 x = MethodHandles::init_method_MemberName(mname2, (Method*)vmtarget, false, NULL); |
1127 } | 1228 } |
1128 result->obj_at_put(1, x); | 1229 result->obj_at_put(1, x); |
1129 return JNIHandles::make_local(env, result()); | 1230 return JNIHandles::make_local(env, result()); |
1130 } | 1231 } |
1131 JVM_END | 1232 JVM_END |
1164 if (name != NULL && sig != NULL && results.not_null()) { | 1265 if (name != NULL && sig != NULL && results.not_null()) { |
1165 // try a direct resolve | 1266 // try a direct resolve |
1166 // %%% TO DO | 1267 // %%% TO DO |
1167 } | 1268 } |
1168 | 1269 |
1169 int res = MethodHandles::find_MemberNames(k(), name, sig, mflags, | 1270 int res = MethodHandles::find_MemberNames(k, name, sig, mflags, |
1170 caller(), skip, results()); | 1271 caller, skip, results); |
1171 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks | 1272 // TO DO: expand at least some of the MemberNames, to avoid massive callbacks |
1172 return res; | 1273 return res; |
1173 } | 1274 } |
1174 JVM_END | 1275 JVM_END |
1175 | 1276 |