В моем проекте компилятора «снова снова выключен» я реализовал замыкания как выделенную память с исполняемым префиксом.Таким образом, замыкание распределяется так:
c = make_closure(code_ptr, env_size, env_data);
c
- указатель на блок выделенной памяти, который выглядит следующим образом:
movl $closure_call, %eax
call *%eax
.align 4
; size of environment
; environment data
; pointer to closure code
closure_call - вспомогательная функция, котораяпросматривает адрес, последний помещенный в стек, и использует его для поиска данных замыкания и указателя кода.Boehm GC используется для общего управления памятью, и когда на закрытие больше нет ссылок, он может быть освобожден GC.
В любом случае эта выделенная память должна быть помечена как исполняемая;фактически целые страницы, которые он охватывает, помечаются.Когда замыкания создаются и освобождаются, все больше и больше памяти в процессе будет исполняемым.
По соображениям защитного программирования я бы предпочел минимизировать количество исполняемой кучи.Мой план состоит в том, чтобы попытаться сохранить все замыкания вместе на одной и той же странице (страницах) и распределять и освобождать исполняемые страницы по мере необходимости;т.е. реализовать пользовательский распределитель для замыканий.(Это проще, если все замыкания имеют одинаковый размер; поэтому первым шагом является перемещение данных среды в отдельное неисполняемое распределение, которым можно нормально управлять. Это также имеет смысл в защитном программировании.)
Ноостающийся вопрос - GC.Бем уже делает это!Я хочу как-то рассказать Бему о моих пользовательских распределениях и попросить Бома сообщить мне, когда они могут быть GC'd, но оставить это на мое усмотрение, чтобы освободить их.
Так что мой вопросесть ли в Boehm хуки, обеспечивающие пользовательские распределения, подобные этой?