【JVM篇】Java类的加载

1、看ClassLoader部分源码,最终总结:

1.loadClass用于实现类加载的代理机制;
2.findClass用于找到类的二进制表示;
3.defineClass用于将类的二进制表示转化成Class对象,这一步由虚拟机来完成;

2、defineClass分析
private native Class defineClass1(String name, byte[] b, int off, int len, ProtectionDomain pd, String source);
private native Class defineClass2(String name, java.nio.ByteBuffer b, int off, int len, ProtectionDomain pd, String source);
//ClassLoader.c
JNIEXPORT jclass JNICALL Java_java_lang_ClassLoader_defineClass1(JNIEnv *env,jclass cls,jobject loader,jstring name,jbyteArray data,jint offset,jint length,jobject pd,jstring source){
    ...
    result = JVM_DefineClassWithSource(env, utfName, loader, body, length, pd, utfSource);
}

JVM_ENTRY是宏,对公共逻辑进行的统一封装,这里关注的逻辑是调用了jvm_define_class_common,最终调用SystemDictionary::resolve_from_stream加载数据流并生成Klass

//jvm.cpp
JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
  JVMWrapper2("JVM_DefineClassWithSource %s", name);
  return jvm_define_class_common(env, name, loader, buf, len, pd, source, true, THREAD);
JVM_END
//jvm.cpp
static jclass jvm_define_class_common(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source, TRAPS) {
    class_name = SymbolTable::new_symbol(name, str_len, CHECK_NULL);
    ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
    Handle class_loader (THREAD, JNIHandles::resolve(loader));
    Klass* k = SystemDictionary::resolve_from_stream(class_name,class_loader,protection_domain,&st,CHECK_NULL);
    return (jclass) JNIHandles::make_local(env, k->java_mirror());
}
InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, TRAPS) {
    ClassLoaderData* loader_data = register_loader(class_loader);
    k = KlassFactory::create_from_stream(st, class_name, loader_data...);
    define_instance_class(k, THREAD);
}

KlassFactory是解析逻辑的重点,加载数据流,通过ClassFileParser 解析类的常量池、成员变量、函数等所有

// klassFactory.cpp
InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream, Symbol* name, ClassLoaderData* loader_data, Handle protection_domain, const InstanceKlass* unsafe_anonymous_host, GrowableArray<Handle>* cp_patches, TRAPS) {
    JvmtiCachedClassFileData* cached_class_file = NULL;
    ClassFileStream* old_stream = stream;
    THREAD->statistical_info().incr_define_class_count();
    // class字节流解析工具
    ClassFileParser parser(stream, name, loader_data, protection_domain,...);
    ->parse_stream(stream, CHECK);  --【classFileParser.cpp】
      //模数版本等
      ->const u4 magic = stream->get_u4_fast();
      ->_minor_version = stream->get_u2_fast();
      ->verify_class_version(_major_version, _minor_version, _class_name, CHECK);
     //常量池的解析 
     ->_cp = ConstantPool::allocate(_loader_data, cp_size, CHECK);  
     ->ConstantPool* const cp = _cp;
     ->parse_constant_pool(stream, cp, _orig_cp_size, CHECK);
     //成员变量的解析
     ->parse_fields(stream, _access_flags.is_interface(),_fac,cp,cp_size,&_java_fields_count,CHECK);
     //方法函数的解析
     ->parse_methods(stream,_access_flags.is_interface(),&promoted_flags,&_has_final_method,&_declares_nonstatic_concrete_methods,CHECK);
       ->_methods = MetadataFactory::new_array<Method*>(_loader_data, length, NULL, CHECK);
       ->for (int index = 0; index < length; index++)
         ->Method* method = parse_method(cfs, is_interface, _cp, promoted_flags, CHECK);
         ->_methods->at_put(index, method);
    //生成最终Klass对象 
    InstanceKlass* result = parser.create_instance_klass(old_stream != stream, CHECK_NULL);
    ->InstanceKlass* const ik = InstanceKlass::allocate_instance_klass(*this, CHECK_NULL);
    ->fill_instance_klass(ik, changed_by_loadhook, CHECK_NULL);  --【classFileParser.cpp】
     ->ik->set_name(_class_name);  --【classFileParser.cpp】
     ->_loader_data->add_class(ik, publicize);  --【classFileParser.cpp】
     ->ik->set_nonstatic_field_size(_field_info->nonstatic_field_size);  --【classFileParser.cpp】
     ->ik->set_has_nonstatic_fields(_field_info->has_nonstatic_fields);  --【classFileParser.cpp】
     ->apply_parsed_class_metadata(ik, _java_fields_count, CHECK);  --【classFileParser.cpp】
       ->_cp->set_pool_holder(this_klass);  --【classFileParser.cpp】
       ->this_klass->set_constants(_cp);  --【classFileParser.cpp】
       ->this_klass->set_fields(_fields, java_fields_count);  --【classFileParser.cpp】
       ->this_klass->set_methods(_methods);  --【classFileParser.cpp】
       ->this_klass->set_local_interfaces(_local_interfaces);  --【classFileParser.cpp】
       ->this_klass->set_annotations(_combined_annotations);  --【classFileParser.cpp】
    ->return ik;
    if (cached_class_file != NULL) {
       result->set_cached_class_file(cached_class_file);
    } 
   result->store_fingerprint(stream->compute_fingerprint());
   p = (JvmtiCachedClassFileData*)os::malloc(offset_of(JvmtiCachedClassFileData, data) + len, mtInternal);
   len = stream->length();
   bytes = stream->buffer();
   memcpy(p->data, bytes, len);
   result->set_archived_class_data(p);                                                   
}

这里重点分析下方法的解析

//classFileParser.cpp
Method* ClassFileParser::parse_method(const ClassFileStream* const cfs, bool is_interface, const ConstantPool* cp, AccessFlags* const promoted_flags, TRAPS) {
    u2 max_stack = 0;
    u2 max_locals = 0;
    u4 code_length = 0;
    const u1* code_start = 0;
    u2 method_attributes_count = cfs->get_u2_fast();
    while (method_attributes_count--) {
        const Symbol* const method_attribute_name = cp->symbol_at(method_attribute_name_index);
        //字节码指令
       if (method_attribute_name == vmSymbols::tag_code()) {
            max_stack = cfs->get_u2_fast();
            max_locals = cfs->get_u2_fast();
            code_length = cfs->get_u4_fast();
            //字节码指令起始
            code_start = cfs->current();
            u2 code_attributes_count = cfs->get_u2_fast();
            while (code_attributes_count--) {
                const u2 code_attribute_name_index = cfs->get_u2_fast();
                const u4 code_attribute_length = cfs->get_u4_fast();
                //局部变量表
                localvariable_type_table_start[lvtt_cnt] = parse_localvariable_table(cfs,code_length,max_locals,code_attribute_length,&localvariable_type_table_length[lvtt_cnt],true,     // is LVTTCHECK_NULL);
                //操作数栈
                stackmap_data = parse_stackmap_table(cfs, code_attribute_length, _need_verify, CHECK_NULL);
            }
        //报错    
        } else if (method_attribute_name == vmSymbols::tag_exceptions()) {
        
        //方法参数
        } else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
            method_parameters_length = cfs->get_u1_fast();
            method_parameters_data = cfs->current();
        } else if (_major_version >= JAVA_1_5_VERSION) {
            //注解
            if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
                parse_annotations(cp,runtime_visible_annotations,runtime_visible_annotations_length,&parsed_annotations,_loader_data,CHECK_NULL);
            }
        }
    }
    //创建方法对象
    Method* const m = Method::allocate(_loader_data,code_length,access_flags,&sizes,ConstMethod::NORMAL,CHECK_NULL);
    //设置常量池
    m->set_constants(_cp);
    m->set_name_index(name_index);
    
    //设置返回类型
    ResultTypeFinder rtf(cp->symbol_at(signature_index));
    m->constMethod()->set_result_type(rtf.type());
    
    m->set_size_of_parameters(args_size);
    m->set_max_stack(max_stack);
    m->set_max_locals(max_locals);
    
    //设置操作数栈空间分配
    m->constMethod()->copy_stackmap_data(_loader_data, (u1*)stackmap_data,stackmap_data_length,CHECK_NULL);
    
    //设置字节码指令起始地址
    m->set_code((u1*)code_start);
    
    memcpy(m->compressed_linenumber_table(),linenumber_table->buffer(),linenumber_table_length);
    //设置局部变量表空间
    copy_localvariable_table(m->constMethod(),lvt_cnt,localvariable_table_length,localvariable_table_start,lvtt_cnt,localvariable_type_table_length,localvariable_type_table_start,CHECK_NULL);
    
    //设置注解
    parsed_annotations.apply_to(m);
    copy_method_annotations(m->constMethod(),...)
    return m;
}

最终将klass注册到dictionary,用于后期类的查询创建

//systemDictionary.cpp
void SystemDictionary::define_instance_class(InstanceKlass* k, TRAPS) {
    Symbol*  name_h = k->name();
    Dictionary* dictionary = loader_data->dictionary();
    unsigned int d_hash = dictionary->compute_hash(name_h);
    check_constraints(d_hash, k, class_loader_h, true, CHECK);
    update_dictionary(d_hash, p_index, p_hash, k, class_loader_h, THREAD);
    ->dictionary->add_klass(d_hash, name, k);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值