2013-03-19 7 views
0

Копирование (генерация) сборка мусора обеспечивает наилучшую производительность любой формы автоматического управления памятью, но требует указания указателей на перемещенные куски данных. Это включено на языках, поддерживающих эту технологию управления памятью, путем отказа от арифметики указателя и обеспечения того, чтобы все указатели находились в начале идентифицируемых объектов.Копирование коллекции мусора сгенерированного кода

Если вы генерируете код во время выполнения с помощью JIT-компилятора, все выглядит немного сложнее, потому что обратные адреса в стеке вызовов указывают, а не начало кодовых блоков, но случайные местоположения внутри них, поэтому исправление проблема.

Как это обычно решается?

+0

Я бы сказал, что код проверен перед передачей в JIT. – leppie

ответ

1

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

Если вы настаиваете на перемещении машинного кода и фиксации стека, то - это. Я думаю: Подобно Mark-Compact, создайте «таблицу перерыва» (я понятия не имею, откуда это имя; «таблица перемещений» может быть более четкой), которая сообщает вам сумму, с которой вы должны настроить указатели на перемещенные объекты. Теперь пройдите по стеку для обратных адресов (конечно, для платформы), и исправьте их, если они ссылаются на перемещенный код. Вместо поиска точных совпадений найдите самый высокий адрес ниже адреса возврата, который вы сейчас заменяете. Вы можете проверить, действительно ли этот адрес ссылается на какой-то машинный код, который перемещается, глядя на размер объекта (в конце концов, у вас есть указатель на начало объекта). Этот подход невозможен для всех объектов по разным причинам.

Есть и другие причины, чтобы сделать что-то подобное. Некоторые компиляторы JIT имеют замену на стопку, что означает создание новой версии (например, более оптимизированной или менее оптимизированной) некоторого машинного кода и замены на нее всех вхождений старой версии. Это гораздо сложнее, чем исправление обратных адресов. Вы должны обеспечить, чтобы новая версия логически продолжалась, где старый был виден. Я не знаком с тем, как это реализовано, поэтому я не буду вдаваться в подробности.

Смежные вопросы