为小型JITted代码分配内存

时间:2013-05-15 16:44:19

标签: multithreading memory-management jit

有没有办法在多线程程序中的JIT汇编程序的不同调用之间共享页面?

我正在构建一个小型JIT引擎。似乎JITting背后的基本原理很简单:mmap一些空间,将机器代码放入其中,mprotect它是可执行的,将代码块的开头强制转换为函数指针,这似乎是我工作系统所需要的一切。

但是,mmap / mprotect组合(以及Windows等效组合)仅适用于整个页面(这是否正确?如果不是,它会抛出整个问题)。这意味着每次JIT汇编程序运行时,它必须至少分配整页空间。这对于一次性处理几个大型函数甚至整个程序的JIT来说没什么大不了的,但我主要对处理非常短的代码片段感兴趣。生成的代码不会使用大部分分配的空间。

在单线程应用程序中,这不是问题。当它是JITter转向tun时,它可以mprotect代码缓冲到它的内容,因为知道代码当时没有运行。因此,空间可以继续用于连续功能,直到它实际上已满。不幸的是,假设或要求单线程现在看起来有点像上个世纪了。

在多线程应用程序中,动态创建的代码可能已在生成其他代码的同时运行。如果JITter尝试使用保护,它将破坏某些东西。处理这种情况有哪些选择?

到目前为止我考虑过的事情:

  • 忽略此问题并为每个过程分配一个新缓冲区。在实践中,需要数千次分配才能显着增加内存使用量,这可能会在桌面上正常运行。然而,从哲学角度来说,“搞砸它我们有很多硬件”和“没有人会强调这个系统”从设计的角度来看有点令人反感。

  • 使用写入+执行保护分配缓冲区。这似乎是一个明显的答案,但它给我一种不好的感觉,我没有经验可以证明(这比没有JIT,或者首先调用mprotect的程序更糟糕吗?) 。安全吗?

  • 让每个JITted函数尝试锁定其代码缓冲区。这(直观地)似乎可能会破坏性能,扩大代码大小,并且可能永久性地阻止JITter做任何事情,如果它是天真地完成的。

  • 让JITter可以随意优先访问代码缓冲区和mprotect,如果这会导致任何现有的JITted过程发生段错误,在信号处理程序中捕获它们并等待JITter完成。我不确定这实际上是可行的,但是......呃,这是一个想法。

我试过看看几个现有的JIT编译器的来源,但是大多数情况下它们都是庞大的系统,需要很长时间才能理解,我不明白,不是很小的例子有明确的答案(不是我不愿意阅读源代码,我只是无法从JavaScriptCore或V8获得我需要的信息;更简单的例子肯定是受欢迎的)。对于某些项目来说,似乎这种事情实际上可能是一个悬而未决的问题。

0 个答案:

没有答案