如何通过不同流程虚拟机的JIT编译器实现事件偷看?

时间:2015-06-29 20:48:55

标签: javascript java virtual-machine smalltalk jit

注意:这个问题是针对Smalltalk,Self,Javascript,Java,C#等语言的VM实现者提出的。

JIT编译器带来的常用功能是自动查看系统事件。这用于处理UI事件和触发GC。

通常这个事件偷看包括在框架构建(调用方法时)和循环回跳时进行检查。我想知道,

  

实施此检查的不同方法有哪些?它们的优点和缺点是什么?你知道任何描述这些技术的论文吗?

     

您能说出它是如何在特定虚拟机中实现的吗? (Pharo,HPS,HotSpot,V8,SpiderMonkey,CLR)

2 个答案:

答案 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处的计数器变为EBXset_my_customers_length(my_customers_length + 1)指令将跳转到检查例程零。如果发生任何这些情况,检查程序将必须辨别原因并采取相应行动。