Skip to content

Commit 8f1db03

Browse files
committed
gc: remove atomic operations on bitmaps
1 parent f1a8b7b commit 8f1db03

1 file changed

Lines changed: 15 additions & 44 deletions

File tree

gc/default/default.c

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,6 @@ struct heap_page {
827827
unsigned int has_remembered_objects : 1;
828828
unsigned int has_uncollectible_wb_unprotected_objects : 1;
829829
} flags;
830-
bool needs_setup_mark_bits;
831830
rb_atomic_t before_sweep; // bool
832831

833832
rb_heap_t *heap;
@@ -920,12 +919,6 @@ heap_page_in_global_empty_pages_pool(rb_objspace_t *objspace, struct heap_page *
920919
#define MARK_IN_BITMAP(bits, p) ((bits)[BITMAP_INDEX(p)] = (bits)[BITMAP_INDEX(p)] | BITMAP_BIT(p))
921920
#define CLEAR_IN_BITMAP(bits, p) ((bits)[BITMAP_INDEX(p)] = (bits)[BITMAP_INDEX(p)] & ~BITMAP_BIT(p))
922921

923-
/* Atomic bitmap operations for use during parallel sweep, where the sweep
924-
* thread and mutator write barriers may modify different bits in the same
925-
* bitmap word concurrently. */
926-
#define ATOMIC_MARK_IN_BITMAP(bits, p) RUBY_ATOMIC_VALUE_OR((bits)[BITMAP_INDEX(p)], BITMAP_BIT(p))
927-
#define ATOMIC_CLEAR_IN_BITMAP(bits, p) RUBY_ATOMIC_VALUE_AND((bits)[BITMAP_INDEX(p)], ~BITMAP_BIT(p))
928-
929922
/* getting bitmap */
930923
#define GET_HEAP_MARK_BITS(x) (&GET_HEAP_PAGE(x)->mark_bits[0])
931924
#define GET_HEAP_PINNED_BITS(x) (&GET_HEAP_PAGE(x)->pinned_bits[0])
@@ -959,10 +952,10 @@ RVALUE_AGE_SET_BITMAP(VALUE obj, int age)
959952

960953
/* Use atomic operations because the sweep thread may concurrently clear
961954
* age bits for dead objects in the same bitmap word. */
962-
if (age & 1) { RUBY_ATOMIC_VALUE_OR(age_bits[idx], mask); }
963-
else { RUBY_ATOMIC_VALUE_AND(age_bits[idx], ~mask); }
964-
if (age & 2) { RUBY_ATOMIC_VALUE_OR(age_bits[idx + 1], mask); }
965-
else { RUBY_ATOMIC_VALUE_AND(age_bits[idx + 1], ~mask); }
955+
if (age & 1) { age_bits[idx] |= mask; }
956+
else { age_bits[idx] &= ~mask; }
957+
if (age & 2) { age_bits[idx + 1] |= mask; }
958+
else { age_bits[idx + 1] &= ~mask; }
966959
}
967960

968961
static void
@@ -2599,7 +2592,7 @@ newobj_init(VALUE klass, VALUE flags, int wb_protected, rb_objspace_t *objspace,
25992592
#endif
26002593

26012594
if (RB_UNLIKELY(wb_protected == FALSE)) {
2602-
ATOMIC_MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
2595+
MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
26032596
}
26042597

26052598
#if RGENGC_PROFILE
@@ -4112,7 +4105,7 @@ deferred_free(rb_objspace_t *objspace, VALUE obj)
41124105

41134106
// Clear bits for the page that was swept by the background thread.
41144107
static inline void
4115-
gc_post_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_page, bool force_setup_mark_bits)
4108+
gc_post_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_page)
41164109
{
41174110
GC_ASSERT(sweep_page->heap == heap);
41184111

@@ -4154,23 +4147,14 @@ gc_post_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *s
41544147
bits_t *age_bits = sweep_page->age_bits;
41554148
for (int i = 0; i < bitmap_plane_count; i++) {
41564149
bits_t unmarked = ~bits[i] & slot_mask;
4157-
RUBY_ATOMIC_VALUE_AND(wb_unprotected_bits[i], ~unmarked);
4158-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2], ~unmarked);
4159-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2 + 1], ~unmarked);
4150+
wb_unprotected_bits[i] &= ~unmarked;
4151+
age_bits[i * 2] &= ~unmarked;
4152+
age_bits[i * 2 + 1] &= ~unmarked;
41604153
}
41614154
}
41624155

41634156
if (!heap->compact_cursor) {
4164-
if (objspace->background_sweep_mode && !force_setup_mark_bits) {
4165-
/* Defer gc_setup_mark_bits to gc_sweep_finish on the GC thread,
4166-
* because it overwrites mark_bits which would race with mutator
4167-
* write barriers for objects on the same page. */
4168-
sweep_page->needs_setup_mark_bits = true;
4169-
}
4170-
else {
4171-
gc_setup_mark_bits(sweep_page);
4172-
sweep_page->needs_setup_mark_bits = false;
4173-
}
4157+
gc_setup_mark_bits(sweep_page);
41744158
}
41754159

41764160
if (RUBY_ATOMIC_PTR_LOAD(heap_pages_deferred_final) && !finalizing) {
@@ -4228,9 +4212,9 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
42284212
bits_t *age_bits = sweep_page->age_bits;
42294213
for (int i = 0; i < bitmap_plane_count; i++) {
42304214
bits_t unmarked = ~bits[i] & slot_mask;
4231-
RUBY_ATOMIC_VALUE_AND(wb_unprotected_bits[i], ~unmarked);
4232-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2], ~unmarked);
4233-
RUBY_ATOMIC_VALUE_AND(age_bits[i * 2 + 1], ~unmarked);
4215+
wb_unprotected_bits[i] &= ~unmarked;
4216+
age_bits[i * 2] &= ~unmarked;
4217+
age_bits[i * 2 + 1] &= ~unmarked;
42344218
}
42354219
}
42364220

@@ -4975,19 +4959,6 @@ gc_sweep_finish(rb_objspace_t *objspace)
49754959

49764960
objspace->use_background_sweep_thread = false;
49774961

4978-
/* Run deferred gc_setup_mark_bits for pages swept by the background thread.
4979-
* This must run on the GC thread to avoid racing with mutator write barriers
4980-
* that modify mark_bits and uncollectible_bits. */
4981-
for (int i = 0; i < HEAP_COUNT; i++) {
4982-
struct heap_page *page;
4983-
ccan_list_for_each(&heaps[i].pages, page, page_node) {
4984-
if (page->needs_setup_mark_bits) {
4985-
gc_setup_mark_bits(page);
4986-
page->needs_setup_mark_bits = false;
4987-
}
4988-
}
4989-
}
4990-
49914962
gc_prof_set_heap_info(objspace);
49924963
heap_pages_free_unused_pages(objspace);
49934964

@@ -5172,7 +5143,7 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
51725143
GC_ASSERT(sweep_page->pre_deferred_free_slots == 0);
51735144
}
51745145
else {
5175-
gc_post_sweep_page(objspace, heap, sweep_page, false); // clear bits
5146+
gc_post_sweep_page(objspace, heap, sweep_page); // clear bits
51765147
// Process deferred free objects
51775148
unsigned short deferred_free_freed = 0;
51785149
unsigned short deferred_to_free = sweep_page->pre_deferred_free_slots;
@@ -7653,7 +7624,7 @@ rb_gc_impl_writebarrier_unprotect(void *objspace_ptr, VALUE obj)
76537624
}
76547625

76557626
RB_DEBUG_COUNTER_INC(obj_wb_unprotect);
7656-
ATOMIC_MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
7627+
MARK_IN_BITMAP(GET_HEAP_WB_UNPROTECTED_BITS(obj), obj);
76577628
}
76587629
RB_GC_VM_UNLOCK_NO_BARRIER(lev);
76597630
}

0 commit comments

Comments
 (0)