diff options
-rw-r--r-- | gc.c | 5 | ||||
-rw-r--r-- | process.c | 2 | ||||
-rw-r--r-- | test/ruby/test_process.rb | 12 |
3 files changed, 18 insertions, 1 deletions
@@ -9596,6 +9596,11 @@ gc_set_candidate_object_i(void *vstart, void *vend, size_t stride, void *data) case T_NONE: case T_ZOMBIE: break; + case T_STRING: + // precompute the string coderange. This both save time for when it will be + // eventually needed, and avoid mutating heap pages after a potential fork. + rb_enc_str_coderange(v); + // fall through default: if (!RVALUE_OLD_P(v) && !RVALUE_WB_UNPROTECTED(v)) { RVALUE_AGE_SET_CANDIDATE(objspace, v); @@ -8555,6 +8555,7 @@ static VALUE rb_mProcID_Syscall; * * Perform a major GC. * * Compacts the heap. * * Promotes all surviving objects to the old generation. + * * Precompute the coderange of all strings. */ static VALUE @@ -8566,7 +8567,6 @@ proc_warmup(VALUE _) return Qtrue; } - /* * Document-module: Process * diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index 6ca16733bb..9846f5e2db 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -2709,4 +2709,16 @@ EOS assert_equal compact_count + 1, GC.stat(:compact_count) end; end + + def test_warmup_precompute_string_coderange + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + require 'objspace' + begin; + obj = "a" * 12 + obj.force_encoding(Encoding::BINARY) + assert_include(ObjectSpace.dump(obj), '"coderange":"unknown"') + Process.warmup + assert_include(ObjectSpace.dump(obj), '"coderange":"7bit"') + end; + end end |