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 коммит произвёл Jean Boussier
Родитель 283b2fdab4
Коммит 9b405a18be
3 изменённых файлов: 18 добавлений и 1 удалений

5
gc.c
Просмотреть файл

@ -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
*

Просмотреть файл

@ -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