Chapter 2. The Structure of the Java Virtual Machine阅读笔记


第二章. Java虚拟机的结构

这篇文章定义了一个抽象的java虚拟机。不包含任何的具体实现。
为了正确地实现一个java虚拟机,你只需要正确地解析class文件并且正确地执行文件定义的操作。不属于java虚拟机定义的实现细节将不必要地限制实现者的创造力。比如,运行时数据区的内存布局,使用的垃圾回收算法,以及任何对java虚拟机指令的优化(比如,将它们翻译成机器代码)都由实现者自行决定。
本规范所有对Unicode的引用都针对Unicode6.0.0版本。 http://www.unicode.org/.

2.1 Class文件格式

JVM执行的代码使用一种硬件,操作系统独立的二进制格式,一般(不是必须)存放在一个叫做class的文件格式中。class文件精确地定义了如何表示一个类或者接口,包括字节序等细节。

2.2 数据类型

JVM操作两种类型的数据,primitive和reference。
JVM期望在run time之前完成几乎所有的类型检查,一般由编译器完成而不是JVM。primitive的值不需要被标记或者在运行时被检查来确认它们的类型,或者与reference类型的值区分。取而代之,通过使用为了操作特定类型而设计的JVM指令集来区分操作数的类型。比如,iadd, ladd, fadd, dadd。
JVM明确支持对象。对象是动态分配的class实例或者数组。指向对象的引用被认为是JVM的reference类型。引用类型的值可以认为是指向对象的指针。对一个对象的多个引用是可以存在的。

2.3 Primitive类型与值

JVM支持三种primitive类型,分别是数字类型,布尔类型和returnAddress类型。
数字类型包括整数和浮点数。
整数包括:

  • byte,其值为8位有符号的二进制补码(Two's complement)整数,默认值为0。
  • short,16位,0
  • int, 32位, 0
  • long, 64位,0
  • char, 16位无符号, UTF-16,默认值\u0000
    浮点数包括
  • float,float value set and float-extended-exponent value set, 默认值+0
  • double, double value set and double-extended-exponent value set, 默认值+0
    布尔类型,默认false
    returnAddress类型是指向JVM指令的操作码的指针。primitive类型中,只有returnAddress没有与java编成语言类型直接关联。

2.3.1 整数

  • byte: [-27~27-1]
  • char: [0, 28-1]

2.3.2 浮点数

IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-1985, New York).
IEEE 754: 正负数字,正负0,正负无穷,NaN
所有的JVM必须实现float value set和double value set。可以实现float-extended-exponent value sets和double-extended-exponent value set。
有限非零的浮点数的表示公式:s ? m ? 2(e ? N + 1)
s = +1 or -1
0 < m <= 2N
-(2K-1-2) <= e <= (2K-1-1)
N and K depend on the value set
normalized value: m >= 2N-1

Parameter float float-extended-exponent double double-extended-exponent
N 24 24 53 53
K 8 ≥ 11 11 ≥ 15
Emax +127 ≥ +1023 +1023 ≥ +16383
Emin -126 ≤ -1022 -1022 ≤ -16382

extended value set拥有更高的精度
float value set的元素正好是用IEEE 754可以表示的值,除了NaN(IEEE中有224-2个不同的NaN表示)。double value set同理。
float-extended-exponent value set与IEEE 754 single extended不是对应的,double同理。本规范不指定任何特定的对于float-point value sets的表示方式,除了float-point values必须可以被class文件格式表示。
float, float-extended-exponent, double, and double-extended-exponent value sets不是类型。使用float value set中的元素来表示float类型的一个值总是正确的。在特定的上下文,使用float-extended-exponent value set的元素作为float类型的值的实现是可以的。
除了NaNs,float-point value sets是有序(ordered)的。
+0 equals -0, 1.0/0.0 = +inf, 1.0/-0.0 = -inf
NaN is unordered。test for numerical equality is false when either operand is NaN

2.3.3 returnAddress

returnAddress类型被用于jsr, ret和jsr_w指令。没有对应的java编程类型。

2.3.4 boolean

JVM没有专用于操作boolean类型的指令。java编程语言中对boolean的操作在JVM中被转化为对JVM int类型的操作。
JVM支持boolean数组,使用newarray指令创建。boolean数组使用byte数组指令baload,bastore访问和修改。
Oracle的JVM实现中,对于boolean数组,每个boolean元素使用使用一个byte表示。
编译器将Java language的boolean类型映射为JVM的int类型。

2.4 Reference Type and Values