Таможенное распределение и Boehm GC - PullRequest
9 голосов
/ 02 августа 2011

В моем проекте компилятора «снова снова выключен» я реализовал замыкания как выделенную память с исполняемым префиксом.Таким образом, замыкание распределяется так:

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 хуки, обеспечивающие пользовательские распределения, подобные этой?

1 Ответ

3 голосов
/ 06 февраля 2012

Вы можете делать то, что вы хотите, с помощью финализатора - Boehm GC по-прежнему освобождает его, но у вас будет возможность заранее зафиксировать закрытие с помощью ops (0xCC на x86) и пометитьего страница неисполняема, если это возможно.

Однако финализаторы имеют снижение производительности, поэтому их не следует использовать легкомысленно.Boehm GC основан на алгоритме разметки, который сначала идентифицирует все фрагменты, которые должны быть освобождены , а не (mark.c), а затем освобождает все остальное сразу (reclaim.c).В вашем случае имеет смысл изменить процесс восстановления, чтобы также заполнить все свободное пространство в вашем исполняемом регионе операциями точек останова и пометить страницы как неисполняемые, поскольку они стали полностью пустыми.Это позволяет избежать финализаторов за счет разветвления библиотеки (я не смог найти для этого никакого механизма расширения).

Наконец, обратите внимание, что предотвращение выполнения является мерой глубокой защиты и не должно быть вашейтолько охранная охрана. Программирование, ориентированное на возврат может использоваться для выполнения произвольного кода с использованием неизменяемых исполняемых областей.

...