From 7ef8bb129ff16750429a7ede4397d0622954ca35 Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Wed, 1 May 2024 10:01:02 -0400 Subject: 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 --- parse.y | 2 +- test/ripper/test_ripper.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/parse.y b/parse.y index 521d24787b..f406bb43b7 100644 --- a/parse.y +++ b/parse.y @@ -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; diff --git a/test/ripper/test_ripper.rb b/test/ripper/test_ripper.rb index 6061496d9c..f129a41be9 100644 --- a/test/ripper/test_ripper.rb +++ b/test/ripper/test_ripper.rb @@ -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 -- cgit v1.2.3