Mark frame info structs with rb_gc_mark_movable

Using rb_gc_mark_movable and a reference update function, we can make
frame infos movable in memory, and avoid pinning frame info backtraces.

```
require "objspace"
exceptions = []
GC.disable
50_000.times do
  begin
    raise "some exception"
  rescue => exception
    exception.backtrace_locations
    exceptions << exception
  end
end
GC.enable
GC.compact
p ObjectSpace.dump_all(output: :string).lines.grep(/"pinned":true/).count
```

Co-authored-by: Peter Zhu <peter@peterzhu.ca>
This commit is contained in:
Gannon McGibbon 2024-03-22 15:40:42 -05:00 коммит произвёл Peter Zhu
Родитель 4300c42a7e
Коммит 4bdb79618b
1 изменённых файлов: 9 добавлений и 1 удалений

Просмотреть файл

@ -134,7 +134,14 @@ static void
location_mark(void *ptr)
{
struct valued_frame_info *vfi = (struct valued_frame_info *)ptr;
rb_gc_mark(vfi->btobj);
rb_gc_mark_movable(vfi->btobj);
}
static void
location_ref_update(void *ptr)
{
struct valued_frame_info *vfi = ptr;
vfi->btobj = rb_gc_location(vfi->btobj);
}
static void
@ -150,6 +157,7 @@ static const rb_data_type_t location_data_type = {
location_mark,
RUBY_TYPED_DEFAULT_FREE,
NULL, // No external memory to report,
location_ref_update,
},
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
};