voidKlass::append_to_sibling_list(){ if (Universe::is_fully_initialized()) { assert_locked_or_safepoint(Compile_lock); } debug_only(verify();) // add ourselves to superklass' subklass list InstanceKlass* super = superklass(); // 什么时候才会有兄弟链的情况 大家都是派生于一个直接父类的时候 if (super == nullptr) return; // special case: class Object assert((!super->is_interface() // interfaces cannot be supers && (super->superklass() == nullptr || !is_interface())), "an interface can only be a subklass of Object");
// Make sure there is no stale subklass head super->clean_subklass();
for (;;) { // 兄弟链上的第一个 也就是单链表的表头 Klass* prev_first_subklass = Atomic::load_acquire(&_super->_subklass); if (prev_first_subklass != nullptr) { // set our sibling to be the superklass' previous first subklass assert(prev_first_subklass->is_loader_alive(), "May not attach not alive klasses"); set_next_sibling(prev_first_subklass); } // Note that the prev_first_subklass is always alive, meaning no sibling_next links // are ever created to not alive klasses. This is an important invariant of the lock-free // cleaning protocol, that allows us to safely unlink dead klasses from the sibling list. if (Atomic::cmpxchg(&super->_subklass, prev_first_subklass, this) == prev_first_subklass) { return; } } debug_only(verify();) }
// Allocation if (parser.is_instance_ref_klass()) { // java.lang.ref.Reference ik = new (loader_data, size, THREAD) InstanceRefKlass(parser); } elseif (class_name == vmSymbols::java_lang_Class()) { // mirror - java.lang.Class ik = new (loader_data, size, THREAD) InstanceMirrorKlass(parser); } elseif (is_stack_chunk_class(class_name, loader_data)) { // stack chunk ik = new (loader_data, size, THREAD) InstanceStackChunkKlass(parser); } elseif (is_class_loader(class_name, parser)) { // class loader - java.lang.ClassLoader ik = new (loader_data, size, THREAD) InstanceClassLoaderKlass(parser); } else { // normal ik = new (loader_data, size, THREAD) InstanceKlass(parser); }
// Check for pending exception before adding to the loader data and incrementing // class count. Can get OOM here. if (HAS_PENDING_EXCEPTION) { returnnullptr; }