注意:这个问题是针对Smalltalk,Self,Javascript,Java,C#等语言的VM实现者提出的。
JIT编译器带来的常用功能是自动查看系统事件。这用于处理UI事件和触发GC。
通常这个事件偷看包括在框架构建(调用方法时)和循环回跳时进行检查。我想知道,
实施此检查的不同方法有哪些?它们的优点和缺点是什么?你知道任何描述这些技术的论文吗?
您能说出它是如何在特定虚拟机中实现的吗? (Pharo,HPS,HotSpot,V8,SpiderMonkey,CLR)
答案 0 :(得分:2)
从我读过的内容来看,我猜每个实现都会做一些以下的变化:
专门为计数分配硬件寄存器,并在达到某个阈值时窥视。 上涨:支票非常快。缺点:你丢失了一个可以更好地使用的寄存器,计数可能是不精确/无意义的。
定时发出定时信号(如何实现?)然后:
stack_limit
变量,然后在框架构建和回跳答案 1 :(得分:2)
正如您和@melkyades所提到的,其中一种方法是分配一些寄存器(例如EBX
),通常从图像初始化到某个最大值。然后,JIT在每个nativized方法中内联代码,在方法开始时和在其中发生的每个backjump(#whileTrue:/False:
)中递减计数器(BTW,这就是为什么有一个backjump字节码。)代码,当计数器变为零时,检查三件事:(1)是否有任何OS事件要查看,(2)对象内存的状态(可能最终触发一些GC动作)和(3)堆栈指针(预测堆栈结束状况。)
可以实现的一个有趣技巧如下:
@1: call CheckEventsEtc
...
cmp ESP, [TOS]
dec EBX
jbe @1
鉴于dec
未修改Carry标志,如果jbe
变得太小或ESP
处的计数器变为EBX
,set_my_customers_length(my_customers_length + 1)
指令将跳转到检查例程零。如果发生任何这些情况,检查程序将必须辨别原因并采取相应行动。