`
xieyj
  • 浏览: 104545 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

ClassFileParser::parseClassFile阅读

阅读更多

     instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
                                                    Handle class_loader,
                                                    Handle protection_domain,
                                                    symbolHandle& parsed_name,
                                                    TRAPS)

     是一个非常复杂的方法。

     unsigned char *cached_class_file_bytes = NULL;
     jint cached_class_file_length;

     //加载的类文件流

     ClassFileStream* cfs = stream();
     // Timing
     PerfTraceTime vmtimer(ClassLoader::perf_accumulated_time());

     _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;

     if (JvmtiExport::should_post_class_file_load_hook()) {
                     unsigned char* ptr = cfs->buffer();
                     unsigned char* end_ptr = cfs->buffer() + cfs->length();

                     JvmtiExport::post_class_file_load_hook(name, class_loader, protection_domain,
                                           &ptr, &end_ptr,
                                           &cached_class_file_bytes,
                                           &cached_class_file_length);

                    if (ptr != cfs->buffer()) {
                             cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source());
                             set_stream(cfs);
                     }
      }


  instanceKlassHandle nullHandle;

  // Figure out whether we can skip format checking (matching classic VM behavior)
  _need_verify = Verifier::should_verify_for(class_loader());

  // Set the verify flag in stream
  cfs->set_verify(_need_verify);

  // 类名不能为空
  _class_name = name.not_null()? name : vmSymbolHandles::unknown_class_name();

  cfs->guarantee_more(8, CHECK_(nullHandle));  // magic, major, minor
  // 文件模数,看是否java文件格式
  u4 magic = cfs->get_u4_fast();
  guarantee_property(magic == JAVA_CLASSFILE_MAGIC,
                     "Incompatible magic value %u in class file %s",
                     magic, CHECK_(nullHandle));

  // jdk的版本号
  u2 minor_version = cfs->get_u2_fast();
  u2 major_version = cfs->get_u2_fast();

  // Check version numbers - we check this even with verifier off
  if (!is_supported_version(major_version, minor_version)) {
    if (name.is_null()) {
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbolHandles::java_lang_UnsupportedClassVersionError(),
        "Unsupported major.minor version %u.%u",
        major_version,
        minor_version);
    } else {
      ResourceMark rm(THREAD);
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbolHandles::java_lang_UnsupportedClassVersionError(),
        "%s : Unsupported major.minor version %u.%u",
        name->as_C_string(),
        major_version,
        minor_version);
    }
    return nullHandle;
  }

  _major_version = major_version;
  _minor_version = minor_version;


  // Check if verification needs to be relaxed for this class file
  // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)
  _relax_verify = Verifier::relax_verify_for(class_loader());

  // 对常量池进行解析,常量池存放文件字符串、final变量值、类名、方法名等常量。
  constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
  int cp_size = cp->length();

  cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len

  // Access flags
  AccessFlags access_flags;
 ...

    u2 super_class_index = cfs->get_u2_fast();

    //只有java.lang.Object没有超类
    if (super_class_index == 0) {
      check_property(class_name() == vmSymbols::java_lang_Object(),
                     "Invalid superclass index %u in class file %s",
                     super_class_index,
                     CHECK_(nullHandle));
    } else {
      check_property(valid_cp_range(super_class_index, cp_size) &&
                     cp->tag_at(super_class_index).is_unresolved_klass(),
                     "Invalid superclass index %u in class file %s",
                     super_class_index,
                     CHECK_(nullHandle));
      // The class name should be legal because it is checked when parsing constant pool.
      // However, make sure it is not an array type.
      if (_need_verify) {
        guarantee_property(cp->unresolved_klass_at(super_class_index)->byte_at(0) != JVM_SIGNATURE_ARRAY,
                          "Bad superclass name in class file %s", CHECK_(nullHandle));
      }
    }

    //先解析类的接口

    u2 itfs_len = cfs->get_u2_fast();
    objArrayHandle local_interfaces;
    if (itfs_len == 0) {
      local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
    } else {
      local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, &vmtimer, _class_name, CHECK_(nullHandle));
    }

    // Fields (offsets are filled in later)
    struct FieldAllocationCount fac = {0,0,0,0,0,0,0,0,0,0};
    objArrayHandle fields_annotations;
    typeArrayHandle fields = parse_fields(cp, access_flags.is_interface(), &fac, &fields_annotations, CHECK_(nullHandle));
    // Methods
    bool has_final_method = false;
    AccessFlags promoted_flags;
    promoted_flags.set_flags(0);
    // These need to be oop pointers because they are allocated lazily
    // inside parse_methods inside a nested HandleMark
    objArrayOop methods_annotations_oop = NULL;
    objArrayOop methods_parameter_annotations_oop = NULL;
    objArrayOop methods_default_annotations_oop = NULL;
    objArrayHandle methods = parse_methods(cp, access_flags.is_interface(),
                                           &promoted_flags,
                                           &has_final_method,
                                           &methods_annotations_oop,
                                           &methods_parameter_annotations_oop,
                                           &methods_default_annotations_oop,
                                           CHECK_(nullHandle));

    objArrayHandle methods_annotations(THREAD, methods_annotations_oop);
    objArrayHandle methods_parameter_annotations(THREAD, methods_parameter_annotations_oop);
    objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);

    // We check super class after class file is parsed and format is checked
    if (super_class_index > 0) {
      symbolHandle sk (THREAD, cp->klass_name_at(super_class_index));
      if (access_flags.is_interface()) {
        // Before attempting to resolve the superclass, check for class format
        // errors not checked yet.
        guarantee_property(sk() == vmSymbols::java_lang_Object(),
                           "Interfaces must have java.lang.Object as superclass in class file %s",
                           CHECK_(nullHandle));
      }

      //解析超类
      klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
                                                           sk,
                                                           class_loader,
                                                           protection_domain,
                                                           true,
                                                           CHECK_(nullHandle));
      KlassHandle kh (THREAD, k);
      super_klass = instanceKlassHandle(THREAD, kh());
      if (super_klass->is_interface()) {
        ResourceMark rm(THREAD);
        Exceptions::fthrow(
          THREAD_AND_LOCATION,
          vmSymbolHandles::java_lang_IncompatibleClassChangeError(),
          "class %s has interface %s as super class",
          class_name->as_klass_external_name(),
          super_klass->external_name()
        );
        return nullHandle;
      }
      // Make sure super class is not final
      if (super_klass->is_final()) {
        THROW_MSG_(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class", nullHandle);
      }
    }

    // Compute the transitive list of all unique interfaces implemented by this class
    objArrayHandle transitive_interfaces = compute_transitive_interfaces(super_klass, local_interfaces, CHECK_(nullHandle));

    // sort methods,这里主要是用于vtable的构造和快速查找吧
    typeArrayHandle method_ordering = sort_methods(methods,
                                                   methods_annotations,
                                                   methods_parameter_annotations,
                                                   methods_default_annotations,
                                                   CHECK_(nullHandle));

    // promote flags from parse_methods() to the klass' flags
    access_flags.add_promoted_flags(promoted_flags.as_int());

    // Size of Java vtable (in words)
    int vtable_size = 0;
    int itable_size = 0;
    int num_miranda_methods = 0;

    klassVtable::compute_vtable_size_and_num_mirandas(vtable_size,
                                                      num_miranda_methods,
                                                      super_klass(),
                                                      methods(),
                                                      access_flags,
                                                      class_loader(),
                                                      class_name(),
                                                      local_interfaces());

    // Size of Java itable (in words)
    itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces);

    // Field size and offset computation
    int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size();
    ....
    next_static_oop_offset      = (instanceKlass::header_size() +
                                  align_object_offset(vtable_size) +
                                  align_object_offset(itable_size)) * wordSize;
    next_static_double_offset   = next_static_oop_offset +
                                  (fac.static_oop_count * heapOopSize);
    ...

    //在上面进行实例大小的计算
    int instance_size;

    instance_size = align_object_size(next_nonstatic_type_offset / wordSize);

    assert(instance_size == align_object_size(instanceOopDesc::header_size() + nonstatic_field_size), "consistent layout helper value");

    // Size of non-static oop map blocks (in words) allocated at end of klass

    //oop map block主要用于gc操作
    int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset);

    // Compute reference type
    ReferenceType rt;
    if (super_klass() == NULL) {
      rt = REF_NONE;
    } else {
      rt = super_klass->reference_type();
    }

    // We can now create the basic klassOop for this klass,在这里面就有Object header

    //垃圾回收会用到的标志,都在里面,粗略来看,一个java对象在jvm里面还涉及Oject header、oop map 大小

    //vtable\itable、静态域等
    klassOop ik = oopFactory::new_instanceKlass(
                                    vtable_size, itable_size,
                                    static_field_size, nonstatic_oop_map_size,
                                    rt, CHECK_(nullHandle));
    instanceKlassHandle this_klass (THREAD, ik);

    assert(this_klass->static_field_size() == static_field_size &&
           this_klass->nonstatic_oop_map_size() == nonstatic_oop_map_size, "sanity check");

    // 填充解析好的各项值

    this_klass->set_access_flags(access_flags);
    jint lh = Klass::instance_layout_helper(instance_size, false);
    this_klass->set_layout_helper(lh);
    ...

    // 解析类的属性
    parse_classfile_attributes(cp, this_klass, CHECK_(nullHandle));

    // Make sure this is the end of class file stream
    guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));

    // Initialize static fields
    this_klass->do_local_static_fields(&initialize_static_field, CHECK_(nullHandle));

    // VerifyOops believes that once this has been set, the object is completely loaded.
    // Compute transitive closure of interfaces this class implements
    this_klass->set_transitive_interfaces(transitive_interfaces());

    // Fill in information needed to compute superclasses.
    this_klass->initialize_supers(super_klass(), CHECK_(nullHandle));

    // Initialize itable offset tables
    klassItable::setup_itable_offset_table(this_klass);

    // Do final class setup
    fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_length);

    set_precomputed_flags(this_klass);

    // reinitialize modifiers, using the InnerClasses attribute
    int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle));
    this_klass->set_modifier_flags(computed_modifiers);

    // check if this class can access its super class
    check_super_class_access(this_klass, CHECK_(nullHandle));

    // check if this class can access its superinterfaces
    check_super_interface_access(this_klass, CHECK_(nullHandle));

    // check if this class overrides any final method
    check_final_method_override(this_klass, CHECK_(nullHandle));

    // check that if this class is an interface then it doesn't have static methods
    if (this_klass->is_interface()) {
      check_illegal_static_method(this_klass, CHECK_(nullHandle));
    }

     ...

     instanceKlassHandle this_klass (THREAD, preserve_this_klass);
    return this_klass;

}

分享到:
评论

相关推荐

    ClassFileParser:它是由库廷大学为软件工程专业的学生提供的基于代码的代码创建的

    《深入解析ClassFileParser:库廷大学软件工程实践之精华》 在软件工程的学习与实践中,理解并解析Java字节码是至关重要的技能之一。库廷大学为了培养学生的这一能力,特别开发了一款名为ClassFileParser的工具。...

    jvm-class-file-parser:一个 Rust 库 + 用于解析 JVM 类文件的程序

    jvm 类文件解析器 这是一个(部分实现的)Rust 库和用于解析 JVM 类文件的程序。 $ cargo +nightly run classes/Dummy.class Classfile /home/chris/Code/jvm-class-file-parser/classes/Dummy.class ...

    MATLAB中的紧束缚模型求解器.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    模型量化校准数据集-ImageNet2012分类图片100张

    从ImageNet2012分类数据集中选取的100张图片,用于对常见分类模型进行量化。 数据集介绍 数据背景: 静态离线量化方法需要少量校准数据,这个数据集用于量化演示示例。 数据来源: 基于Imagenet2012测试数据集,取前100张图片和标签作为本数据集。

    ### 【计算机组成原理】计算机发展历程与关键技术解析:从冯·诺依曼架构到量子计算的未来展望

    内容概要:本文详细介绍了计算机的发展历程及其核心组成部分,从早期计算工具的演进到现代计算机的诞生,重点探讨了冯·诺依曼体系结构的重要性。文章回顾了从机械计算器、ENIAC到微处理器的科技进步,阐述了计算机五大组成部分(运算器、控制器、存储器、输入设备、输出设备)的功能与协作机制。同时,文中还讨论了操作系统、编程语言、数据库管理系统等软件层面的内容,以及量子计算和神经形态计算等前沿技术对未来计算机发展的影响。; 适合人群:计算机专业学生、计算机爱好者及对计算机技术感兴趣的读者。; 使用场景及目标:①帮助读者理解计算机硬件的基本组成和工作原理;②解释软件与硬件之间的协同关系;③介绍量子计算和神经形态计算等新兴技术的发展趋势及挑战。; 其他说明:掌握计算机组成原理有助于读者深入了解计算机系统的工作机制,培养硬件思维和系统思维,为后续学习操作系统、编译原理、计算机网络等课程打下坚实基础。同时,对于广大计算机爱好者而言,了解计算机组成原理可以让他们更好地理解计算机的运行机制,在使用计算机的过程中更加得心应手。

    中国移动2024年6G通感算智融合技术体系白皮书1.053页.pdf

    中国移动2024年6G通感算智融合技术体系白皮书1.053页.pdf

    汽车电子:MATLAB_开发电池管理系统SOC估算算法.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    通信工程分包合同.docx

    通信工程分包合同.docx

    基于Qt+C++实现的物联网景区地质灾害监测系统+源码+项目文档(毕业设计&课程设计&项目开发)

    基于Qt+C++实现的物联网景区地质灾害监测系统+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 本项目利用Zigbee协议搭建了专属物联网,搭建了以Cortex-A8为主核的本地网关,租用阿里云组建系统服务器,并建立了相关网站。监测中心站通过客户端监控易发灾害点数据,在灾害爆发前做好预防工作;普通用户可以通过网站查看各项数据。 基于Qt+C++实现的物联网景区地质灾害监测系统+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 本项目利用Zigbee协议搭建了专属物联网,搭建了以Cortex-A8为主核的本地网关,租用阿里云组建系统服务器,并建立了相关网站。监测中心站通过客户端监控易发灾害点数据,在灾害爆发前做好预防工作;普通用户可以通过网站查看各项数据

    CNC-控制器-STM32-开源项目

    CNC_控制器_STM32_开源项目

    世邦魏理仕:2022年北京房地产市场回顾与2023年展望.pdf

    世邦魏理仕:2022年北京房地产市场回顾与2023年展望

    科学发展观与建筑企业管理论文.docx

    科学发展观与建筑企业管理论文.docx

    Epson-L130-Series

    爱普生L130

    基于javaScript+Springboot+Vue实现的校园社团信息管理系统+源码+演示视频+项目文档(毕业设计&课程设计&项目开发)

    基于javaScript+Springboot+Vue实现的校园社团信息管理系统+源码+演示视频+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 园社团信息管理系统管理员功能有个人中心,学生管理,社长管理,社团分类管理,社团信息管理,加入社团管理,社团成员管理,社团活动管理,活动报名管理,系统管理等。社长添加社团,管理员审核社团,学生加入社团,社长审核社团。因而具有一定的实用性。 本站是一个B/S模式系统,采用Spring Boot框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得校园社团信息管理系统管理工作系统化、规范化。本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高校园社团信息管理系统管理效率。

    apk文件.zip

    apk文件

    JDK1.7及之前HashMap的put方法图解.png

    JDK1.7及之前HashMap的put方法图解

    珠宝鉴定:MATLAB高光谱成像在宝石内部包裹体分析中的实践.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    基于MATLAB_的无人机编队协同控制算法开发与半实物仿真.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    Epson-L301303.zip

    Epson_L301303.zip

Global site tag (gtag.js) - Google Analytics