@@ -37,12 +37,23 @@ void IO_Event_Profiler_Call_free(struct IO_Event_Profiler_Call *call) {
3737static void IO_Event_Profiler_mark (void * ptr ) {
3838 struct IO_Event_Profiler * profiler = (struct IO_Event_Profiler * )ptr ;
3939
40- rb_gc_mark (profiler -> self );
40+ rb_gc_mark_movable (profiler -> self );
4141
4242 // If `klass` is stored as a VALUE in calls, we need to mark them here:
4343 for (size_t i = 0 ; i < profiler -> calls .limit ; i += 1 ) {
4444 struct IO_Event_Profiler_Call * call = profiler -> calls .base [i ];
45- rb_gc_mark (call -> klass );
45+ rb_gc_mark_movable (call -> klass );
46+ }
47+ }
48+
49+ static void IO_Event_Profiler_compact (void * ptr ) {
50+ struct IO_Event_Profiler * profiler = (struct IO_Event_Profiler * )ptr ;
51+ profiler -> self = rb_gc_location (profiler -> self );
52+
53+ // If `klass` is stored as a VALUE in calls, we need to update their locations here:
54+ for (size_t i = 0 ; i < profiler -> calls .limit ; i += 1 ) {
55+ struct IO_Event_Profiler_Call * call = profiler -> calls .base [i ];
56+ call -> klass = rb_gc_location (call -> klass );
4657 }
4758}
4859
@@ -54,13 +65,20 @@ static void IO_Event_Profiler_free(void *ptr) {
5465 free (profiler );
5566}
5667
68+ static size_t IO_Event_Profiler_memsize (const void * ptr ) {
69+ const struct IO_Event_Profiler * profiler = (const struct IO_Event_Profiler * )ptr ;
70+ return sizeof (* profiler ) + IO_Event_Array_memory_size (& profiler -> calls );
71+ }
72+
5773const rb_data_type_t IO_Event_Profiler_Type = {
5874 .wrap_struct_name = "IO::Event::Profiler" ,
5975 .function = {
6076 .dmark = IO_Event_Profiler_mark ,
77+ .dcompact = IO_Event_Profiler_compact ,
6178 .dfree = IO_Event_Profiler_free ,
79+ .dsize = IO_Event_Profiler_memsize ,
6280 },
63- .flags = RUBY_TYPED_FREE_IMMEDIATELY ,
81+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED ,
6482};
6583
6684VALUE IO_Event_Profiler_allocate (VALUE klass ) {
0 commit comments