int klassKlass::oop_oop_iterate(oop obj, OopClosure* blk) { // Get size before changing pointers int size = oop_size(obj); Klass* k = Klass::cast(klassOop(obj)); blk->do_oop(k->adr_super()); for (juint i = 0; i < Klass::primary_super_limit(); i++) blk->do_oop(k->adr_primary_supers()+i); blk->do_oop(k->adr_secondary_super_cache()); blk->do_oop(k->adr_secondary_supers()); blk->do_oop(k->adr_java_mirror()); blk->do_oop(k->adr_name()); // The following are in the perm gen and are treated // specially in a later phase of a perm gen collection; ... assert(oop(k)->is_perm(), "should be in perm"); assert(oop(k->subklass())->is_perm_or_null(), "should be in perm"); assert(oop(k->next_sibling())->is_perm_or_null(), "should be in perm"); // ... don't scan them normally, but remember this klassKlass // for later (see, for instance, oop_follow_contents above // for what MarkSweep does with it. if (blk->should_remember_klasses()) { blk->remember_klass(k); } obj->oop_iterate_header(blk); return size; }
// Return self, except for abstract classes with exactly 1 // implementor. Then return the 1 concrete implementation. Klass *Klass::up_cast_abstract() { Klass *r = this; while( r->is_abstract() ) { // Receiver is abstract? Klass *s = r->subklass(); // Check for exactly 1 subklass if( !s || s->next_sibling() ) // Oops; wrong count; give up return this; // Return 'this' as a no-progress flag r = s; // Loop till find concrete class } return r; // Return the 1 concrete class }