说明
翻译KVM的文档,只是为了个人学习以做记录.如果有翻译不周到的地方,请指出,我会修正的.
为何翻译该文档
此KVM不是目前特别火的Kernel-based Virtual Machine(一个开源的系统虚拟化模块).而是一个JAVA 的虚拟机.是J2ME cldc 的一个实现.其源码的难度比hotspot简单多了.因此,想通过研读KVM,以加深对hotspot的理解
64位支持
我们不要求编译器支持64位运算。然而,拥有一个64位的编译器使移植变得容易得多。
基础
如果编译器支持64位整数,那么应该在一个依赖于平台的包含文件中定义long64和ulong64类型。这两种类型的含义如下所示:
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中所示的函数。
这些函数中的任何一个都可以作为宏来实现。
函数
|
举例
|
---|---|
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
|
函数
|
举例
|
---|---|
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:
- 或者您的代码必须是严格的ANSI C标准
- 参见乔纳森·斯威夫特,《格列佛游记》,第一部分:到利利浦特的游记,了解big-endian和little-endian的争议