Shopify / liquid-c

Liquid performance extension in C.
MIT License
120 stars 25 forks source link

Support GC Compaction #182

Closed eightbitraptor closed 2 years ago

eightbitraptor commented 2 years ago

While attempting to enable GC.auto_compact=true on Shopify/shopify we ran into a crash Try to mark T_NONE object originating in document_body_entry_mark while trying to mark body->self

The crash can be seen in this buildkite build

Relevant log entries below:

<OBJ_INFO:gc_mark_ptr@gc.c:6713> 0x00007f8f53555840 [0 MP   ] T_NONE 
/usr/local/ruby/lib/ruby/3.1.0/socket.rb:452: [BUG] try to mark T_NONE object
ruby 3.1.2p20 (2022-04-12 revision f76e4d39fb) [x86_64-linux]
-- C level backtrace information -------------------------------------------
/usr/local/ruby/bin/ruby(rb_print_backtrace+0x11) [0x561c5ee924d8] vm_dump.c:759
/usr/local/ruby/bin/ruby(rb_vm_bugreport) vm_dump.c:1045
/usr/local/ruby/bin/ruby(bug_report_end+0x0) [0x561c5ef3f1af] error.c:798
/usr/local/ruby/bin/ruby(rb_bug_without_die) error.c:798
/usr/local/ruby/bin/ruby(die+0x0) [0x561c5ecb08d1] error.c:806
/usr/local/ruby/bin/ruby(rb_bug) error.c:808
/usr/local/ruby/bin/ruby(gc_mark_ptr+0x138) [0x561c5ecd2428] gc.c:6714
/tmp/bundle/ruby/3.1.0/bundler/gems/liquid-c-629377c93a7a/lib/liquid_c.so(document_body_entry_mark+0x8) [0x7f9136b2f119] document_body.h:37
/tmp/bundle/ruby/3.1.0/bundler/gems/liquid-c-629377c93a7a/lib/liquid_c.so(block_body_mark) block.c:47
/usr/local/ruby/bin/ruby(gc_mark_children+0x6e7) [0x561c5ecd3f37] gc.c:6967
/usr/local/ruby/bin/ruby(gc_mark_stacked_objects+0x31) [0x561c5ecd4c8d] gc.c:7071

Because the document body is stored as an ivar on the parse context a reference to it exists in the generic_iv_tbl. When the generic_iv_tbl_ gets compacted objects can get moved around on it and the ivar references will be updated correctly.

But the pointer on the document body body->self that refers to itself will not be updated this pointer will go invalid and cause the crash.

In order to prevent this issue (and similar in future), this PR implements compaction callbacks for all Ruby types defined in the native extension in order to fully support movement and reference updating during GC compaction.

eightbitraptor commented 2 years ago

Closed in favour of a much simpler fix in [#183]