Fix memory leak with invalid yield in prism

[Bug #21383]

The following script leaks memory:

    10.times do
      20_000.times do
        eval("class C; yield; end")
      rescue SyntaxError
      end

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

Before:

    16464
    25536
    29424
    35904
    39552
    44576
    46736
    51600
    56096
    59824

After:

    13488
    16160
    18240
    20528
    19760
    21808
    21680
    22272
    22064
    22336
This commit is contained in:
Peter Zhu 2025-05-28 14:48:02 -04:00
parent 6a62a46c3c
commit 9f91f3617b
Notes: git 2025-05-29 20:07:02 +00:00
2 changed files with 14 additions and 0 deletions

View File

@ -1265,6 +1265,7 @@ pm_new_child_iseq(rb_iseq_t *iseq, pm_scope_node_t *node, VALUE name, const rb_i
type, ISEQ_COMPILE_DATA(iseq)->option, &error_state);
if (error_state) {
pm_scope_node_destroy(node);
RUBY_ASSERT(ret_iseq == NULL);
rb_jump_tag(error_state);
}

View File

@ -337,6 +337,19 @@ class TestAst < Test::Unit::TestCase
assert_parse("END {defined? yield}")
end
def test_invalid_yield_no_memory_leak
# [Bug #21383]
assert_no_memory_leak([], "#{<<-"begin;"}", "#{<<-'end;'}", rss: true)
code = proc do
eval("class C; yield; end")
rescue SyntaxError
end
1_000.times(&code)
begin;
100_000.times(&code)
end;
end
def test_node_id_for_location
omit if ParserSupport.prism_enabled?