// QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases // out so c++ compiler has a chance for constant prop to fold everything possible away.
// Special case of invokeinterface called for virtual method of // java.lang.Object. See cpCacheOop.cpp for details. // This code isn't produced by javac, but could be produced by // another compliant java compiler. if (cache->is_forced_virtual()) { Method* callee; CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); if (cache->is_vfinal()) { callee = cache->f2_as_vfinal_method(); // Profile 'special case of invokeinterface' final call. BI_PROFILE_UPDATE_FINALCALL(); } else { // Get receiver. intparms= cache->parameter_size(); // Same comments as invokevirtual apply here. ooprcvr= STACK_OBJECT(-parms); VERIFY_OOP(rcvr); Klass* rcvrKlass = rcvr->klass(); callee = (Method*) rcvrKlass->method_at_vtable(cache->f2_as_index()); // Profile 'special case of invokeinterface' virtual call. BI_PROFILE_UPDATE_VIRTUALCALL(rcvrKlass); } istate->set_callee(callee); istate->set_callee_entry_point(callee->from_interpreted_entry()); #ifdef VM_JVMTI if(JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { istate->set_callee_entry_point(callee->interpreter_entry()); } #endif /* VM_JVMTI */ istate->set_bcp_advance(5); UPDATE_PC_AND_RETURN(0); // I'll be back... }
// this could definitely be cleaned up QQQ Method* callee; Klass* iclass = cache->f1_as_klass(); // InstanceKlass* interface = (InstanceKlass*) iclass; // get receiver intparms= cache->parameter_size(); ooprcvr= STACK_OBJECT(-parms); CHECK_NULL(rcvr); InstanceKlass* int2 = (InstanceKlass*) rcvr->klass(); itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable(); int i; for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) { if (ki->interface_klass() == iclass) break; } // If the interface isn't found, this class doesn't implement this // interface. The link resolver checks this but only for the first // time this interface is called. if (i == int2->itable_length()) { VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "", note_no_trap); } intmindex= cache->f2_as_index(); itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); callee = im[mindex].method(); if (callee == NULL) { VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), "", note_no_trap); }