CHAResult* CHA::analyze_call(KlassHandle calling_klass, KlassHandle static_receiver, KlassHandle actual_receiver, symbolHandle name, symbolHandle signature) { assert(static_receiver->oop_is_instance(), "must be instance klass"); methodHandle m; // Only do exact lookup if receiver klass has been linked. Otherwise, // the vtables has not been setup, and the LinkResolver will fail. if (instanceKlass::cast(static_receiver())->is_linked() && instanceKlass::cast(actual_receiver())->is_linked()) { if (static_receiver->is_interface()) { // no point trying to resolve unless actual receiver is a klass if (!actual_receiver->is_interface()) { m = LinkResolver::resolve_interface_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass); } } else { m = LinkResolver::resolve_virtual_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass); } if (m.is_null()) { // didn't find method (e.g., could be abstract method) return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); } if( Klass::can_be_statically_bound(m()) || m()->is_private() || actual_receiver->subklass() == NULL ) { // always optimize final methods, private methods or methods with no // subclasses. return new CHAResult(actual_receiver, name, signature, NULL, NULL, m); } if (!UseCHA) { // don't optimize this call return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); } } // If the method is abstract then each non-abstract subclass must implement // the method and inlining is not possible. If there is exactly 1 subclass // then there can be only 1 implementation and we are OK. if( !m.is_null() && m()->is_abstract() ) {// Method is abstract? Klass *sr = Klass::cast(static_receiver()); if( sr == sr->up_cast_abstract() ) return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); // Fall into the next code; it will find the one implementation // and that implementation is correct. } _used = true; GrowableArray<methodHandle>* methods = new GrowableArray<methodHandle>(CHA::max_result()); GrowableArray<KlassHandle>* receivers = new GrowableArray<KlassHandle>(CHA::max_result()); // Since 'm' is visible from the actual receiver we can call it if the // runtime receiver class does not override 'm'. if( !m.is_null() && m()->method_holder() != actual_receiver() && !m->is_abstract() ) { receivers->push(actual_receiver); methods->push(m); } if (static_receiver->is_interface()) { instanceKlassHandle sr = static_receiver(); process_interface(sr, receivers, methods, name, signature); } else { process_class(static_receiver, receivers, methods, name, signature); } methodHandle dummy; CHAResult* res = new CHAResult(actual_receiver, name, signature, receivers, methods, dummy); //res->print(); return res; }