Я разрабатываю систему, которая заранее компилирует байт-код CIL. Чтобы сохранить его относительно простым, а также сделать его очень переносимым, система будет выдавать исходный код C (однако со всеми конструкциями более высокого уровня, такими как разложение ООП) вместо машинного кода. Предполагается, что стандартный компилятор C для целевой платформы будет затем использоваться в этом коде для получения конечного продукта.
Изначально я намереваюсь использовать очень простой подход к сборке мусора, такой как stop-the-world. Однако, хотя приложение не требует выдающейся производительности, ему нужна достойная производительность, поэтому со временем может потребоваться замена GC.
Я думаю о том, чтобы в конечном итоге создать более сложный сборщик мусора, требующий какого-то барьера записи. Я рассмотрел подходы к SATB и маркировке карт, но я еще не готов планировать хороший сборщик мусора. Я просто не хочу стрелять себе в ногу из-за того, что вещь испускает исходный код C только для того, чтобы позже обнаружить, что эффективный барьер записи GC потребует встроенной сборки, в значительной степени побеждая цель испускания C.
Итак, мой вопрос: можно ли эффективно реализовать типичные барьеры записи в коде C? Можно предположить, что компилятор C имеет достойный оптимизатор. Также уже известно, что результирующий «исходный код» будет совершенно неразборчивым, поэтому ясность не имеет значения.
Я предполагаю, что - за счет еще большего раздувания исходных файлов - это, вероятно, можно сделать разумно, но я был бы признателен за слова людей, более опытных в проектировании GC и / или внутреннем устройстве компилятора.
1 ответ
Я предполагаю, что вам нужен точный сборщик мусора, перемещающий или копирующий поколения.
У вас может быть барьер записи в C; Например, в средах выполнения Ocaml и MELT есть сборщик мусора поколений с барьером записи. А qish - это глобальный копирующий сборщик мусора с барьером записи, работающий с C.
(Кстати, MELT - это предметно-ориентированный язык для расширения GCC, и он скомпилирован в C, точно так же, как вы хотите это сделать)
Более важная проблема заключается в том, как вы храните локальные указатели (и как GC знает о них), это точный аспект вашего GC. Возможно, вы захотите упаковать их в какую-то локальную структуру .... Но тогда может случиться так, что компилятор C (например, GCC) оптимизирует немного меньше.
Вы можете заглянуть в исходный код последних версий MONO, у них есть GC с копированием поколений. Также загляните в Chicken Scheme (также генерирующую код C).
Обратите внимание, что ваш генератор кода C необходимо будет изменить, чтобы он соответствовал какой-либо (или вашей) конкретной реализации GC (поскольку каждый GC имеет несколько разные инварианты и ожидания). Позаботьтесь также о хвостовой рекурсии (некоторые компиляторы C , особенно последние версии GCC , может оптимизировать их в ограниченных случаях).
В Qish, MELT или Ocaml барьер записи (на стороне C) реализуется некоторыми макросами (или встроенными функциями), вызываемыми для каждого указателя, к которому прикоснулись. Детали зависят от реализации. Ваш генератор кода C позаботится о них.
Будьте осторожны, так как многопоточный сборщик мусора сложно спроектировать, а отладка сборщика мусора, даже простого, занимает много времени и является сложной задачей.
Похожие вопросы
Новые вопросы
garbage-collection
Сборка мусора (GC) - это форма автоматического управления памятью, которая пытается вернуть мусор или память, занятую объектами, которые больше не используются программой.