4.4 常量池 java虚拟机指令并不依赖类.接口.类实例或者数组的运行时布局.相反,指令依靠常量池中的符号信息. 所有的常量池条目都有如下的通用结构: cp_info { u1 tag; u1 info[]; } 常量池表中的每一个项目是以1比特的标识位开始,指示是哪种cp_info条目.info数组的内容由标志位来决定.有效的标识以及对应的值见表4.4-A.每个标识位后面必须跟2个或更多字节,这些字节给出了这些指定常量的信息.额外信息的格式由标识值来决定. 表4.4-A 常量池标识 Cons…
4.7 属性 属性用于class文件格式中的ClassFile,field_info,method_info和Code_attribute结构. 所有的属性都是下面的格式: attribute_info { u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length]; } 对于所有的属性,attribute_name_index是类文件常量池中有效的16位索引.在这个索引位置的常量池条目必须是CONSTANT_U…
第四章 class文件格式 本章介绍了java虚拟机的class文件格式.每一个class文件包含一个单独的类或者接口的定义.虽然类和接口不一定都定义在文件中(比如类和接口亦可以通过类加载器直接生成),我们将通俗地将类或接口的任何有效表示称为class文件格式.class文件是由8位的字节流组成.所有16位,32位和64位的数字都是分别通过读取两个.四个和八个连续的8位字节来构成.多字节的数据使用大端模式存储的,也就是高字节在前.在java se平台,这个格式由接口java.io.DataInp…
4.7.1 定义和命名新属性 允许编译器定义和发布的class文件在class文件结构体.field_info结构体.method_info结构体和Code结构体中的attributes表中包含新的属性.允许java虚拟机识别和使用attributes表中的新属性.但是,任何没有在class文件规范中定义的属性都不能影响class文件的语义.java虚拟机的实现需要忽略它们不能识别的属性. 例如,允许定义一个新属性来支持特定供应商的调试.因为java虚拟要需要忽略它们不能识别的属性,为特殊jav…
4.5 字段 字段使用field_info结构来描述. 在同一个class文件中的两个字段不能有相同的名称和描述符. 结构的格式如下: field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; } field_info结构中的项目如下: access_flags access_flags的值是…
4.7.5 Exceptions 属性 Exceptions 属性是一个变长属性,它位于 method_info(§4.6)结构的属性表中. Exceptions 属性指出了一个方法需要检查的可能抛出的异常.一个 method_info 结构中最多只能有一个 Exceptions 属性. Exceptions 属性格式如下: Exceptions_attribute { u2 attribute_name_index; u4 attribute_length; u2 number_of_exce…
4.7.4 StackMapTable 属性 StackMapTable 属性是一个变长属性,位于 Code(§4.7.3)属性的属性表中.这个属性会在虚拟机类加载的类型阶段(§4.10.1)被使用. StackMapTable 属性包含 0 至多个栈映射帧(Stack Map Frames),每个栈映射帧都显式或隐式地指定了一个字节码偏移量,用于表示局部变量表和操作数栈的验证类型(Verification Types §4.10.1). 类型检测器(Type Checker)会检查和处理目标方…
本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述某个特定的虚拟机实现. 要正确实现一个Java虚拟机,你只需要能够读取class文件的格式并正确执行其中指定的操作.具体的实现并不是java虚拟机规范的一部分,因为它们会限制实现者的创造力.比如,运行时数据区域的内存布局,垃圾回收使用的算法,以及任何的java虚拟机指令的内部优化(如:转换为机器码)…
2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区域随着线程的创建而创建,随着线程的退出而销毁. 2.5.1 pc寄存器 java虚拟机支持多个线程同时执行.每个线程拥有自己的pc(program counter)寄存器.在任何时刻,一个线程只会执行一个方法,即线程的当前方法.如果执行的方法不是本地(native)方法,pc寄存器包含当前正在执行的…
3.3 算术运算 java虚拟机通常在操作数栈上进行算术运算(例外情况是iinc指令,它直接增加一个局部变量的值).例如下面的align2grain()方法,它的作用是将int值对齐到2的指定次幂: int align2grain(int i, int grain) { return ((i + grain-1) & ~(grain-1)); } 算术运算的操作数是从操作数栈中弹出的,运算结果会压回操作数栈.因此,算术子计算的结果可以作为嵌套计算的操作数.例如.~(grain-1)的计算结果就是…