2010-09-11 2 views
1

Я читал статью «Сборщик мусора в неработоспособной среде» и задавался вопросом, как трудно было его реализовать. В документе описывается необходимость сбора всех адресов от процессора (в дополнение к стеку). Часть стека кажется интуитивной. Есть ли способ собирать адреса из регистров, кроме перечисления каждого регистра явно в сборке? Предположим x86_64 для POSIX-подобной системы, такой как linux или mac.Механизм сборщика мусора Boehm Weiser

SetJmp

+1

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

+0

Я не уверен, что ты прав, Ганс. Возможно, мы можем рассчитывать на структуру среды выполнения C для решения этой проблемы. Если мы вызываем неинтенсивную оболочку malloc, которая сбрасывает регистры в стек (flushrs), возможно, мы сможем использовать адрес любых локальных переменных (локальных для нашего malloc) и перемещаться выше в памяти, пока не нажмем адрес argv [0]. – SetJmp

ответ

2

С Сете и Вайзер фактически implemented their GC, то основной источник информации является исходным кодом этой реализации (это с открытым исходным кодом).

Чтобы получить значения регистра, вы можете подорвать функцию setjmp(), которая сохраняет копию регистров в пользовательской структуре (по крайней мере, те регистры, которые должны быть сохранены во всех вызовах функций). Но эта структура не стандартизирована (ее содержимое номинально непрозрачно), и setjmp() может быть специально обработан компилятором C, что делает его немного нежным, чтобы использовать что-либо кроме longjmp() (что уже довольно сложно, как есть). Часть встроенной сборки кажется намного проще и безопаснее.

Первая сложная часть реализации GC, по-видимому, способна надежно определить начало и конец стеков (обратите внимание на множественное число: могут быть потоки, каждая со своим собственным стеком). Это требует углубления в документированные детали OS ABI. Когда моя настольная система была машиной Alpha под управлением FreeBSD, реализация Boehm-Weiser не могла работать на ней (хотя она поддерживала Linux на одном процессоре).

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

0

Я думаю, что на x86_86 они используют инструкцию сборки flushrs, чтобы поместить регистры в стек. Я уверен, что кто-то из переполнения стека исправит меня, если это не так.

0

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

Мой собственный многопоточный GC похож на коллектор Boehm и более или менее стандартный C++ с небольшим количеством хаков (с использованием jmpbuf более или менее определенно работает) и немного менее агрессивной средой (без исключений). Но он прекращает мир благодаря сотрудничеству, что очень плохо: если у вас есть занятый CPU, ожидающие его ждут. Boehm использует сигналы или другие функции ОС, чтобы попытаться остановить потоки, но поддержка очень шелушащаяся.

Обратите внимание, что процессор Intel i64 имеет два стека на поток .. немного сложно объяснить этот тип вещей в целом.

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