src/share/vm/prims/methodHandles.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/prims/methodHandles.cpp Mon May 6 15:01:45 2013
--- new/src/share/vm/prims/methodHandles.cpp Mon May 6 15:01:45 2013
*** 191,213 ****
--- 191,209 ----
receiver_limit = mklass;
if (m->is_initializer()) {
flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
} else if (mods.is_static()) {
flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
// Get vindex from itable if method holder is an interface.
if (m->method_holder()->is_interface()) {
vmindex = klassItable::compute_itable_index(m);
}
} else if (receiver_limit != mklass &&
!receiver_limit->is_subtype_of(mklass)) {
return NULL; // bad receiver limit
! } else if (do_dispatch && receiver_limit->is_interface() &&
mklass->is_interface()) {
flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
receiver_limit = mklass; // ignore passed-in limit; interfaces are interconvertible
vmindex = klassItable::compute_itable_index(m);
! } else if (do_dispatch && mklass != receiver_limit && mklass->is_interface()) {
flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
// it is a miranda method, so m->vtable_index is not what we want
ResourceMark rm;
klassVtable* vt = InstanceKlass::cast(receiver_limit)->vtable();
vmindex = vt->index_of_miranda(m->name(), m->signature());
*** 248,261 ****
--- 244,272 ----
// Caller is responsible to prevent this from happening.
THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
}
methodHandle m = info.resolved_method();
KlassHandle defc = info.resolved_klass();
! int vmindex = -1;
! int vmindex = Method::invalid_vtable_index;
if (defc->is_interface() && m->method_holder()->is_interface()) {
+ // static interface methods do not reference vtable or itable
+ if (m->is_static()) {
+ vmindex = Method::nonvirtual_vtable_index;
+ }
+ // interface methods invoked via invokespecial also
+ // do not reference vtable or itable.
+ int ref_kind = ((java_lang_invoke_MemberName::flags(mname()) >>
+ REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK);
+ if (ref_kind == JVM_REF_invokeSpecial) {
+ vmindex = Method::nonvirtual_vtable_index;
+ }
+ // If neither m is static nor ref_kind is invokespecial,
+ // set it to itable index.
+ if (vmindex == Method::invalid_vtable_index) {
// LinkResolver does not report itable indexes! (fix this?)
vmindex = klassItable::compute_itable_index(m());
+ }
} else if (m->can_be_statically_bound()) {
// LinkResolver reports vtable index even for final methods!
vmindex = Method::nonvirtual_vtable_index;
} else {
vmindex = info.vtable_index();
*** 663,688 ****
--- 674,696 ----
// Time to do the lookup.
switch (flags & ALL_KINDS) {
case IS_METHOD:
{
CallInfo result;
bool do_dispatch = true; // default, neutral setting
{
assert(!HAS_PENDING_EXCEPTION, "");
if (ref_kind == JVM_REF_invokeStatic) {
//do_dispatch = false; // no need, since statics are never dispatched
LinkResolver::resolve_static_call(result,
defc, name, type, KlassHandle(), false, false, THREAD);
} else if (ref_kind == JVM_REF_invokeInterface) {
LinkResolver::resolve_interface_call(result, Handle(), defc,
defc, name, type, KlassHandle(), false, false, THREAD);
} else if (mh_invoke_id != vmIntrinsics::_none) {
assert(!is_signature_polymorphic_static(mh_invoke_id), "");
LinkResolver::resolve_handle_call(result,
defc, name, type, KlassHandle(), THREAD);
} else if (ref_kind == JVM_REF_invokeSpecial) {
do_dispatch = false; // force non-virtual linkage
LinkResolver::resolve_special_call(result,
defc, name, type, KlassHandle(), false, THREAD);
} else if (ref_kind == JVM_REF_invokeVirtual) {
LinkResolver::resolve_virtual_call(result, Handle(), defc,
defc, name, type, KlassHandle(), false, false, THREAD);
src/share/vm/prims/methodHandles.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File