ruby-changes:63748
From: Aaron <ko1@a...>
Date: Wed, 25 Nov 2020 14:30:44 +0900 (JST)
Subject: [ruby-changes:63748] fed67fe6b2 (master): Revert "Disable auto compaction on platforms that can't support it"
https://git.ruby-lang.org/ruby.git/commit/?id=fed67fe6b2 From fed67fe6b277361940e3357c8b1ffa455d7f2339 Mon Sep 17 00:00:00 2001 From: Aaron Patterson <tenderlove@r...> Date: Tue, 24 Nov 2020 21:29:45 -0800 Subject: Revert "Disable auto compaction on platforms that can't support it" This reverts commit 63ad55cd882e4010fe313d271af006a430b5ffa8. Revert "Disable read barrier on explicit compaction request" This reverts commit 490b57783d80f0c5f7882c66d9fb6aa02713c9a5. diff --git a/gc.c b/gc.c index d5ad476..5573ee5 100644 --- a/gc.c +++ b/gc.c @@ -682,7 +682,7 @@ typedef struct rb_objspace { https://github.com/ruby/ruby/blob/trunk/gc.c#L682 unsigned int dont_gc : 1; unsigned int dont_incremental : 1; unsigned int during_gc : 1; - unsigned int during_compacting : 2; + unsigned int during_compacting : 1; unsigned int gc_stressful: 1; unsigned int has_hook: 1; unsigned int during_minor_gc : 1; @@ -3090,17 +3090,6 @@ Init_heap(void) https://github.com/ruby/ruby/blob/trunk/gc.c#L3090 { rb_objspace_t *objspace = &rb_objspace; -#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) - /* If Ruby's heap pages are not a multiple of the system page size, we - * cannot use mprotect for the read barrier, so we must disable automatic - * compaction. */ - int pagesize; - pagesize = (int)sysconf(_SC_PAGE_SIZE); - if ((HEAP_PAGE_SIZE % pagesize) != 0) { - ruby_enable_autocompact = 0; - } -#endif - objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL); objspace->id_to_obj_tbl = st_init_table(&object_id_hash_type); objspace->obj_to_id_tbl = st_init_numtable(); @@ -4400,11 +4389,6 @@ static VALUE gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free); https://github.com/ruby/ruby/blob/trunk/gc.c#L4389 static void lock_page_body(rb_objspace_t *objspace, struct heap_page_body *body) { - /* If this is an explicit compaction (GC.compact), we don't need a read - * barrier, so just return early. */ - if (objspace->flags.during_compacting >> 1) { - return; - } #if defined(_WIN32) DWORD old_protect; @@ -4421,11 +4405,6 @@ lock_page_body(rb_objspace_t *objspace, struct heap_page_body *body) https://github.com/ruby/ruby/blob/trunk/gc.c#L4405 static void unlock_page_body(rb_objspace_t *objspace, struct heap_page_body *body) { - /* If this is an explicit compaction (GC.compact), we don't need a read - * barrier, so just return early. */ - if (objspace->flags.during_compacting >> 1) { - return; - } #if defined(_WIN32) DWORD old_protect; @@ -7051,7 +7030,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark) https://github.com/ruby/ruby/blob/trunk/gc.c#L7030 #endif objspace->flags.during_minor_gc = FALSE; if (ruby_enable_autocompact) { - objspace->flags.during_compacting |= TRUE; + objspace->flags.during_compacting = TRUE; } objspace->profile.major_gc_count++; objspace->rgengc.uncollectible_wb_unprotected_objects = 0; @@ -8078,9 +8057,7 @@ gc_start(rb_objspace_t *objspace, int reason) https://github.com/ruby/ruby/blob/trunk/gc.c#L8057 /* reason may be clobbered, later, so keep set immediate_sweep here */ objspace->flags.immediate_sweep = !!((unsigned)reason & GPR_FLAG_IMMEDIATE_SWEEP); - - /* Explicitly enable compaction (GC.compact) */ - objspace->flags.during_compacting = (!!((unsigned)reason & GPR_FLAG_COMPACT) << 1); + objspace->flags.during_compacting = !!((unsigned)reason & GPR_FLAG_COMPACT); if (!heap_allocated_pages) return FALSE; /* heap is not ready */ if (!(reason & GPR_FLAG_METHOD) && !ready_to_gc(objspace)) return TRUE; /* GC is not allowed */ @@ -9271,19 +9248,6 @@ heap_check_moved_i(void *vstart, void *vend, size_t stride, void *data) https://github.com/ruby/ruby/blob/trunk/gc.c#L9248 } static VALUE -gc_compact(rb_execution_context_t *ec, VALUE self) -{ - /* Clear the heap. */ - gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qfalse); - - /* At this point, all references are live and the mutator is not allowed - * to run, so we don't need a read barrier. */ - gc_start_internal(ec, self, Qtrue, Qtrue, Qtrue, Qtrue); - - return gc_compact_stats(ec, self); -} - -static VALUE gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE double_heap, VALUE toward_empty) { rb_objspace_t *objspace = &rb_objspace; @@ -9901,16 +9865,6 @@ gc_disable(rb_execution_context_t *ec, VALUE _) https://github.com/ruby/ruby/blob/trunk/gc.c#L9865 static VALUE gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v) { -#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) - /* If Ruby's heap pages are not a multiple of the system page size, we - * cannot use mprotect for the read barrier, so we must disable automatic - * compaction. */ - int pagesize; - pagesize = (int)sysconf(_SC_PAGE_SIZE); - if ((HEAP_PAGE_SIZE % pagesize) != 0) { - rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform"); - } -#endif ruby_enable_autocompact = RTEST(v); return v; } diff --git a/gc.rb b/gc.rb index 4e0faaf..d2b0d8e 100644 --- a/gc.rb +++ b/gc.rb @@ -199,7 +199,8 @@ module GC https://github.com/ruby/ruby/blob/trunk/gc.rb#L199 end def self.compact - Primitive.gc_compact + Primitive.gc_start_internal true, true, true, true + Primitive.gc_compact_stats end # call-seq: diff --git a/test/ruby/test_gc_compact.rb b/test/ruby/test_gc_compact.rb index 4a8cff3..3aad9e6 100644 --- a/test/ruby/test_gc_compact.rb +++ b/test/ruby/test_gc_compact.rb @@ -1,82 +1,56 @@ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_gc_compact.rb#L1 # frozen_string_literal: true require 'test/unit' require 'fiddle' -require 'etc' class TestGCCompact < Test::Unit::TestCase - class AutoCompact < Test::Unit::TestCase - def setup - skip "autocompact not supported on this platform" unless supports_auto_compact? - super - end - - def test_enable_autocompact - before = GC.auto_compact - GC.auto_compact = true - assert GC.auto_compact - ensure - GC.auto_compact = before - end - - def test_disable_autocompact - before = GC.auto_compact - GC.auto_compact = false - refute GC.auto_compact - ensure - GC.auto_compact = before - end - - def test_major_compacts - before = GC.auto_compact - GC.auto_compact = true - compact = GC.stat :compact_count - GC.start - assert_operator GC.stat(:compact_count), :>, compact - ensure - GC.auto_compact = before - end - - def test_implicit_compaction_does_something - before = GC.auto_compact - list = [] - list2 = [] - - # Try to make some fragmentation - 500.times { - list << Object.new - Object.new - Object.new - } - count = GC.stat :compact_count - GC.auto_compact = true - loop do - break if count < GC.stat(:compact_count) - list2 << Object.new - end - compact_stats = GC.latest_compact_info - refute_predicate compact_stats[:considered], :empty? - refute_predicate compact_stats[:moved], :empty? - ensure - GC.auto_compact = before - end + def test_enable_autocompact + before = GC.auto_compact + GC.auto_compact = true + assert GC.auto_compact + ensure + GC.auto_compact = before + end - private + def test_disable_autocompact + before = GC.auto_compact + GC.auto_compact = false + refute GC.auto_compact + ensure + GC.auto_compact = before + end - def supports_auto_compact? - return true unless defined?(Etc::SC_PAGE_SIZE) + def test_major_compacts + before = GC.auto_compact + GC.auto_compact = true + compact = GC.stat :compact_count + GC.start + assert_operator GC.stat(:compact_count), :>, compact + ensure + GC.auto_compact = before + end - begin - return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0 - rescue NotImplementedError - rescue ArgumentError - end + def test_implicit_compaction_does_something + before = GC.auto_compact + list = [] + list2 = [] - true + # Try to make some fragmentation + 500.times { + list << Object.new + Object.new + Object.new + } + count = GC.stat :compact_count + GC.auto_compact = true + loop do + break if count < GC.stat(:compact_count) + list2 << Object.new end - end - - def os_page_size - return true unless defined?(Etc::SC_PAGE_SIZE) + compact_stats = GC.latest_compact_info + refute_predicate compact_stats[:considered], :empty? + refute_predicate compact_stats[:moved], :empty? + ensure + GC.auto_compact = before end def test_gc_compact_stats -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/