125 if (!k->is_initialized()) k->initialize(CHECK_(empty)); |
125 if (!k->is_initialized()) k->initialize(CHECK_(empty)); |
126 return Handle(THREAD, k->allocate_instance(THREAD)); |
126 return Handle(THREAD, k->allocate_instance(THREAD)); |
127 } |
127 } |
128 |
128 |
129 oop MethodHandles::init_MemberName(Handle mname, Handle target) { |
129 oop MethodHandles::init_MemberName(Handle mname, Handle target) { |
|
130 // This method is used from java.lang.invoke.MemberName constructors. |
|
131 // It fills in the new MemberName from a java.lang.reflect.Member. |
130 Thread* thread = Thread::current(); |
132 Thread* thread = Thread::current(); |
131 oop target_oop = target(); |
133 oop target_oop = target(); |
132 Klass* target_klass = target_oop->klass(); |
134 Klass* target_klass = target_oop->klass(); |
133 if (target_klass == SystemDictionary::reflect_Field_klass()) { |
135 if (target_klass == SystemDictionary::reflect_Field_klass()) { |
134 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() |
136 oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder() |
135 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() |
137 int slot = java_lang_reflect_Field::slot(target_oop); // fd.index() |
136 int mods = java_lang_reflect_Field::modifiers(target_oop); |
|
137 oop type = java_lang_reflect_Field::type(target_oop); |
|
138 oop name = java_lang_reflect_Field::name(target_oop); |
|
139 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
138 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
140 intptr_t offset = InstanceKlass::cast(k())->field_offset(slot); |
139 if (!k.is_null() && k->oop_is_instance()) { |
141 return init_field_MemberName(mname, k, accessFlags_from(mods), type, name, offset); |
140 fieldDescriptor fd(InstanceKlass::cast(k()), slot); |
|
141 oop mname2 = init_field_MemberName(mname, fd); |
|
142 if (mname2 != NULL) { |
|
143 // Since we have the reified name and type handy, add them to the result. |
|
144 if (java_lang_invoke_MemberName::name(mname2) == NULL) |
|
145 java_lang_invoke_MemberName::set_name(mname2, java_lang_reflect_Field::name(target_oop)); |
|
146 if (java_lang_invoke_MemberName::type(mname2) == NULL) |
|
147 java_lang_invoke_MemberName::set_type(mname2, java_lang_reflect_Field::type(target_oop)); |
|
148 } |
|
149 return mname2; |
|
150 } |
142 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { |
151 } else if (target_klass == SystemDictionary::reflect_Method_klass()) { |
143 oop clazz = java_lang_reflect_Method::clazz(target_oop); |
152 oop clazz = java_lang_reflect_Method::clazz(target_oop); |
144 int slot = java_lang_reflect_Method::slot(target_oop); |
153 int slot = java_lang_reflect_Method::slot(target_oop); |
145 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
154 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
146 if (!k.is_null() && k->oop_is_instance()) { |
155 if (!k.is_null() && k->oop_is_instance()) { |
147 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
156 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
148 return init_method_MemberName(mname, m, true, k); |
157 if (m == NULL || is_signature_polymorphic(m->intrinsic_id())) |
|
158 return NULL; // do not resolve unless there is a concrete signature |
|
159 CallInfo info(m, k()); |
|
160 return init_method_MemberName(mname, info); |
149 } |
161 } |
150 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { |
162 } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) { |
151 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); |
163 oop clazz = java_lang_reflect_Constructor::clazz(target_oop); |
152 int slot = java_lang_reflect_Constructor::slot(target_oop); |
164 int slot = java_lang_reflect_Constructor::slot(target_oop); |
153 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
165 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
154 if (!k.is_null() && k->oop_is_instance()) { |
166 if (!k.is_null() && k->oop_is_instance()) { |
155 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
167 Method* m = InstanceKlass::cast(k())->method_with_idnum(slot); |
156 return init_method_MemberName(mname, m, false, k); |
168 if (m == NULL) return NULL; |
157 } |
169 CallInfo info(m, k()); |
158 } else if (target_klass == SystemDictionary::MemberName_klass()) { |
170 return init_method_MemberName(mname, info); |
159 // Note: This only works if the MemberName has already been resolved. |
171 } |
160 oop clazz = java_lang_invoke_MemberName::clazz(target_oop); |
172 } |
161 int flags = java_lang_invoke_MemberName::flags(target_oop); |
173 return NULL; |
162 Metadata* vmtarget=java_lang_invoke_MemberName::vmtarget(target_oop); |
174 } |
163 intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop); |
175 |
164 KlassHandle k(thread, java_lang_Class::as_Klass(clazz)); |
176 oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) { |
165 int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK; |
177 assert(info.resolved_appendix().is_null(), "only normal methods here"); |
166 if (vmtarget == NULL) return NULL; // not resolved |
178 KlassHandle receiver_limit = info.resolved_klass(); |
167 if ((flags & IS_FIELD) != 0) { |
179 methodHandle m = info.resolved_method(); |
168 assert(vmtarget->is_klass(), "field vmtarget is Klass*"); |
180 int flags = (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); |
169 int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0); |
181 int vmindex = Method::invalid_vtable_index; |
170 // FIXME: how does k (receiver_limit) contribute? |
182 |
171 KlassHandle k_vmtarget(thread, (Klass*)vmtarget); |
183 switch (info.call_kind()) { |
172 return init_field_MemberName(mname, k_vmtarget, accessFlags_from(basic_mods), NULL, NULL, vmindex); |
184 case CallInfo::itable_call: |
173 } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) { |
185 vmindex = info.itable_index(); |
174 assert(vmtarget->is_method(), "method or constructor vmtarget is Method*"); |
186 // More importantly, the itable index only works with the method holder. |
175 return init_method_MemberName(mname, (Method*)vmtarget, ref_kind_does_dispatch(ref_kind), k); |
187 receiver_limit = m->method_holder(); |
|
188 assert(receiver_limit->verify_itable_index(vmindex), ""); |
|
189 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); |
|
190 break; |
|
191 |
|
192 case CallInfo::vtable_call: |
|
193 vmindex = info.vtable_index(); |
|
194 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); |
|
195 assert(receiver_limit->is_subtype_of(m->method_holder()), "virtual call must be type-safe"); |
|
196 break; |
|
197 |
|
198 case CallInfo::direct_call: |
|
199 vmindex = Method::nonvirtual_vtable_index; |
|
200 if (m->is_static()) { |
|
201 flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); |
|
202 } else if (m->is_initializer()) { |
|
203 flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); |
|
204 assert(receiver_limit == m->method_holder(), "constructor call must be exactly typed"); |
176 } else { |
205 } else { |
177 return NULL; |
206 flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); |
178 } |
207 assert(receiver_limit->is_subtype_of(m->method_holder()), "special call must be type-safe"); |
179 } |
208 } |
180 return NULL; |
209 break; |
181 } |
210 |
182 |
211 default: assert(false, "bad CallInfo"); return NULL; |
183 oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispatch, |
|
184 KlassHandle receiver_limit_h) { |
|
185 Klass* receiver_limit = receiver_limit_h(); |
|
186 AccessFlags mods = m->access_flags(); |
|
187 int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ); |
|
188 int vmindex = Method::nonvirtual_vtable_index; // implies never any dispatch |
|
189 Klass* mklass = m->method_holder(); |
|
190 if (receiver_limit == NULL) |
|
191 receiver_limit = mklass; |
|
192 if (m->is_initializer()) { |
|
193 flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); |
|
194 } else if (mods.is_static()) { |
|
195 flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); |
|
196 } else if (receiver_limit != mklass && |
|
197 !receiver_limit->is_subtype_of(mklass)) { |
|
198 return NULL; // bad receiver limit |
|
199 } else if (do_dispatch && receiver_limit->is_interface() && |
|
200 mklass->is_interface()) { |
|
201 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); |
|
202 receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible |
|
203 vmindex = klassItable::compute_itable_index(m); |
|
204 } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) { |
|
205 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); |
|
206 // it is a miranda method, so m->vtable_index is not what we want |
|
207 ResourceMark rm; |
|
208 klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable(); |
|
209 vmindex = vt->index_of_miranda(m->name(), m->signature()); |
|
210 } else if (!do_dispatch || m->can_be_statically_bound()) { |
|
211 flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); |
|
212 } else { |
|
213 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); |
|
214 vmindex = m->vtable_index(); |
|
215 } |
212 } |
216 |
213 |
217 // @CallerSensitive annotation detected |
214 // @CallerSensitive annotation detected |
218 if (m->caller_sensitive()) { |
215 if (m->caller_sensitive()) { |
219 flags |= CALLER_SENSITIVE; |
216 flags |= CALLER_SENSITIVE; |
220 } |
217 } |
221 |
218 |
222 oop mname_oop = mname(); |
219 oop mname_oop = mname(); |
223 java_lang_invoke_MemberName::set_flags( mname_oop, flags); |
220 java_lang_invoke_MemberName::set_flags( mname_oop, flags); |
224 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m); |
221 java_lang_invoke_MemberName::set_vmtarget(mname_oop, m()); |
225 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index |
222 java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex); // vtable/itable index |
226 java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); |
223 java_lang_invoke_MemberName::set_clazz( mname_oop, receiver_limit->java_mirror()); |
227 // Note: name and type can be lazily computed by resolve_MemberName, |
224 // Note: name and type can be lazily computed by resolve_MemberName, |
228 // if Java code needs them as resolved String and MethodType objects. |
225 // if Java code needs them as resolved String and MethodType objects. |
229 // The clazz must be eagerly stored, because it provides a GC |
226 // The clazz must be eagerly stored, because it provides a GC |
235 m->method_holder()->add_member_name(m->method_idnum(), mname); |
232 m->method_holder()->add_member_name(m->method_idnum(), mname); |
236 |
233 |
237 return mname(); |
234 return mname(); |
238 } |
235 } |
239 |
236 |
240 Handle MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) { |
237 oop MethodHandles::init_field_MemberName(Handle mname, fieldDescriptor& fd, bool is_setter) { |
241 Handle empty; |
238 int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); |
242 if (info.resolved_appendix().not_null()) { |
239 flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
243 // The resolved MemberName must not be accompanied by an appendix argument, |
|
244 // since there is no way to bind this value into the MemberName. |
|
245 // Caller is responsible to prevent this from happening. |
|
246 THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); |
|
247 } |
|
248 methodHandle m = info.resolved_method(); |
|
249 KlassHandle defc = info.resolved_klass(); |
|
250 int vmindex = Method::invalid_vtable_index; |
|
251 if (defc->is_interface() && m->method_holder()->is_interface()) { |
|
252 // static interface methods do not reference vtable or itable |
|
253 if (m->is_static()) { |
|
254 vmindex = Method::nonvirtual_vtable_index; |
|
255 } |
|
256 // interface methods invoked via invokespecial also |
|
257 // do not reference vtable or itable. |
|
258 int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >> |
|
259 REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK); |
|
260 if (ref_kind == JVM_REF_invokeSpecial) { |
|
261 vmindex = Method::nonvirtual_vtable_index; |
|
262 } |
|
263 // If neither m is static nor ref_kind is invokespecial, |
|
264 // set it to itable index. |
|
265 if (vmindex == Method::invalid_vtable_index) { |
|
266 // LinkResolver does not report itable indexes! (fix this?) |
|
267 vmindex = klassItable::compute_itable_index(m()); |
|
268 } |
|
269 } else if (m->can_be_statically_bound()) { |
|
270 // LinkResolver reports vtable index even for final methods! |
|
271 vmindex = Method::nonvirtual_vtable_index; |
|
272 } else { |
|
273 vmindex = info.vtable_index(); |
|
274 } |
|
275 oop res = init_method_MemberName(mname, m(), (vmindex >= 0), defc()); |
|
276 assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), ""); |
|
277 return Handle(THREAD, res); |
|
278 } |
|
279 |
|
280 oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder, |
|
281 AccessFlags mods, oop type, oop name, |
|
282 intptr_t offset, bool is_setter) { |
|
283 int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ); |
|
284 flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
|
285 if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
240 if (is_setter) flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT); |
286 Metadata* vmtarget = field_holder(); |
241 Metadata* vmtarget = fd.field_holder(); |
287 int vmindex = offset; // determines the field uniquely when combined with static bit |
242 int vmindex = fd.offset(); // determines the field uniquely when combined with static bit |
288 oop mname_oop = mname(); |
243 oop mname_oop = mname(); |
289 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
244 java_lang_invoke_MemberName::set_flags(mname_oop, flags); |
290 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
245 java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget); |
291 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
246 java_lang_invoke_MemberName::set_vmindex(mname_oop, vmindex); |
292 java_lang_invoke_MemberName::set_clazz(mname_oop, field_holder->java_mirror()); |
247 java_lang_invoke_MemberName::set_clazz(mname_oop, fd.field_holder()->java_mirror()); |
|
248 oop type = field_signature_type_or_null(fd.signature()); |
|
249 oop name = field_name_or_null(fd.name()); |
293 if (name != NULL) |
250 if (name != NULL) |
294 java_lang_invoke_MemberName::set_name(mname_oop, name); |
251 java_lang_invoke_MemberName::set_name(mname_oop, name); |
295 if (type != NULL) |
252 if (type != NULL) |
296 java_lang_invoke_MemberName::set_type(mname_oop, type); |
253 java_lang_invoke_MemberName::set_type(mname_oop, type); |
297 // Note: name and type can be lazily computed by resolve_MemberName, |
254 // Note: name and type can be lazily computed by resolve_MemberName, |