Fix memory leak in Ripper.sexp

rb_ast_dispose does not free the rb_ast_t causing it to be leaked. This
commit changes it to use rb_ast_free instead.

For example:

    require "ripper"

    10.times do
      100_000.times do
        Ripper.sexp("")
      end

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

Before:

    27648
    32512
    37376
    42240
    47232
    52224
    57344
    62208
    67072
    71936

After:

    22784
    22784
    22784
    22784
    22912
    22912
    22912
    22912
    22912
    22912
This commit is contained in:
Peter Zhu 2024-05-01 10:01:02 -04:00
parent e9e41ad6b0
commit 7ef8bb129f
2 changed files with 9 additions and 1 deletions

View File

@ -16076,7 +16076,7 @@ rb_ruby_ripper_parse0(rb_parser_t *p)
parser_prepare(p);
p->ast = rb_ast_new();
ripper_yyparse((void*)p);
rb_ast_dispose(p->ast);
rb_ast_free(p->ast);
p->ast = 0;
p->eval_tree = 0;
p->eval_tree_begin = 0;

View File

@ -170,6 +170,14 @@ end
end;
end
def test_sexp_no_memory_leak
assert_no_memory_leak(%w(-rripper), "", "#{<<~'end;'}", rss: true)
1_000_000.times do
Ripper.sexp("")
end
end;
end
class TestInput < self
Input = Struct.new(:lines) do
def gets