进程虚拟机如何实现回调支持?

How do process virtual machines implement callback support?

序言:这个问题是作为 VM 实现者提出的,希望支持本机回调(更具体地说是 wndProc)。对于进程虚拟机,我指的是 Smalltalk、Java、Python 等

VM 通常会非常小心进入堆栈的内容。这是因为在 GC 期间,他们会将堆栈用作一组根,并且对于堆栈中的每个单词,他们必须知道它是否是指向对象的指针。

所以问题来了:在回调期间,VM 将一堆东西压入堆栈。这可能只是参数和 return 地址,但也可能包含更多内容。这是一个小方案,堆栈向上增长:

oop <- managed
oop <- managed
-------------- <- native code end
... bunch of native stuff ...
-------------- <- native code start
oop <- managed
oop <- managed

从输入回调后的那一刻起,作为回调程序员,您可以控制再次进入堆栈的内容。但问题是,你如何控制之前发生的事情?更具体地说,你如何检测本机代码启动限制?

我猜测VM对回调的种类有限制,只允许我们调用时到达的回调,所以VM可以节省当时堆栈的限制。那是对的吗?还有其他选择吗?我认为使用单独的堆栈也可能是一种解决方案,但我不确定对性能的影响。

我想我自己回答了。要点是回调不能随时到达(即异步)。原因如下。

回调是一种简单的用户编写的 C 风格函数,遵循调用约定。例如,在 windows 中,CALLBACK 类型表示 stdcall。这意味着回调只会保存一些寄存器(被调用者保存的)并且可能会覆盖其他寄存器(调用者保存的)。如果回调在任何时候到达,那么 运行 函数将不会准备好,并且调用者保存的寄存器可能会损坏。然后,唯一可以安全调用回调的时刻是同步调用,即在完成标注以确保正确保存上下文之后。

可能还有其他类型的回调(我正在考虑中断例程和调试代码)可以异步,但我认为要点已得到解答。