comparison src/share/vm/prims/methodHandles.cpp @ 10259:39ead0411f07

8013875: Incorrect vtable index being set during methodHandle creation for static Summary: Set vtable index as appropriate for static interface methods and for interface methods invoked via invokespecial. To be improved in a later enhancement to CallInfo. Reviewed-by: jrose, twisti
author bharadwaj
date Wed, 08 May 2013 14:18:03 -0700
parents 746b070f5022
children e484fe2abebd
comparison
equal deleted inserted replaced
10258:0dc028fd5101 10259:39ead0411f07
191 receiver_limit = mklass; 191 receiver_limit = mklass;
192 if (m->is_initializer()) { 192 if (m->is_initializer()) {
193 flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT); 193 flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
194 } else if (mods.is_static()) { 194 } else if (mods.is_static()) {
195 flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT); 195 flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
196 // Get vindex from itable if method holder is an interface.
197 if (m->method_holder()->is_interface()) {
198 vmindex = klassItable::compute_itable_index(m);
199 }
200 } else if (receiver_limit != mklass && 196 } else if (receiver_limit != mklass &&
201 !receiver_limit->is_subtype_of(mklass)) { 197 !receiver_limit->is_subtype_of(mklass)) {
202 return NULL; // bad receiver limit 198 return NULL; // bad receiver limit
203 } else if (receiver_limit->is_interface() && 199 } else if (do_dispatch && receiver_limit->is_interface() &&
204 mklass->is_interface()) { 200 mklass->is_interface()) {
205 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT); 201 flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
206 receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible 202 receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
207 vmindex = klassItable::compute_itable_index(m); 203 vmindex = klassItable::compute_itable_index(m);
208 } else if (mklass != receiver_limit && mklass->is_interface()) { 204 } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
209 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT); 205 flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
210 // it is a miranda method, so m->vtable_index is not what we want 206 // it is a miranda method, so m->vtable_index is not what we want
211 ResourceMark rm; 207 ResourceMark rm;
212 klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable(); 208 klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable();
213 vmindex = vt->index_of_miranda(m->name(), m->signature()); 209 vmindex = vt->index_of_miranda(m->name(), m->signature());
248 // Caller is responsible to prevent this from happening. 244 // Caller is responsible to prevent this from happening.
249 THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty); 245 THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
250 } 246 }
251 methodHandle m = info.resolved_method(); 247 methodHandle m = info.resolved_method();
252 KlassHandle defc = info.resolved_klass(); 248 KlassHandle defc = info.resolved_klass();
253 int vmindex = -1; 249 int vmindex = Method::invalid_vtable_index;
254 if (defc->is_interface() && m->method_holder()->is_interface()) { 250 if (defc->is_interface() && m->method_holder()->is_interface()) {
255 // LinkResolver does not report itable indexes! (fix this?) 251 // static interface methods do not reference vtable or itable
256 vmindex = klassItable::compute_itable_index(m()); 252 if (m->is_static()) {
253 vmindex = Method::nonvirtual_vtable_index;
254 }
255 // interface methods invoked via invokespecial also
256 // do not reference vtable or itable.
257 int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >>
258 REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK);
259 if (ref_kind == JVM_REF_invokeSpecial) {
260 vmindex = Method::nonvirtual_vtable_index;
261 }
262 // If neither m is static nor ref_kind is invokespecial,
263 // set it to itable index.
264 if (vmindex == Method::invalid_vtable_index) {
265 // LinkResolver does not report itable indexes! (fix this?)
266 vmindex = klassItable::compute_itable_index(m());
267 }
257 } else if (m->can_be_statically_bound()) { 268 } else if (m->can_be_statically_bound()) {
258 // LinkResolver reports vtable index even for final methods! 269 // LinkResolver reports vtable index even for final methods!
259 vmindex = Method::nonvirtual_vtable_index; 270 vmindex = Method::nonvirtual_vtable_index;
260 } else { 271 } else {
261 vmindex = info.vtable_index(); 272 vmindex = info.vtable_index();
663 // Time to do the lookup. 674 // Time to do the lookup.
664 switch (flags & ALL_KINDS) { 675 switch (flags & ALL_KINDS) {
665 case IS_METHOD: 676 case IS_METHOD:
666 { 677 {
667 CallInfo result; 678 CallInfo result;
668 bool do_dispatch = true; // default, neutral setting
669 { 679 {
670 assert(!HAS_PENDING_EXCEPTION, ""); 680 assert(!HAS_PENDING_EXCEPTION, "");
671 if (ref_kind == JVM_REF_invokeStatic) { 681 if (ref_kind == JVM_REF_invokeStatic) {
672 //do_dispatch = false; // no need, since statics are never dispatched
673 LinkResolver::resolve_static_call(result, 682 LinkResolver::resolve_static_call(result,
674 defc, name, type, KlassHandle(), false, false, THREAD); 683 defc, name, type, KlassHandle(), false, false, THREAD);
675 } else if (ref_kind == JVM_REF_invokeInterface) { 684 } else if (ref_kind == JVM_REF_invokeInterface) {
676 LinkResolver::resolve_interface_call(result, Handle(), defc, 685 LinkResolver::resolve_interface_call(result, Handle(), defc,
677 defc, name, type, KlassHandle(), false, false, THREAD); 686 defc, name, type, KlassHandle(), false, false, THREAD);
678 } else if (mh_invoke_id != vmIntrinsics::_none) { 687 } else if (mh_invoke_id != vmIntrinsics::_none) {
679 assert(!is_signature_polymorphic_static(mh_invoke_id), ""); 688 assert(!is_signature_polymorphic_static(mh_invoke_id), "");
680 LinkResolver::resolve_handle_call(result, 689 LinkResolver::resolve_handle_call(result,
681 defc, name, type, KlassHandle(), THREAD); 690 defc, name, type, KlassHandle(), THREAD);
682 } else if (ref_kind == JVM_REF_invokeSpecial) { 691 } else if (ref_kind == JVM_REF_invokeSpecial) {
683 do_dispatch = false; // force non-virtual linkage
684 LinkResolver::resolve_special_call(result, 692 LinkResolver::resolve_special_call(result,
685 defc, name, type, KlassHandle(), false, THREAD); 693 defc, name, type, KlassHandle(), false, THREAD);
686 } else if (ref_kind == JVM_REF_invokeVirtual) { 694 } else if (ref_kind == JVM_REF_invokeVirtual) {
687 LinkResolver::resolve_virtual_call(result, Handle(), defc, 695 LinkResolver::resolve_virtual_call(result, Handle(), defc,
688 defc, name, type, KlassHandle(), false, false, THREAD); 696 defc, name, type, KlassHandle(), false, false, THREAD);