示例#1
0
void CHA::process_interface(instanceKlassHandle r, GrowableArray<KlassHandle>* receivers, GrowableArray<methodHandle>* methods, 
                            symbolHandle name, symbolHandle signature) {
  // recursively add non-abstract implementors of interface r to receivers list
  assert(r->is_interface(), "should call process_class instead");
  
  // We only store the implementors for an interface, if there is exactly one implementor  
  klassOop k = r->implementor();
  assert(k == NULL || r->nof_implementors() == 1, "inconsistent implementor list");
  if (k != NULL && !methods->is_full()) {   
    instanceKlass* kl = instanceKlass::cast(k);
    assert(kl->oop_is_instance(), "primitive klasses don't implement interfaces");
    assert(!kl->is_interface(), "must be a real klass");
    process_class(kl, receivers, methods, name, signature);
  }

  // now process all subinterfaces
  for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) {
    assert(s->is_interface(), "must be an interface");
    instanceKlassHandle sub(s->as_klassOop());
    process_interface(sub, receivers, methods, name, signature);
    if (methods->is_full()) break;          // give up -- too many overriding methods
  }
}
示例#2
0
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);
    }
  }
}