@@ -1594,7 +1594,7 @@ RVALUE_MARKED_ATOMIC(rb_objspace_t *objspace, VALUE obj)
15941594{
15951595 bits_t * bits = GET_HEAP_MARK_BITS (obj );
15961596 struct heap_page * page = GET_HEAP_PAGE (obj );
1597- bits_t word = __atomic_load_n ( & bits [SLOT_BITMAP_INDEX (page , obj )], __ATOMIC_SEQ_CST );
1597+ bits_t word = rbimpl_atomic_value_load (( VALUE * ) & bits [SLOT_BITMAP_INDEX (page , obj )], RBIMPL_ATOMIC_ACQUIRE );
15981598 return (word & SLOT_BITMAP_BIT (page , obj )) != 0 ;
15991599}
16001600
@@ -1946,7 +1946,7 @@ rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE ptr)
19461946 bool dead = false;
19471947
19481948 // Set to false/true by the ruby GC thread when entering/exiting GC, so shouldn't change throughout this call.
1949- rb_atomic_t use_sweep_thread = RUBY_ATOMIC_LOAD ( objspace -> use_background_sweep_thread );
1949+ rb_atomic_t use_sweep_thread = rbimpl_atomic_load ( & objspace -> use_background_sweep_thread , RBIMPL_ATOMIC_RELAXED );
19501950
19511951 if (!use_sweep_thread ) {
19521952 // It's not safe to read flags on an object if the sweep thread is running
@@ -1971,13 +1971,12 @@ rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE ptr)
19711971 if (!use_sweep_thread ) {
19721972 // The ruby GC thread or a user thread called us
19731973 bool marked = RVALUE_MARKED (objspace , ptr );
1974- GC_ASSERT (marked == RVALUE_MARKED_ATOMIC (objspace , ptr ));
1975- return during_lazy_sweep && !marked && RUBY_ATOMIC_LOAD (page -> before_sweep );
1974+ return during_lazy_sweep && !marked && rbimpl_atomic_load (& page -> before_sweep , RBIMPL_ATOMIC_RELAXED );
19761975 }
19771976 else if (during_lazy_sweep ) {
19781977 // we're currently lazy sweeping with the sweep thread
19791978 bool marked = RVALUE_MARKED_ATOMIC (objspace , ptr ); // load it atomically so it can't be re-ordered past the next atomic load
1980- bool before_sweep = RUBY_ATOMIC_LOAD ( page -> before_sweep );
1979+ rb_atomic_t before_sweep = rbimpl_atomic_load ( & page -> before_sweep , RBIMPL_ATOMIC_ACQUIRE );
19811980 bool is_garbage = !marked && before_sweep ;
19821981 if (is_garbage ) return true;
19831982 if (marked && before_sweep ) return false;
@@ -4132,7 +4131,7 @@ gc_post_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *s
41324131 GC_ASSERT (RUBY_ATOMIC_LOAD (sweep_page -> before_sweep ));
41334132 }
41344133#endif
4135- RUBY_ATOMIC_SET ( sweep_page -> before_sweep , 0 );
4134+ rbimpl_atomic_store ( & sweep_page -> before_sweep , 0 , RBIMPL_ATOMIC_RELEASE );
41364135
41374136 bits = sweep_page -> mark_bits ;
41384137
@@ -4186,7 +4185,7 @@ gc_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct gc_sweep_context
41864185 GC_ASSERT (RUBY_ATOMIC_LOAD (sweep_page -> before_sweep ));
41874186 }
41884187#endif
4189- RUBY_ATOMIC_SET ( sweep_page -> before_sweep , 0 );
4188+ rbimpl_atomic_store ( & sweep_page -> before_sweep , 0 , RBIMPL_ATOMIC_RELEASE );
41904189 sweep_page -> free_slots = 0 ;
41914190
41924191 p = (uintptr_t )sweep_page -> start ;
@@ -4607,7 +4606,7 @@ gc_pre_sweep_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pa
46074606static inline bool
46084607done_worker_incremental_sweep_steps_p (rb_objspace_t * objspace , rb_heap_t * heap )
46094608{
4610- if (ATOMIC_LOAD_RELAXED ( heap -> foreground_sweep_steps ) != heap -> background_sweep_steps ) {
4609+ if (rbimpl_atomic_load ( & heap -> foreground_sweep_steps , RBIMPL_ATOMIC_ACQUIRE ) != heap -> background_sweep_steps ) {
46114610 GC_ASSERT (ATOMIC_LOAD_RELAXED (heap -> foreground_sweep_steps ) > heap -> background_sweep_steps );
46124611 return true;
46134612 }
@@ -4942,7 +4941,7 @@ gc_sweep_start(rb_objspace_t *objspace)
49424941 (objspace -> profile .latest_gc_info & GPR_FLAG_METHOD ) == 0 &&
49434942 !(objspace -> hook_events & RUBY_INTERNAL_EVENT_FREEOBJ )) {
49444943
4945- RUBY_ATOMIC_SET ( objspace -> use_background_sweep_thread , true);
4944+ rbimpl_atomic_store ( & objspace -> use_background_sweep_thread , true, RBIMPL_ATOMIC_RELEASE );
49464945 psweep_debug (-1 , "[gc] gc_sweep_start: requesting sweep thread\n" );
49474946 sweep_lock_lock (& objspace -> sweep_lock );
49484947 {
@@ -4952,7 +4951,7 @@ gc_sweep_start(rb_objspace_t *objspace)
49524951 sweep_lock_unlock (& objspace -> sweep_lock );
49534952 }
49544953 else {
4955- RUBY_ATOMIC_SET ( objspace -> use_background_sweep_thread , false);
4954+ rbimpl_atomic_store ( & objspace -> use_background_sweep_thread , false, RBIMPL_ATOMIC_RELEASE );
49564955 psweep_debug (-1 , "[gc] gc_sweep_start: not using background sweep thread\n" );
49574956 }
49584957}
@@ -5011,17 +5010,16 @@ gc_sweep_finish(rb_objspace_t *objspace)
50115010 gc_report (1 , objspace , "gc_sweep_finish\n" );
50125011 psweep_debug (-1 , "[gc] gc_sweep_finish\n" );
50135012
5014- RUBY_ATOMIC_SET ( objspace -> use_background_sweep_thread , false);
5013+ rbimpl_atomic_store ( & objspace -> use_background_sweep_thread , false, RBIMPL_ATOMIC_RELEASE );
50155014
50165015 gc_prof_set_heap_info (objspace );
50175016 heap_pages_free_unused_pages (objspace );
50185017
50195018 for (int i = 0 ; i < HEAP_COUNT ; i ++ ) {
50205019 rb_heap_t * heap = & heaps [i ];
50215020
5022- #ifdef DEBUG_SWEEP_BOOKKEEPING
5021+ #if VM_CHECK_MODE > 0
50235022 {
5024- /* Assert that every page in this heap was swept. */
50255023 struct heap_page * page ;
50265024 ccan_list_for_each (& heap -> pages , page , page_node ) {
50275025 if (RUBY_ATOMIC_LOAD (page -> before_sweep )) {
@@ -5177,10 +5175,10 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
51775175#endif
51785176 psweep_debug (-2 , "[gc] gc_sweep_step heap:%p (%ld) use_sweep_thread:%d\n" , heap , heap - heaps , objspace -> use_background_sweep_thread );
51795177 bool sweep_rest = objspace -> sweep_rest ;
5180- bool use_bg_thread = objspace -> use_background_sweep_thread ;
5178+ bool use_sweep_thread = objspace -> use_background_sweep_thread ;
51815179
51825180 while (1 ) {
5183- bool free_in_user_thread_p = !use_bg_thread ;
5181+ bool free_in_user_thread_p = !use_sweep_thread ;
51845182 bool dequeued_unswept_page = false;
51855183 // NOTE: pages we dequeue from the sweep thread need to be AFTER the list of heap->free_pages so we don't free from pages
51865184 // we've allocated from since sweep started.
@@ -5219,39 +5217,25 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
52195217 if (deferred_to_free > 0 ) {
52205218 uintptr_t p = (uintptr_t )sweep_page -> start ;
52215219 bits_t * deferred_bits = sweep_page -> deferred_free_bits ;
5220+ int total_slots = sweep_page -> total_slots ;
52225221 short slot_size = sweep_page -> slot_size ;
5223- short slot_bits = slot_size / BASE_SLOT_SIZE ;
5224- bits_t slot_mask = heap -> slot_bits_mask ;
5225-
5226- int page_rvalue_count = sweep_page -> total_slots * slot_bits ;
5227- int bitmap_plane_count = CEILDIV (NUM_IN_PAGE (p ) + page_rvalue_count , BITS_BITLENGTH );
5228-
5229- // First plane: skip out-of-range slots at head of page
5230- bits_t bitset = deferred_bits [0 ];
5231- bitset >>= NUM_IN_PAGE (p );
5232- bitset &= slot_mask ;
5233- while (bitset ) {
5234- if (bitset & 1 ) {
5235- VALUE obj = (VALUE )p ;
5236- GC_ASSERT (GET_HEAP_PAGE (obj ) == sweep_page );
5237- if (deferred_free (objspace , obj )) {
5238- deferred_free_freed ++ ;
5239- }
5240- else {
5241- deferred_free_final_slots ++ ;
5242- }
5243- }
5244- p += slot_size ;
5245- bitset >>= slot_bits ;
5222+
5223+ int bitmap_plane_count = CEILDIV (total_slots , BITS_BITLENGTH );
5224+ int out_of_range_bits = total_slots % BITS_BITLENGTH ;
5225+ bits_t bitset ;
5226+
5227+ if (out_of_range_bits != 0 ) {
5228+ deferred_bits [bitmap_plane_count - 1 ] &= (((bits_t )1 << out_of_range_bits ) - 1 );
52465229 }
5247- p = (uintptr_t )sweep_page -> start + (BITS_BITLENGTH - NUM_IN_PAGE ((uintptr_t )sweep_page -> start )) * BASE_SLOT_SIZE ;
52485230
5249- for (int i = 1 ; i < bitmap_plane_count ; i ++ ) {
5250- bitset = deferred_bits [i ] & slot_mask ;
5231+ for (int i = 0 ; i < bitmap_plane_count ; i ++ ) {
5232+ bitset = deferred_bits [i ];
5233+ p = (uintptr_t )sweep_page -> start + (i * BITS_BITLENGTH * slot_size );
52515234 while (bitset ) {
52525235 if (bitset & 1 ) {
52535236 VALUE obj = (VALUE )p ;
52545237 GC_ASSERT (GET_HEAP_PAGE (obj ) == sweep_page );
5238+ GC_ASSERT (!RVALUE_MARKED (objspace , obj ));
52555239 if (deferred_free (objspace , obj )) {
52565240 deferred_free_freed ++ ;
52575241 }
@@ -5260,11 +5244,11 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
52605244 }
52615245 }
52625246 p += slot_size ;
5263- bitset >>= slot_bits ;
5247+ bitset >>= 1 ;
52645248 }
5265- p = (uintptr_t )sweep_page -> start + (BITS_BITLENGTH * (i + 1 ) - NUM_IN_PAGE ((uintptr_t )sweep_page -> start )) * BASE_SLOT_SIZE ;
52665249 }
52675250 }
5251+ GC_ASSERT (deferred_to_free == (deferred_free_freed + deferred_free_final_slots ));
52685252
52695253 ctx .final_slots = sweep_page -> pre_final_slots + deferred_free_final_slots ;
52705254 ctx .freed_slots = sweep_page -> pre_freed_slots + deferred_free_freed ;
@@ -5369,8 +5353,8 @@ gc_sweep_step(rb_objspace_t *objspace, rb_heap_t *heap)
53695353 heap_add_freepage (heap , sweep_page , "gc_sweep_step" );
53705354 swept_slots += free_slots ;
53715355 if (swept_slots > GC_INCREMENTAL_SWEEP_SLOT_COUNT ) {
5372- if (!sweep_rest && use_bg_thread ) {
5373- RUBY_ATOMIC_INC ( heap -> foreground_sweep_steps ); // signal sweep thread to move on
5356+ if (!sweep_rest && use_sweep_thread ) {
5357+ rbimpl_atomic_inc ( & heap -> foreground_sweep_steps , RBIMPL_ATOMIC_RELEASE ); // signal sweep thread to move on
53745358 }
53755359 psweep_debug (0 , "[gc] gc_sweep_step got to SWEEP_SLOT_COUNT, break\n" );
53765360 break ;
0 commit comments