Skip to content

Commit

Permalink
Process.warmup: precompute strings coderange
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
byroot committed Jul 26, 2023
1 parent 26aef1c commit ce23b6d
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 2 deletions.
5 changes: 5 additions & 0 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions internal/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#define STR_NOEMBED FL_USER1
#define STR_SHARED FL_USER2 /* = ELTS_SHARED */
#define STR_NOFREE FL_USER18

#ifdef rb_fstring_cstr
# undef rb_fstring_cstr
Expand Down
2 changes: 1 addition & 1 deletion process.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -8566,7 +8567,6 @@ proc_warmup(VALUE _)
return Qtrue;
}


/*
* Document-module: Process
*
Expand Down
1 change: 0 additions & 1 deletion string.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ VALUE rb_cSymbol;
#define STR_SHARED_ROOT FL_USER5
#define STR_BORROWED FL_USER6
#define STR_TMPLOCK FL_USER7
#define STR_NOFREE FL_USER18
#define STR_FAKESTR FL_USER19

#define STR_SET_NOEMBED(str) do {\
Expand Down
12 changes: 12 additions & 0 deletions test/ruby/test_process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2709,4 +2709,16 @@ def test_warmup_run_major_gc_and_compact
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

0 comments on commit ce23b6d

Please sign in to comment.