mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Make rb_gc_impl_writebarrier_remember Ractor-safe
rb_gc_impl_writebarrier_remember is not Ractor safe because it writes to bitmaps and also pushes onto the mark stack during incremental marking. We should acquire the VM lock to prevent race conditions. In the case that the object is not old, there is no performance impact. However, we can see a performance impact in this microbenchmark where the object is old: 4.times.map do Ractor.new do ary = [] 3.times { GC.start } 10_000_000.times do |i| ary.push(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) ary.clear end end end.map(&:value) Before: Time (mean ± σ): 682.4 ms ± 5.1 ms [User: 2564.8 ms, System: 16.0 ms] After: Time (mean ± σ): 5.522 s ± 0.096 s [User: 8.237 s, System: 7.931 s] Co-Authored-By: Luke Gruber <luke.gruber@shopify.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
This commit is contained in:
parent
0ba488d7f5
commit
e639e5fd1a
1 changed files with 12 additions and 8 deletions
|
@ -6110,16 +6110,20 @@ rb_gc_impl_writebarrier_remember(void *objspace_ptr, VALUE obj)
|
|||
|
||||
gc_report(1, objspace, "rb_gc_writebarrier_remember: %s\n", rb_obj_info(obj));
|
||||
|
||||
if (is_incremental_marking(objspace) || RVALUE_OLD_P(objspace, obj)) {
|
||||
int lev = RB_GC_VM_LOCK_NO_BARRIER();
|
||||
{
|
||||
if (is_incremental_marking(objspace)) {
|
||||
if (RVALUE_BLACK_P(objspace, obj)) {
|
||||
gc_grey(objspace, obj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (RVALUE_OLD_P(objspace, obj)) {
|
||||
else if (RVALUE_OLD_P(objspace, obj)) {
|
||||
rgengc_remember(objspace, obj);
|
||||
}
|
||||
}
|
||||
RB_GC_VM_UNLOCK_NO_BARRIER(lev);
|
||||
}
|
||||
}
|
||||
|
||||
struct rb_gc_object_metadata_names {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue