说明

翻译KVM的文档,只是为了个人学习以做记录.如果有翻译不周到的地方,请指出,我会修正的.

为何翻译该文档

此KVM不是目前特别火的Kernel-based Virtual Machine(一个开源的系统虚拟化模块).而是一个JAVA 的虚拟机.是J2ME cldc 的一个实现.其源码的难度比hotspot简单多了.因此,想通过研读KVM,以加深对hotspot的理解

64位支持

我们不要求编译器支持64位运算。然而,拥有一个64位的编译器使移植变得容易得多。

基础

如果编译器支持64位整数,那么应该在一个依赖于平台的包含文件中定义long64和ulong64类型。这两种类型的含义如下所示:

TABLE 7  –  64-bit types

Type

Description

long64

有符号的64位整数

ulong64

无符号的64位整数

您应该考虑将两个编译器常量之一BIG_ENDIAN或LITTLE_ENDIAN设置为非零值。如果您使用ava Code Compactor,则只需要这样做,但是KVM如果知道机器的字节序,则可以生成更好的代码

例如,使用GNU C编译器或Solaris C编译器,可以编写:

typedef long long long64; 
typedef unsigned long long ulong64;

使用微软Visual C/C++,你可以写:

typedef __int64 long64; 
typedef unsigned __int64 ulong64;

如果编译器不支持64位整数,必须将预处理器常量COMPILER_SUPPORTS_LONG设置为零。您必须定义一个BIG_ENDIAN或LITTLE_ENDIAN 有一个非零值。

long64和ulong64类型被定义为由两个字段组成的结构,每个字段都是一个无符号长单词,分别命名为high和low。如果您的机器是big-endian,则高字段是第一个;如果您的机器是little-endian,则低字段是第一个。

必须定义表8中所示的函数。如果平台支持浮点,则还必须定义表9中所示的函数。

这些函数中的任何一个都可以作为宏来实现。

TABLE 8  –  Implementing longs

函数

举例

long64 ll_mul(long64 a, long64 b);

a * b

long64 ll_div(long64 a, long64 b);

a / b

long64 ll_rem(long64 a, long64 b);

a % b

long64 ll_shl(long64 a, int b);

a << b

long64 ll_shr(long64 a, int b);

a >> b

long64 ll_ushr(long64 a, int b);

a >>> b

TABLE 9  –  Implementing both longs and floats

函数

举例

long64   float2ll(float f);

(long)f

long64   double2ll(double d);

(long)d

float    ll2float(long64 a);

(float)a

double   ll2double(long64 a);

(double)a

对齐

当Java类型long或double对象位于Java堆栈或常量池中时,其地址将是4的倍数。

一些硬件平台(如SPARC)要求64位类型对齐,以便其地址是8的倍数。

如果平台要求64位整数在8字节边界上对齐,请设置

#define NEED_LONG_ALIGNMENT 1

如果平台需要在8字节边界上对齐双精度浮点数,请设置

#define NEED_DOUBLE_ALIGNMENT 1

当这些值为0时,编译器可以生成更好的代码。

ps:

  1. 或者您的代码必须是严格的ANSI C标准
  2. 参见乔纳森·斯威夫特,《格列佛游记》,第一部分:到利利浦特的游记,了解big-endian和little-endian的争议