Skip to content

Commit 16af727

Browse files
authored
Avoid taking vm barrier in heap_prepare() (ruby#14425)
We can avoid taking this barrier if we're not incremental marking or lazy sweeping. I found this was taking a significant amount of samples when profiling `Psych.load` in multiple ractors due to the vm barrier. With this change, we get significant improvements in ractor benchmarks that allocate lots of objects. -- Psych.load benchmark -- ``` Before: After: r: itr: time r: itr: time 0 #1: 960ms 0 #1: 943ms 0 ruby#2: 979ms 0 ruby#2: 939ms 0 ruby#3: 968ms 0 ruby#3: 948ms 0 ruby#4: 963ms 0 ruby#4: 946ms 0 ruby#5: 964ms 0 ruby#5: 944ms 1 #1: 947ms 1 #1: 940ms 1 ruby#2: 950ms 1 ruby#2: 947ms 1 ruby#3: 962ms 1 ruby#3: 950ms 1 ruby#4: 947ms 1 ruby#4: 945ms 1 ruby#5: 947ms 1 ruby#5: 943ms 2 #1: 1131ms 2 #1: 1005ms 2 ruby#2: 1153ms 2 ruby#2: 996ms 2 ruby#3: 1155ms 2 ruby#3: 1003ms 2 ruby#4: 1205ms 2 ruby#4: 1012ms 2 ruby#5: 1179ms 2 ruby#5: 1012ms 4 #1: 1555ms 4 #1: 1209ms 4 ruby#2: 1509ms 4 ruby#2: 1244ms 4 ruby#3: 1529ms 4 ruby#3: 1254ms 4 ruby#4: 1512ms 4 ruby#4: 1267ms 4 ruby#5: 1513ms 4 ruby#5: 1245ms 6 #1: 2122ms 6 #1: 1584ms 6 ruby#2: 2080ms 6 ruby#2: 1532ms 6 ruby#3: 2079ms 6 ruby#3: 1476ms 6 ruby#4: 2021ms 6 ruby#4: 1463ms 6 ruby#5: 1999ms 6 ruby#5: 1461ms 8 #1: 2741ms 8 #1: 1630ms 8 ruby#2: 2711ms 8 ruby#2: 1632ms 8 ruby#3: 2688ms 8 ruby#3: 1654ms 8 ruby#4: 2641ms 8 ruby#4: 1684ms 8 ruby#5: 2656ms 8 ruby#5: 1752ms ```
1 parent 505fcf5 commit 16af727

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

gc/default/default.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,9 @@ total_final_slots_count(rb_objspace_t *objspace)
985985
#define GC_INCREMENTAL_SWEEP_SLOT_COUNT 2048
986986
#define GC_INCREMENTAL_SWEEP_POOL_SLOT_COUNT 1024
987987
#define is_lazy_sweeping(objspace) (GC_ENABLE_LAZY_SWEEP && has_sweeping_pages(objspace))
988+
/* In lazy sweeping or the previous incremental marking finished and did not yield a free page. */
989+
#define needs_continue_sweeping(objspace, heap) \
990+
((heap)->free_pages == NULL && is_lazy_sweeping(objspace))
988991

989992
#if SIZEOF_LONG == SIZEOF_VOIDP
990993
# define obj_id_to_ref(objid) ((objid) ^ FIXNUM_FLAG) /* unset FIXNUM_FLAG */
@@ -2022,7 +2025,10 @@ static void
20222025
gc_continue(rb_objspace_t *objspace, rb_heap_t *heap)
20232026
{
20242027
unsigned int lock_lev;
2025-
gc_enter(objspace, gc_enter_event_continue, &lock_lev);
2028+
bool needs_gc = is_incremental_marking(objspace) || needs_continue_sweeping(objspace, heap);
2029+
if (!needs_gc) return;
2030+
2031+
gc_enter(objspace, gc_enter_event_continue, &lock_lev); // takes vm barrier, try to avoid
20262032

20272033
/* Continue marking if in incremental marking. */
20282034
if (is_incremental_marking(objspace)) {
@@ -2031,9 +2037,7 @@ gc_continue(rb_objspace_t *objspace, rb_heap_t *heap)
20312037
}
20322038
}
20332039

2034-
/* Continue sweeping if in lazy sweeping or the previous incremental
2035-
* marking finished and did not yield a free page. */
2036-
if (heap->free_pages == NULL && is_lazy_sweeping(objspace)) {
2040+
if (needs_continue_sweeping(objspace, heap)) {
20372041
gc_sweep_continue(objspace, heap);
20382042
}
20392043

0 commit comments

Comments
 (0)