122 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE |
122 ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE |
123 }; |
123 }; |
124 |
124 |
125 Handle MethodHandles::new_MemberName(TRAPS) { |
125 Handle MethodHandles::new_MemberName(TRAPS) { |
126 Handle empty; |
126 Handle empty; |
127 instanceKlassHandle k(THREAD, SystemDictionary::MemberName_klass()); |
127 InstanceKlass* k = SystemDictionary::MemberName_klass(); |
128 if (!k->is_initialized()) k->initialize(CHECK_(empty)); |
128 if (!k->is_initialized()) k->initialize(CHECK_(empty)); |
129 return Handle(THREAD, k->allocate_instance(THREAD)); |
129 return Handle(THREAD, k->allocate_instance(THREAD)); |
130 } |
130 } |
131 |
131 |
132 oop MethodHandles::init_MemberName(Handle mname, Handle target) { |
132 oop MethodHandles::init_MemberName(Handle mname, Handle target) { |
136 oop target_oop = target(); |
136 oop target_oop = target(); |
137 Klass* target_klass = target_oop->klass(); |
137 Klass* target_klass = target_oop->klass(); |
138 if (target_klass == SystemDictionary::reflect_Field_klass()) { |
138 if (target_klass == SystemDictionary::reflect_Field_klass()) { |
139 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() |
139 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() |
140 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() |
140 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() |
141 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
141 Klass* k = java_lang_Class::as_Klass(clazz); |
142 if (!k.is_null() && k->is_instance_klass()) { |
142 if (k != NULL && k->is_instance_klass()) { |
143 fieldDescriptor fd(InstanceKlass::cast(k()), slot); |
143 fieldDescriptor fd(InstanceKlass::cast(k), slot); |
144 oop mname2 = init_field_MemberName(mname, fd); |
144 oop mname2 = init_field_MemberName(mname, fd); |
145 if (mname2 != NULL) { |
145 if (mname2 != NULL) { |
146 // Since we have the reified name and type handy, add them to the result. |
146 // Since we have the reified name and type handy, add them to the result. |
147 if (java_lang_invoke_MemberName::name(mname2) == NULL) |
147 if (java_lang_invoke_MemberName::name(mname2) == NULL) |
148 java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); |
148 java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); |
152 return mname2; |
152 return mname2; |
153 } |
153 } |
154 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { |
154 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { |
155 oop clazz = java_lang_reflect_Method::clazz(target_oop); |
155 oop clazz = java_lang_reflect_Method::clazz(target_oop); |
156 int slot = java_lang_reflect_Method::slot(target_oop); |
156 int slot = java_lang_reflect_Method::slot(target_oop); |
157 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
157 Klass* k = java_lang_Class::as_Klass(clazz); |
158 if (!k.is_null() && k->is_instance_klass()) { |
158 if (k != NULL && k->is_instance_klass()) { |
159 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
159 Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); |
160 if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) |
160 if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) |
161 return NULL; // do not resolve unless there is a concrete signature |
161 return NULL; // do not resolve unless there is a concrete signature |
162 CallInfo info(m, k()); |
162 CallInfo info(m, k); |
163 return init_method_MemberName(mname, info); |
163 return init_method_MemberName(mname, info); |
164 } |
164 } |
165 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { |
165 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { |
166 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); |
166 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); |
167 int slot = java_lang_reflect_Constructor::slot(target_oop); |
167 int slot = java_lang_reflect_Constructor::slot(target_oop); |
168 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
168 Klass* k = java_lang_Class::as_Klass(clazz); |
169 if (!k.is_null() && k->is_instance_klass()) { |
169 if (k != NULL && k->is_instance_klass()) { |
170 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
170 Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); |
171 if (m == NULL) return NULL; |
171 if (m == NULL) return NULL; |
172 CallInfo info(m, k()); |
172 CallInfo info(m, k); |
173 return init_method_MemberName(mname, info); |
173 return init_method_MemberName(mname, info); |
174 } |
174 } |
175 } |
175 } |
176 return NULL; |
176 return NULL; |
177 } |
177 } |
178 |
178 |
179 oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, bool intern) { |
179 oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, bool intern) { |
180 assert(info.resolved_appendix().is_null(), "only normal methods here"); |
180 assert(info.resolved_appendix().is_null(), "only normal methods here"); |
181 methodHandle m = info.resolved_method(); |
181 methodHandle m = info.resolved_method(); |
182 assert(m.not_null(), "null method handle"); |
182 assert(m.not_null(), "null method handle"); |
183 KlassHandle m_klass = m->method_holder(); |
183 Klass* m_klass = m->method_holder(); |
184 assert(m.not_null(), "null holder for method handle"); |
184 assert(m_klass != NULL, "null holder for method handle"); |
185 int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); |
185 int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); |
186 int vmindex = Method::invalid_vtable_index; |
186 int vmindex = Method::invalid_vtable_index; |
187 |
187 |
188 switch (info.call_kind()) { |
188 switch (info.call_kind()) { |
189 case CallInfo::itable_call: |
189 case CallInfo::itable_call: |
206 break; |
206 break; |
207 |
207 |
208 case CallInfo::vtable_call: |
208 case CallInfo::vtable_call: |
209 vmindex = info.vtable_index(); |
209 vmindex = info.vtable_index(); |
210 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); |
210 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); |
211 assert(info.resolved_klass()->is_subtype_of(m_klass()), "virtual call must be type-safe"); |
211 assert(info.resolved_klass()->is_subtype_of(m_klass), "virtual call must be type-safe"); |
212 if (m_klass->is_interface()) { |
212 if (m_klass->is_interface()) { |
213 // This is a vtable call to an interface method (abstract "miranda method" or default method). |
213 // This is a vtable call to an interface method (abstract "miranda method" or default method). |
214 // The vtable index is meaningless without a class (not interface) receiver type, so get one. |
214 // The vtable index is meaningless without a class (not interface) receiver type, so get one. |
215 // (LinkResolver should help us figure this out.) |
215 // (LinkResolver should help us figure this out.) |
216 KlassHandle m_klass_non_interface = info.resolved_klass(); |
216 Klass* m_klass_non_interface = info.resolved_klass(); |
217 if (m_klass_non_interface->is_interface()) { |
217 if (m_klass_non_interface->is_interface()) { |
218 m_klass_non_interface = SystemDictionary::Object_klass(); |
218 m_klass_non_interface = SystemDictionary::Object_klass(); |
219 #ifdef ASSERT |
219 #ifdef ASSERT |
220 { ResourceMark rm; |
220 { ResourceMark rm; |
221 Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex); |
221 Method* m2 = m_klass_non_interface->vtable()->method_at(vmindex); |
227 } |
227 } |
228 if (!m->is_public()) { |
228 if (!m->is_public()) { |
229 assert(m->is_public(), "virtual call must be to public interface method"); |
229 assert(m->is_public(), "virtual call must be to public interface method"); |
230 return NULL; // elicit an error later in product build |
230 return NULL; // elicit an error later in product build |
231 } |
231 } |
232 assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface()), "virtual call must be type-safe"); |
232 assert(info.resolved_klass()->is_subtype_of(m_klass_non_interface), "virtual call must be type-safe"); |
233 m_klass = m_klass_non_interface; |
233 m_klass = m_klass_non_interface; |
234 } |
234 } |
235 if (TraceInvokeDynamic) { |
235 if (TraceInvokeDynamic) { |
236 ttyLocker ttyl; |
236 ttyLocker ttyl; |
237 ResourceMark rm; |
237 ResourceMark rm; |
635 |
635 |
636 |
636 |
637 // An unresolved member name is a mere symbolic reference. |
637 // An unresolved member name is a mere symbolic reference. |
638 // Resolving it plants a vmtarget/vmindex in it, |
638 // Resolving it plants a vmtarget/vmindex in it, |
639 // which refers directly to JVM internals. |
639 // which refers directly to JVM internals. |
640 Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS) { |
640 Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller, TRAPS) { |
641 Handle empty; |
641 Handle empty; |
642 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); |
642 assert(java_lang_invoke_MemberName::is_instance(mname()), ""); |
643 |
643 |
644 if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) { |
644 if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) { |
645 // Already resolved. |
645 // Already resolved. |
662 |
662 |
663 if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) { |
663 if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) { |
664 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty); |
664 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty); |
665 } |
665 } |
666 |
666 |
667 instanceKlassHandle defc; |
667 InstanceKlass* defc = NULL; |
668 { |
668 { |
669 Klass* defc_klass = java_lang_Class::as_Klass(defc_oop()); |
669 Klass* defc_klass = java_lang_Class::as_Klass(defc_oop()); |
670 if (defc_klass == NULL) return empty; // a primitive; no resolution possible |
670 if (defc_klass == NULL) return empty; // a primitive; no resolution possible |
671 if (!defc_klass->is_instance_klass()) { |
671 if (!defc_klass->is_instance_klass()) { |
672 if (!defc_klass->is_array_klass()) return empty; |
672 if (!defc_klass->is_array_klass()) return empty; |
673 defc_klass = SystemDictionary::Object_klass(); |
673 defc_klass = SystemDictionary::Object_klass(); |
674 } |
674 } |
675 defc = instanceKlassHandle(THREAD, defc_klass); |
675 defc = InstanceKlass::cast(defc_klass); |
676 } |
676 } |
677 if (defc.is_null()) { |
677 if (defc == NULL) { |
678 THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty); |
678 THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty); |
679 } |
679 } |
680 defc->link_class(CHECK_(empty)); // possible safepoint |
680 defc->link_class(CHECK_(empty)); // possible safepoint |
681 |
681 |
682 // convert the external string name to an internal symbol |
682 // convert the external string name to an internal symbol |
685 if (name == vmSymbols::class_initializer_name()) |
685 if (name == vmSymbols::class_initializer_name()) |
686 return empty; // illegal name |
686 return empty; // illegal name |
687 |
687 |
688 vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none; |
688 vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none; |
689 if ((flags & ALL_KINDS) == IS_METHOD && |
689 if ((flags & ALL_KINDS) == IS_METHOD && |
690 (defc() == SystemDictionary::MethodHandle_klass()) && |
690 (defc == SystemDictionary::MethodHandle_klass()) && |
691 (ref_kind == JVM_REF_invokeVirtual || |
691 (ref_kind == JVM_REF_invokeVirtual || |
692 ref_kind == JVM_REF_invokeSpecial || |
692 ref_kind == JVM_REF_invokeSpecial || |
693 // static invocation mode is required for _linkToVirtual, etc.: |
693 // static invocation mode is required for _linkToVirtual, etc.: |
694 ref_kind == JVM_REF_invokeStatic)) { |
694 ref_kind == JVM_REF_invokeStatic)) { |
695 vmIntrinsics::ID iid = signature_polymorphic_name_id(name); |
695 vmIntrinsics::ID iid = signature_polymorphic_name_id(name); |
703 |
703 |
704 // convert the external string or reflective type to an internal signature |
704 // convert the external string or reflective type to an internal signature |
705 TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty)); |
705 TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty)); |
706 if (type == NULL) return empty; // no such signature exists in the VM |
706 if (type == NULL) return empty; // no such signature exists in the VM |
707 |
707 |
708 LinkInfo::AccessCheck access_check = caller.not_null() ? |
708 LinkInfo::AccessCheck access_check = caller != NULL ? |
709 LinkInfo::needs_access_check : |
709 LinkInfo::needs_access_check : |
710 LinkInfo::skip_access_check; |
710 LinkInfo::skip_access_check; |
711 |
711 |
712 // Time to do the lookup. |
712 // Time to do the lookup. |
713 switch (flags & ALL_KINDS) { |
713 switch (flags & ALL_KINDS) { |
838 } |
838 } |
839 case IS_FIELD: |
839 case IS_FIELD: |
840 { |
840 { |
841 assert(vmtarget->is_klass(), "field vmtarget is Klass*"); |
841 assert(vmtarget->is_klass(), "field vmtarget is Klass*"); |
842 if (!((Klass*) vmtarget)->is_instance_klass()) break; |
842 if (!((Klass*) vmtarget)->is_instance_klass()) break; |
843 instanceKlassHandle defc(THREAD, (Klass*) vmtarget); |
843 InstanceKlass* defc = InstanceKlass::cast((Klass*) vmtarget); |
844 DEBUG_ONLY(vmtarget = NULL); // safety |
844 DEBUG_ONLY(vmtarget = NULL); // safety |
845 bool is_static = ((flags & JVM_ACC_STATIC) != 0); |
845 bool is_static = ((flags & JVM_ACC_STATIC) != 0); |
846 fieldDescriptor fd; // find_field initializes fd if found |
846 fieldDescriptor fd; // find_field initializes fd if found |
847 if (!defc->find_field_from_offset(vmindex, is_static, &fd)) |
847 if (!defc->find_field_from_offset(vmindex, is_static, &fd)) |
848 break; // cannot expand |
848 break; // cannot expand |
866 } |
866 } |
867 } |
867 } |
868 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
868 THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format"); |
869 } |
869 } |
870 |
870 |
871 int MethodHandles::find_MemberNames(KlassHandle k, |
871 int MethodHandles::find_MemberNames(Klass* k, |
872 Symbol* name, Symbol* sig, |
872 Symbol* name, Symbol* sig, |
873 int mflags, KlassHandle caller, |
873 int mflags, Klass* caller, |
874 int skip, objArrayHandle results) { |
874 int skip, objArrayHandle results) { |
875 // %%% take caller into account! |
875 // %%% take caller into account! |
876 |
876 |
877 Thread* thread = Thread::current(); |
877 Thread* thread = Thread::current(); |
878 |
878 |
879 if (k.is_null() || !k->is_instance_klass()) return -1; |
879 if (k == NULL || !k->is_instance_klass()) return -1; |
880 |
880 |
881 int rfill = 0, rlimit = results->length(), rskip = skip; |
881 int rfill = 0, rlimit = results->length(), rskip = skip; |
882 // overflow measurement: |
882 // overflow measurement: |
883 int overflow = 0, overflow_limit = MAX2(1000, rlimit); |
883 int overflow = 0, overflow_limit = MAX2(1000, rlimit); |
884 |
884 |
902 if ((match_flags & IS_TYPE) != 0) { |
902 if ((match_flags & IS_TYPE) != 0) { |
903 // NYI, and Core Reflection works quite well for this query |
903 // NYI, and Core Reflection works quite well for this query |
904 } |
904 } |
905 |
905 |
906 if ((match_flags & IS_FIELD) != 0) { |
906 if ((match_flags & IS_FIELD) != 0) { |
907 for (FieldStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) { |
907 InstanceKlass* ik = InstanceKlass::cast(k); |
|
908 for (FieldStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) { |
908 if (name != NULL && st.name() != name) |
909 if (name != NULL && st.name() != name) |
909 continue; |
910 continue; |
910 if (sig != NULL && st.signature() != sig) |
911 if (sig != NULL && st.signature() != sig) |
911 continue; |
912 continue; |
912 // passed the filters |
913 // passed the filters |
948 return 0; // no methods of this constructor name |
949 return 0; // no methods of this constructor name |
949 } |
950 } |
950 } else { |
951 } else { |
951 // caller will accept either sort; no need to adjust name |
952 // caller will accept either sort; no need to adjust name |
952 } |
953 } |
953 for (MethodStream st(k(), local_only, !search_intfc); !st.eos(); st.next()) { |
954 InstanceKlass* ik = InstanceKlass::cast(k); |
|
955 for (MethodStream st(ik, local_only, !search_intfc); !st.eos(); st.next()) { |
954 Method* m = st.method(); |
956 Method* m = st.method(); |
955 Symbol* m_name = m->name(); |
957 Symbol* m_name = m->name(); |
956 if (m_name == clinit_name) |
958 if (m_name == clinit_name) |
957 continue; |
959 continue; |
958 if (name != NULL && ((m_name != name) ^ negate_name_test)) |
960 if (name != NULL && ((m_name != name) ^ negate_name_test)) |
1236 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name()); |
1238 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), reference_klass->external_name()); |
1237 } |
1239 } |
1238 } |
1240 } |
1239 } |
1241 } |
1240 |
1242 |
1241 KlassHandle caller(THREAD, |
1243 Klass* caller = caller_jh == NULL ? NULL : |
1242 caller_jh == NULL ? (Klass*) NULL : |
1244 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh)); |
1243 java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh))); |
|
1244 Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL); |
1245 Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL); |
1245 |
1246 |
1246 if (resolved.is_null()) { |
1247 if (resolved.is_null()) { |
1247 int flags = java_lang_invoke_MemberName::flags(mname()); |
1248 int flags = java_lang_invoke_MemberName::flags(mname()); |
1248 int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; |
1249 int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; |
1328 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
1329 // int matchFlags, Class<?> caller, int skip, MemberName[] results); |
1329 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, |
1330 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, |
1330 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
1331 jclass clazz_jh, jstring name_jh, jstring sig_jh, |
1331 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { |
1332 int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { |
1332 if (clazz_jh == NULL || results_jh == NULL) return -1; |
1333 if (clazz_jh == NULL || results_jh == NULL) return -1; |
1333 KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz_jh))); |
1334 Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz_jh)); |
1334 |
1335 |
1335 objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); |
1336 objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); |
1336 if (results.is_null() || !results->is_objArray()) return -1; |
1337 if (results.is_null() || !results->is_objArray()) return -1; |
1337 |
1338 |
1338 TempNewSymbol name = NULL; |
1339 TempNewSymbol name = NULL; |
1344 if (sig_jh != NULL) { |
1345 if (sig_jh != NULL) { |
1345 sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh)); |
1346 sig = java_lang_String::as_symbol_or_null(JNIHandles::resolve_non_null(sig_jh)); |
1346 if (sig == NULL) return 0; // a match is not possible |
1347 if (sig == NULL) return 0; // a match is not possible |
1347 } |
1348 } |
1348 |
1349 |
1349 KlassHandle caller; |
1350 Klass* caller = NULL; |
1350 if (caller_jh != NULL) { |
1351 if (caller_jh != NULL) { |
1351 oop caller_oop = JNIHandles::resolve_non_null(caller_jh); |
1352 oop caller_oop = JNIHandles::resolve_non_null(caller_jh); |
1352 if (!java_lang_Class::is_instance(caller_oop)) return -1; |
1353 if (!java_lang_Class::is_instance(caller_oop)) return -1; |
1353 caller = KlassHandle(THREAD, java_lang_Class::as_Klass(caller_oop)); |
1354 caller = java_lang_Class::as_Klass(caller_oop); |
1354 } |
1355 } |
1355 |
1356 |
1356 if (name != NULL && sig != NULL && results.not_null()) { |
1357 if (name != NULL && sig != NULL && results.not_null()) { |
1357 // try a direct resolve |
1358 // try a direct resolve |
1358 // %%% TO DO |
1359 // %%% TO DO |