Skip to content

Commit

Permalink
Fix memory leak of rb_ast_t in parser
Browse files Browse the repository at this point in the history
Do not allocate `rb_ast_t` in `ast_alloc` to avoid memory leak.

For example:

    10.times do
      100_000.times do
        eval("")
      end

      puts `ps -o rss= -p #{$$}`
    end

Before:

    17568
    20960
    24096
    27808
    31008
    34160
    37312
    40464
    43568
    46816

After:

    14432
    14448
    14496
    14576
    14592
    15072
    15072
    15072
    15072
    15088
  • Loading branch information
nobu authored and yui-knk committed May 1, 2024
1 parent 0aee83d commit 62fe7fe
Showing 1 changed file with 6 additions and 9 deletions.
15 changes: 6 additions & 9 deletions ruby_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,13 +784,7 @@ static const rb_data_type_t ast_data_type = {
static VALUE
ast_alloc(void)
{
rb_ast_t *ast;
VALUE vast = TypedData_Make_Struct(0, rb_ast_t, &ast_data_type, ast);
#ifdef UNIVERSAL_PARSER
ast = (rb_ast_t *)DATA_PTR(vast);
ast->config = &rb_global_parser_config;
#endif
return vast;
return TypedData_Wrap_Struct(0, &ast_data_type, NULL);
}

VALUE
Expand Down Expand Up @@ -1142,8 +1136,11 @@ parser_aset_script_lines_for(VALUE path, rb_parser_ary_t *lines)
VALUE
rb_ruby_ast_new(const NODE *const root)
{
VALUE vast = ast_alloc();
rb_ast_t *ast = DATA_PTR(vast);
rb_ast_t *ast;
VALUE vast = TypedData_Make_Struct(0, rb_ast_t, &ast_data_type, ast);
#ifdef UNIVERSAL_PARSER
ast->config = &rb_global_parser_config;
#endif
ast->body = (rb_ast_body_t){
.root = root,
.frozen_string_literal = -1,
Expand Down

0 comments on commit 62fe7fe

Please sign in to comment.