void CHA::process_class(KlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, symbolHandle name, symbolHandle signature) { // recursively add non-abstract subclasses of r to receivers list assert(!r->is_interface(), "should call process_interface instead"); for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) { // preorder traversal, so check subclasses first if (s->is_interface()) { // can only happen if r == Object assert(r->superklass() == NULL, "must be klass Object"); } else { process_class(s, receivers, methods, name, signature); } } // now check r itself (after subclasses because of preorder) if (!methods->is_full()) { // don't add abstract classes to receivers list // (but still consider their methods -- they may be non-abstract) if (!receivers->is_full() && !r->is_abstract()) receivers->push(r); methodOop m = NULL; if (r->oop_is_instance()) m = instanceKlass::cast(r())->find_method(name(), signature()); if (m != NULL && !m->is_abstract()) { if (!methods->contains(m)) methods->push(m); } } }