zoukankan      html  css  js  c++  java
  • jvm源码解读--07 创建 fixup_mirrors

    通过前面的分析,创建的insttanceKlass 都没放入了java_lang_Class::fixup_mirror_list()这里类的数组里面了,所有的instance列举如下

    ---------------------------------------------list->at(8)
    $3 = 0x7f6d6800f2b8 "java/lang/Object"
    (gdb) p _klass
    $4 = (InstanceKlass *) 0x100000f30
    ---------------------------------------------list->at(9)
    $7 = 0x7f6d68014f58 "java/io/Serializable"
    (gdb) p _klass
    $8 = (InstanceKlass *) 0x100001120
    ---------------------------------------------list->at(10)
    $9 = 0x7f6d68014fa8 "java/lang/Comparable"
    (gdb) p _klass
    $10 = (InstanceKlass *) 0x100001308
    -----------------------------------------------list->at(11)
            (gdb) p name->as_C_string()
    $12 = 0x7f6d680156b8 "java/lang/CharSequence"
    (gdb) p _klass
    $13 = (InstanceKlass *) 0x1000014f0
     -----------------------------------------------list->at(12)
            (gdb) p name->as_C_string()
    $15 = 0x7f6d68014d38 "java/lang/String"
    (gdb) p _klass
    $16 = (InstanceKlass *) 0x1000016d8
    -----------------------------------------------
            (gdb) p name->as_C_string()
    $17 = 0x7f6d6800ea68 "java/lang/Class"
    加载一半就不执行了,不知道为什么
    -----------------------------------------------list->at(13)
    $8 = 0x7ff06c0100a8 "java/lang/reflect/AnnotatedElement"
    (gdb) p _klass
    $9 = (InstanceKlass *) 0x100001948
     -----------------------------------------------list->at(13)
            (gdb) p name->as_C_string()
    $11 = 0x7ff06c00ef28 "java/lang/reflect/GenericDeclaration"
    (gdb) p _klass
    $16 = (InstanceKlass *) 0x100001b30
     -------------------------------------------预加载中创建的对象
    (gdb) p $26.as_C_string()
    $27 = 0x7ff06c009c88 "java/lang/Class"
    (gdb) p k
    $21 = (InstanceMirrorKlass *) 0x100001f00
    --------------------------------------------

    最后的java/lang/Class是,不再list中

    进入主流程

      GrowableArray <Klass*>* list = java_lang_Class::fixup_mirror_list();
      int list_length = list->length();
      for (int i = 0; i < list_length; i++) {
        Klass* k = list->at(i);
        assert(k->is_klass(), "List should only hold classes");
        EXCEPTION_MARK;
        KlassHandle kh(THREAD, k);
        java_lang_Class::fixup_mirror(kh, CATCH);
    }

    说明 上述的list_length为17 , 前面从list->at(8)就是读取的Object,之前的是ArrayKlass类型的对象,现在读取的是k 为 $32 = (TypeArrayKlass *) 0x100000030

    -->

    java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {create_mirror(k, Handle(NULL), CHECK);}

    进入

    oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
      assert(k->java_mirror() == NULL, "should only assign mirror once");
    
      int computed_modifiers = k->compute_modifier_flags(CHECK_0);
      k->set_modifier_flags(computed_modifiers);
      // Class_klass has to be loaded because it is used to allocate
      // the mirror.
      if (SystemDictionary::Class_klass_loaded()) {
        // Allocate mirror (java.lang.Class instance)
        Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
    
        InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
        java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
    
        // It might also have a component mirror.  This mirror must already exist.
        if (k->oop_is_array()) {
          Handle comp_mirror;
          if (k->oop_is_typeArray()) {
            BasicType type = TypeArrayKlass::cast(k())->element_type();
            comp_mirror = Universe::java_mirror(type);
          } else {
            assert(k->oop_is_objArray(), "Must be");
            Klass* element_klass = ObjArrayKlass::cast(k())->element_klass();
            assert(element_klass != NULL, "Must have an element klass");
              comp_mirror = element_klass->java_mirror();
          }
          assert(comp_mirror.not_null(), "must have a mirror");
    
            // Two-way link between the array klass and its component mirror:
          ArrayKlass::cast(k())->set_component_mirror(comp_mirror());
          set_array_klass(comp_mirror(), k());
        } else {
          assert(k->oop_is_instance(), "Must be");
    
          // Allocate a simple java object for a lock.
          // This needs to be a java object because during class initialization
          // it can be held across a java call.
          typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
          set_init_lock(mirror(), r);
    
          // Set protection domain also
          set_protection_domain(mirror(), protection_domain());
    
          // Initialize static fields
          InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
        }
        return mirror();
      } else {
        if (fixup_mirror_list() == NULL) {
          GrowableArray<Klass*>* list =
           new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true);
          set_fixup_mirror_list(list);
        }
        fixup_mirror_list()->push(k());
        return NULL;
      }
    }

    解析橘色标记的橘色就是创建mirror的内存空间,

    InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);

    这个句子的主干是 Klass->allocat_instance(k,xxx),这个Klass就是名字为"java/lang/Class"的instanceKlass对象,这个对象的地址为0x100001f00,这个对象非常重要

    那么解析过程如下

    //解析宏如下
    获取 SystemDictionary::Class_klass()
    
    static Klass* name() { return check_klass_##option(_well_known_klasses[Class_klass_knum]); }
    --->
       static Klass* check_klass_Pre(       Klass* k) { return check_klass(k); }
    ----->
            // Fast access to commonly used classes (preloaded)
            static Klass* check_klass(Klass* k) {
                assert(k != NULL, "preloaded klass not initialized");
                return k;
            }
    (gdb) p k
    $21 = (InstanceMirrorKlass *) 0x100001f00

    打印对象

            (gdb) p *k
    $23 = (InstanceMirrorKlass) {
            <InstanceKlass> = {
                <Klass> = {
                    <Metadata> = {
                        <MetaspaceObj> = {<No data fields>},
                        members of Metadata:
                        _vptr.Metadata = 0x7ff071f18a50 <vtable for InstanceMirrorKlass+16>,
                                _valid = 0
                    },
                    members of Klass:
                    _layout_helper = 97,
                    _super_check_offset = 56,
                    _name = 0x7ff070064108,
                    _secondary_super_cache = 0x0,
                    _secondary_supers = 0x7ff05ada9560,
                    _primary_supers = {0x100000f30, 0x100001f00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
                    _java_mirror = 0x0,
                    _super = 0x100000f30,
                    _subklass = 0x0,
                    _next_sibling = 0x100001d18,
                    _next_link = 0x100001d18,
                    _class_loader_data = 0x7ff06c02e868,
                    _modifier_flags = 17,
                    _access_flags = {
                            _flags = 538968113
                    },
                    _last_biased_lock_bulk_revocation_time = 0,
                    _prototype_header = 0x1,
                    _biased_lock_revocation_count = 0,
                    _modified_oops = 0 '00',
                            _accumulated_modified_oops = 0 '00'
                },
                members of InstanceKlass:
                static _total_instanceKlass_count = 9,
                        _annotations = 0x0,
                        _array_klasses = 0x0,
                        _constants = 0x7ff05ad9da78,
                        _inner_classes = 0x7ff05ada94f0,
                        _source_debug_extension = 0x0,
                        _array_name = 0x0,
                        _nonstatic_field_size = 20,
                        _static_field_size = 5,
                        _generic_signature_index = 796,
                        _source_file_name_index = 798,
                        _static_oop_field_count = 3,
                        _java_fields_count = 20,
                        _nonstatic_oop_map_size = 1,
                        _is_marked_dependent = false,
                        _misc_flags = 34,
                        _minor_version = 0,
                        _major_version = 52,
                        _init_thread = 0x0,
                        _vtable_len = 5,
                        _itable_len = 20,
                        _oop_map_cache = 0x0,
                        _member_names = 0x0,
                        _jni_ids = 0x0,
                        _methods_jmethod_ids = 0x0,
                        _dependencies = 0x0,
                        _osr_nmethods_head = 0x0,
                        _breakpoints = 0x0,
                        _previous_versions = 0x0,
                        _cached_class_file = 0x0,
                        _idnum_allocated_count = 129,
                        _init_state = 1 '01',
                        _reference_type = 0 '00',
                        _jvmti_cached_class_field_map = 0x0,
                        _verify_count = 0,
                        _methods = 0x7ff05ada19f0,
                        _default_methods = 0x0,
                        _local_interfaces = 0x7ff05ada0440,
                        _transitive_interfaces = 0x7ff05ada9560,
                        _method_ordering = 0x7ff05ad94048,
                        _default_vtable_indices = 0x0,
                        _fields = 0x7ff05ada1898
            },
            members of InstanceMirrorKlass:
            static _offset_of_static_fields = 96
    }
    (gdb) p k._name
            $24 = (Symbol *) 0x7ff070064108
    
    (gdb) p *(Symbol *) 0x7ff070064108
    $26 = {
            <SymbolBase> = {
                <MetaspaceObj> = {<No data fields>},
                members of SymbolBase:
                _length = 15,
                _refcount = -1,
                _identity_hash = 813005551
            },
            members of Symbol:
            _body = {106 'j'},
            static _total_count = 3
    }
    View Code

    (gdb) p $26.as_C_string()
    $27 = 0x7ff06c009c88 "java/lang/Class"

    以上验证了 0x100001f00 是 java/lang/Class,但是他是预加载了,并没有在.Class文件解析中来创建对象

    进入InstanceMirrorKlass::allocate_instance函数

    instanceOop InstanceMirrorKlass::allocate_instance(KlassHandle k, TRAPS) {
      // Query before forming handle.
      int size = instance_size(k);
      KlassHandle h_k(THREAD, this);
      instanceOop i = (instanceOop) CollectedHeap::Class_obj_allocate(h_k, size, k, CHECK_NULL);
      return i;
    }

    进入size()函数

    int InstanceMirrorKlass::instance_size(KlassHandle k) {
      if (k() != NULL && k->oop_is_instance()) {//不进入
        return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
      }
      return size_helper();
    }
    
    ---->
      int size_helper() const {
        return layout_helper_to_size_helper(layout_helper());
      }
    ------->  int layout_helper() const            { return _layout_helper; }

    那么这个名字为"java/lang/Class"的  _layout_helper

    这里看到就是(const InstanceMirrorKlass * const) 0x100001f00 这个对象的成员
      打印如下:
            members of Klass:
            _layout_helper = 97,

    还经过了右移处理,返回为12

    进入紫色函数

    oop CollectedHeap::Class_obj_allocate(KlassHandle klass, int size, KlassHandle real_klass, TRAPS) {
      
      HeapWord* obj;
        
        obj = common_mem_allocate_init(real_klass, size, CHECK_NULL);
    //设置oop的内容
    post_allocation_setup_common(klass, obj);
    oop mirror = (oop)obj;  // 这个是设置oop对象大小属性
      java_lang_Class::set_oop_size(mirror, size);
    
      // Setup indirections
      if (!real_klass.is_null()) {
        java_lang_Class::set_klass(mirror, real_klass());
        real_klass->set_java_mirror(mirror);
      }
    
      InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
      assert(size == mk->instance_size(real_klass), "should have been set");
    
      // notify jvmti and dtrace
      post_allocation_notify(klass, (oop)obj);
    
      return mirror;
    }

    绿色的就是分配函数,进去

    HeapWord* CollectedHeap::common_mem_allocate_init(KlassHandle klass, size_t size, TRAPS) {
      HeapWord* obj = common_mem_allocate_noinit(klass, size, CHECK_NULL);
    // 初始化为0的函数 init_obj(obj, size);
    return obj; }

    再进去

    HeapWord* CollectedHeap::common_mem_allocate_noinit(KlassHandle klass, size_t size, TRAPS) {
    
      // Clear unhandled oops for memory allocation.  Memory allocation might
      // not take out a lock if from tlab, so clear here.
      CHECK_UNHANDLED_OOPS_ONLY(THREAD->clear_unhandled_oops();)
    
      if (HAS_PENDING_EXCEPTION) {
        NOT_PRODUCT(guarantee(false, "Should not allocate with exception pending"));
        return NULL;  // caller does a CHECK_0 too
      }
    
      HeapWord* result = NULL;
      if (UseTLAB) { 
        result = allocate_from_tlab(klass, THREAD, size);
        if (result != NULL) {
          assert(!HAS_PENDING_EXCEPTION,
                 "Unexpected exception, will result in uninitialized storage");
          return result;
        }
      }
    }

    那么UseTLAB=true 就是从TLAB分配内存打印一下

            (gdb) p thread->tlab()
    $9 = (ThreadLocalAllocBuffer &) @0x7f97cc00b860: {
    <CHeapObj<512u>> = {
    <AllocatedObj> = {
    _vptr.AllocatedObj = 0x7f97d4254710 <vtable for ThreadLocalAllocBuffer+16>
    }, <No data fields>},
    members of ThreadLocalAllocBuffer:
    _start = 0xd7580000,
            _top = 0xd75803d0,
            _pf_top = 0xd7580010,
            _end = 0xd75828f0,
            _desired_size = 1310,
            _refill_waste_limit = 20,
    static _target_refills = 50,
            _number_of_refills = 1,
            _fast_refill_waste = 0,
            _slow_refill_waste = 0,
            _gc_waste = 0,
            _slow_allocations = 0,
            _allocation_fraction = {
            <CHeapObj<1280u>> = {
                <AllocatedObj> = {
                    _vptr.AllocatedObj = 0x7f97d42429d0 <vtable for AdaptiveWeightedAverage+16>
                }, <No data fields>},
            members of AdaptiveWeightedAverage:
            _average = 0.999450684,
            _sample_count = 1,
            _weight = 35,
            _is_old = false,
            static OLD_THRESHOLD = 100,
            _last_sample = 0.999450684
    },
    static _global_stats = 0x7f97cc02d998
    }

    就是从线程中获取_tlab 然后调用它的allocate函数

    inline HeapWord* ThreadLocalAllocBuffer::allocate(size_t size) {
      invariants();
      HeapWord* obj = top();
      if (pointer_delta(end(), obj) >= size) {
        // successful thread-local allocation
    #ifdef ASSERT
        // Skip mangling the space corresponding to the object header to
        // ensure that the returned space is not considered parsable by
        // any concurrent GC thread.
        size_t hdr_size = oopDesc::header_size();
        Copy::fill_to_words(obj + hdr_size, size - hdr_size, badHeapWordVal);
    #endif // ASSERT
        // This addition is safe because we know that top is
        // at least size below end, so the add can't wrap.
        set_top(obj + size);
    
        invariants();
        return obj;
      }
      return NULL;
    }

    然后 ,看的出来就是将_top = 0xd7580370 + 12 这个是指针加法

    加完之后的_top为 0xd75803d0 一共加了0x60,即12*8字节

    补充下黄色函数是

    void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
      assert(obj != NULL, "cannot initialize NULL object");
      const size_t hs = oopDesc::header_size();
      assert(size >= hs, "unexpected object size");
      ((oop)obj)->set_klass_gap(0);
      Copy::fill_to_aligned_words(obj + hs, size - hs);
    }
    
    ((oop)obj)->set_klass_gap(0);
    --->
        inline void oopDesc::set_klass_gap(int v) {
            if (UseCompressedClassPointers) {
                *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes()) = v;
            }
        }
    //以下返回12 int类型
    inline int oopDesc::klass_gap_offset_in_bytes() {
        assert(UseCompressedClassPointers, "only applicable to compressed klass pointers");
        return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
    }
    
    Copy::fill_to_aligned_words(obj + hs, size - hs);
    --->
    static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) { //count=10
        #ifdef AMD64  //在这里执行,一共执行了10次,每次移动8个字节,所以将oop后面的
        julong* to = (julong*) tohw;   //value 0xd7580380
        julong  v  = ((julong) value << 32) | value;
        while (count-- > 0) {
        *to++ = v;
        }
        #else  //以下不执行
        juint* to = (juint*)tohw;
        count *= HeapWordSize / BytesPerInt;
        while (count-- > 0) {
        *to++ = value;
        }
        #endif // AMD64
        }

    最后的执行结果为

        执行结果为
    (gdb) x/13xg 0xd7580370
    0xd7580370:    0xbaadbabebaadbabe    0x00000000baadbabe
    0xd7580380:    0x0000000000000000    0x0000000000000000
    0xd7580390:    0x0000000000000000    0x0000000000000000
    0xd75803a0:    0x0000000000000000    0x0000000000000000
    0xd75803b0:    0x0000000000000000    0x0000000000000000
    0xd75803c0:    0x0000000000000000    0x0000000000000000
    0xd75803d0:    0xbaadbabebaadbabe

    红色设置oop内容函数

    void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
                                                     HeapWord* obj) {
    //设置_mark为0x01
      post_allocation_setup_no_klass_install(klass, obj);
    //设置_metadata._compressed_klass的值为java/lang/Class的压缩指针0x100001f00
      post_allocation_install_obj_klass(klass, oop(obj));
    }

    具体只贴一下代码

    void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
                                                               HeapWord* objPtr) {
      oop obj = (oop)objPtr;
    
      assert(obj != NULL, "NULL object pointer");
      if (UseBiasedLocking && (klass() != NULL)) {
        obj->set_mark(klass->prototype_header());
      } else {
        // May be bootstrapping
        obj->set_mark(markOopDesc::prototype());
      }
    }
    
     打印java/lang/Class类instanceKlass的属性为
     _prototype_header = 0x1,

    还有

    void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
                                                       oop obj) {
      // These asserts are kind of complicated because of klassKlass
      // and the beginning of the world.
      assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
      assert(klass() == NULL || klass()->is_klass(), "not a klass");
      assert(obj != NULL, "NULL object pointer");
      obj->set_klass(klass());
      assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
             "missing klass");
    }
    
    inline void oopDesc::set_klass(Klass* k) {
      // since klasses are promoted no store check is needed
      assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
      assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
      if (UseCompressedClassPointers) {
        *compressed_klass_addr() = Klass::encode_klass_not_null(k);
      } else {
        *klass_addr() = k;
      }
    }
    //这个压缩指针,就是设置为0x200003e0
    inline narrowKlass Klass::encode_klass_not_null(Klass* v) {
      assert(!is_null(v), "klass value can never be zero");
      assert(check_klass_alignment(v), "Address not aligned");
      int    shift = Universe::narrow_klass_shift();
      uint64_t pd = (uint64_t)(pointer_delta((void*)v, Universe::narrow_klass_base(), 1));
      assert(KlassEncodingMetaspaceMax > pd, "change encoding max if new encoding");
      uint64_t result = pd >> shift;
      assert((result & CONST64(0xffffffff00000000)) == 0, "narrow klass pointer overflow");
      assert(decode_klass(result) == v, "reversibility");
      return (narrowKlass)result;
    }

    进入紫色的函数

    void java_lang_Class::set_oop_size(oop java_class, int size) {
      assert(_oop_size_offset != 0, "must be set");
      java_class->int_field_put(_oop_size_offset, size);
    }

    先弄清楚了定义java_lang_Class 中的定义

    打印的的内容
        _klass_offset  =64
        _array_klass_offset   =72
        _oop_size_offset   =84
        _static_oop_field_count_offset =88
        _protection_domain_offset = 52
        _init_lock_offset =56
        _signers_offset=60
        offsets_computed=80

    一连串后

    inline void*     oopDesc::field_base(int offset)        const { return (void*)&((char*)this)[offset]; }

    就是那么就是将 _oop_size_offset =84 的位置设置为12

    还有灰色函数 是设置mirror 和real_class的对应关系

    //设置oop的偏移量为64的时候,为真是instancekass的地址 0x100000030
    void java_lang_Class::set_klass(oop java_class, Klass* klass) {
      assert(java_lang_Class::is_instance(java_class), "must be a Class object");
      java_class->metadata_field_put(_klass_offset, klass);
    }

    另外的是设置mirror

    (gdb) p this
    $15 = (TypeArrayKlass * const) 0x100000030
    real_klass->set_java_mirror(mirror);
    void set_java_mirror(oop m) { klass_oop_store(&_java_mirror, m); }
    
    void Klass::klass_oop_store(oop* p, oop v) {
    assert(!Universe::heap()->is_in_reserved((void*)p), "Should store pointer into metadata");
    assert(v == NULL || Universe::heap()->is_in_reserved((void*)v), "Should store pointer to an object");
    
    //真是对象的_java_mirror设置为oop
    设置klass对象_java_mirror变量值,这个_java_mirror是很重要的呢

    以上就结束了 mirror的创建打印一下

    (gdb) p mirror
    $16 = (oopDesc *) 0xd7580370
            (gdb) x/12xg mirror
    0xd7580370:    0x0000000000000001    0x00000000200003e0
    0xd7580380:    0x0000000000000000    0x0000000000000000
    0xd7580390:    0x0000000000000000    0x0000000000000000
    0xd75803a0:    0x0000000000000000    0x0000000000000000
    0xd75803b0:    0x0000000100000030    0x0000000000000000
    0xd75803c0:    0x0000000c00000000    0x0000000000000000

    那么就是叶子颜色的函数

     InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
    inline Klass* oopDesc::klass() const {
      if (UseCompressedClassPointers) {
        return Klass::decode_klass_not_null(_metadata._compressed_klass);
      } else {
        return _metadata._klass;
      }
    }

    这就是获取了之前设置的压缩指针_klass

    (gdb) p mk
    $29 = (InstanceMirrorKlass *) 0x100001f00

    还有

    (gdb) p  **  mirror._handle
            $28 = {
            _mark = 0x1,
            _metadata = {
                    _klass = 0x200003e0,
                    _compressed_klass = 536871904
            },
            static _bs = 0x7f6ba401ea48
    }
    0x200003e0左移3位 得到 0x100001f00
    java/lang/Class 内存为 0x100001f00, 处理的对象内存为 0x100000030

    进入最顶级紫色函数

    int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
      Klass* k = java_lang_Class::as_Klass(obj);
      if (k != NULL && k->oop_is_instance()) {
        return InstanceKlass::cast(k)->static_oop_field_count();
      }
      return 0;
    }
    
    //因为是array返回为0
    mirror()函数返回oop对象0xd7580370

    还是给oop对象设置内容

    void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
      assert(_static_oop_field_count_offset != 0, "must be set");
      java_class->int_field_put(_static_oop_field_count_offset, size);
    }

    顶级灰色

    (gdb) p k
    $30 = (TypeArrayKlass *) 0x100000030
    BasicType type = TypeArrayKlass::cast(k())->element_type();
    comp_mirror = Universe::java_mirror(type);
    static oop java_mirror(BasicType t) {
        assert((uint)t < T_VOID+1, "range check");
        return check_mirror(_mirrors[t]);
    }
    //从上边看的出来type为4  Bool类型
    
    $31 = (oopDesc *) 0xd7580190
            (gdb) p _mirrors[4]
    $32 = (oopDesc *) 0xd7580190

    那么将_mirror[4]设置为comp_mirror

    // Two-way link between the array klass and its component mirror:
    ArrayKlass::cast(k())->set_component_mirror(comp_mirror()); void set_component_mirror(oop m) { klass_oop_store(&_component_mirror, m); }
    // comp_mirror()
    = 0xd7580190 ,,,k()=0x100000030
    //设置oop的72便宜量为0x100000030
    set_array_klass(comp_mirror(), k()); void java_lang_Class::set_array_klass(oop java_class, Klass* klass) { assert(klass->is_klass() && klass->oop_is_array(), "should be array klass"); java_class->metadata_field_put(_array_klass_offset, klass); //off=72 }

    最后的oop内存结构为

    (gdb) x/12xg 0xd7580370
    0xd7580370:    0x0000000000000001    0x00000000200003e0
    0xd7580380:    0x0000000000000000    0x0000000000000000
    0xd7580390:    0x0000000000000000    0x0000000000000000
    0xd75803a0:    0x0000000000000000    0x0000000000000000
    0xd75803b0:    0x0000000100000030    0x0000000000000000
    0xd75803c0:    0x0000000c00000000    0x0000000000000000

    这就结束了mirror的创建arrrayinstancemirror的创建003e

  • 相关阅读:
    如何将平时所学的代码知识,用在实际测试场景中
    CSS,XTHML书写规范以及常见问题总结
    网页底部定位
    时不我待
    用CSS设置Table的细边框的最好用的方法
    CSS Hack总结说明
    批处理轻松删除Win7下WINDOWS.OLD文件夹
    通过iframe调用页面的一部分,实现自己想要的页面
    超简单的javascript
    form在IE6中会影响样式的问题
  • 原文地址:https://www.cnblogs.com/zytcomeon/p/14631488.html
Copyright © 2011-2022 走看看