Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Compiler construction 自定义分配和Boehm GC_Compiler Construction_Garbage Collection_Closures_Boehm Gc - Fatal编程技术网

Compiler construction 自定义分配和Boehm GC

Compiler construction 自定义分配和Boehm GC,compiler-construction,garbage-collection,closures,boehm-gc,Compiler Construction,Garbage Collection,Closures,Boehm Gc,在我的开-关-关编译器项目中,我将闭包实现为带有可执行前缀的分配内存。因此,闭包的分配方式如下: c = make_closure(code_ptr, env_size, env_data); movl $closure_call, %eax call *%eax .align 4 ; size of environment ; environment data ; pointer to closure code c是指向已分配内存块的指针,如下所示: c = make_closure(co

在我的开-关-关编译器项目中,我将闭包实现为带有可执行前缀的分配内存。因此,闭包的分配方式如下:

c = make_closure(code_ptr, env_size, env_data);
movl $closure_call, %eax
call *%eax
.align 4
; size of environment
; environment data
; pointer to closure code
c
是指向已分配内存块的指针,如下所示:

c = make_closure(code_ptr, env_size, env_data);
movl $closure_call, %eax
call *%eax
.align 4
; size of environment
; environment data
; pointer to closure code
closure_调用是一个助手函数,它查看最近放置在堆栈上的地址,并使用它查找闭包数据和代码指针。Boehm GC用于一般内存管理,当闭包不再被引用时,它可以由GC解除分配

无论如何,这个分配的内存需要标记为可执行的;事实上,它跨越的整个页面都会被标记。随着闭包的创建和释放,进程中越来越多的堆内存将是可执行的

出于防御性编程的原因,我更愿意最小化可执行堆的数量。我的计划是尝试将所有闭包放在同一个页面上,并根据需要分配和取消分配可执行页面;i、 e.为闭包实现自定义分配器。(如果所有闭包的大小都相同,这就更容易了;因此,第一步是将环境数据移动到一个单独的、可以正常管理的不可执行的分配中。这也有防御性编程的意义。)

但剩下的问题是GC。博姆已经做到了!我想要的是告诉Boehm我的自定义分配,让Boehm告诉我什么时候可以进行GC'd,但让我来解除分配


所以我的问题是,Boehm中是否有这样的钩子提供自定义分配?

您可能可以使用a执行您想要的操作-Boehm GC仍然会解除分配它,但您事先有机会使用断点ops(x86上的0xCC)来memset闭包,并在可能的情况下将其页面标记为不可执行

但是,终结器有性能成本,因此不应轻率使用。Boehm GC基于标记扫描算法,该算法首先识别所有不应释放的块(mark.c),然后一次释放所有其他块(recall.c)。在您的情况下,修改回收过程以使用断点操作填充可执行区域中的所有可用空间,并在页面变为完全空时将其标记为非可执行页面是有意义的。这避免了终结器,代价是分叉库(我找不到任何扩展机制)


最后,请注意,执行预防是一种深入防御措施,不应该是您唯一的安全保护。可用于使用不可修改的可执行区域执行任意代码。

因此,使用终结器方法,效果是可执行分配将通过堆进行,但如果可能,释放后将返回非可执行?这是一个改进,尽管我们需要一个方法来跟踪页面上的其他可执行分配,以便知道何时重新标记它。断点操作的使用似乎与分配本身有点类似——我想,在可执行页面上用断点操作填充空闲空间是一种很好的做法。分叉GC的一个好处是,在标记阶段,您可以非常轻松地跟踪哪些页面上有可访问的对象(只需为每个可执行页面使用带有位的位图)。然后,您可以将从未到达的对象标记为不可执行。我不知道有什么方法可以使用终结器来做类似的事情,除了自己走参考图之外。我可以在每个页面上维护分配的可执行对象的数量。创建对象时递增,在对象的终结器中递减。如果一个对象跨越一个页面边界(只需要增加/减少两个页面),事情会变得有点棘手。这听起来是个不错的计划,是的。请记住,不一定要取消映射空页,因为下一页上块的分配元数据可能会落在当前页上。但是,您应该能够将它们标记为不可执行。