Взглянув на это, кажется, что все типы выстраиваются в ряд (вы возвращаете VALUE и передаете ptr VALUE), поэтому я предполагаю, что операция mark неправильно маркирует объекты, а фаза подметания захватывает их вверх.
Возможно, помещая дочерние объекты в массив с правильной функцией маркера, вы защищаете свои объекты данных.
Это скорее теория, чем твердый ответ, но, возможно, с этого стоит начать. :)
Нет, по иронии судьбы, вернемся к копанию слишком глубоко в Ruby GC. Смотря вау некоторые рекрутеры. : D
- Правка -
Чтобы добавить к этому, я просто копался в gc.c и в строке 1098 точный тест, который вы хотите fail -
if (! (P-> as.basic.flags & FL_MARK))
Так что сделайте то, что вы должны в своей функции отметки, чтобы включить в свои флаги FL_MARK, чтобы уборщик не ... хм ... вас не охватил.