Process.warmup: precompute strings coderange

This both save time for when it will be eventually needed,
and avoid mutating heap pages after a potential fork.

Instrumenting some large Rails app, I've witnessed up to
58% of String instances having their coderange still unknown.
This commit is contained in:
Jean Boussier 2023-02-21 12:38:25 +01:00 committed by Jean Boussier
parent 283b2fdab4
commit 9b405a18be
Notes: git 2023-07-26 09:41:42 +00:00
3 changed files with 18 additions and 1 deletions

5
gc.c
View File

@ -9596,6 +9596,11 @@ gc_set_candidate_object_i(void *vstart, void *vend, size_t stride, void *data)
case T_NONE: case T_NONE:
case T_ZOMBIE: case T_ZOMBIE:
break; 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: default:
if (!RVALUE_OLD_P(v) && !RVALUE_WB_UNPROTECTED(v)) { if (!RVALUE_OLD_P(v) && !RVALUE_WB_UNPROTECTED(v)) {
RVALUE_AGE_SET_CANDIDATE(objspace, v); RVALUE_AGE_SET_CANDIDATE(objspace, v);

View File

@ -8555,6 +8555,7 @@ static VALUE rb_mProcID_Syscall;
* * Perform a major GC. * * Perform a major GC.
* * Compacts the heap. * * Compacts the heap.
* * Promotes all surviving objects to the old generation. * * Promotes all surviving objects to the old generation.
* * Precompute the coderange of all strings.
*/ */
static VALUE static VALUE
@ -8566,7 +8567,6 @@ proc_warmup(VALUE _)
return Qtrue; return Qtrue;
} }
/* /*
* Document-module: Process * Document-module: Process
* *

View File

@ -2709,4 +2709,16 @@ EOS
assert_equal compact_count + 1, GC.stat(:compact_count) assert_equal compact_count + 1, GC.stat(:compact_count)
end; end;
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 end