зеркало из https://github.com/github/ruby.git
Fix leak of token_info when Ripper#warn jumps
For example, the following code leaks: class MyRipper < Ripper def initialize(src, &blk) super(src) @blk = blk end def warn(msg, *args) = @blk.call(msg) end $VERBOSE = true def call_parse = MyRipper.new("if true\n end\n") { |msg| return msg }.parse 10.times do 500_000.times do call_parse end puts `ps -o rss= -p #{$$}` end Before: 37536 53744 70064 86448 102576 119120 135248 151216 167744 183824 After: 19280 19696 19728 20336 20448 21408 21616 21616 21824 21840
This commit is contained in:
Родитель
60bbd9e462
Коммит
584559d86a
3
parse.y
3
parse.y
|
@ -7203,10 +7203,11 @@ token_info_pop(struct parser_params *p, const char *token, const rb_code_locatio
|
|||
token_info *ptinfo_beg = p->token_info;
|
||||
|
||||
if (!ptinfo_beg) return;
|
||||
p->token_info = ptinfo_beg->next;
|
||||
|
||||
/* indentation check of matched keywords (begin..end, if..end, etc.) */
|
||||
token_info_warn(p, token, ptinfo_beg, 1, loc);
|
||||
|
||||
p->token_info = ptinfo_beg->next;
|
||||
ruby_sized_xfree(ptinfo_beg, sizeof(*ptinfo_beg));
|
||||
}
|
||||
|
||||
|
|
|
@ -1786,5 +1786,26 @@ class TestRipper::ParserEvents < Test::Unit::TestCase
|
|||
call_parse
|
||||
end
|
||||
end;
|
||||
|
||||
assert_no_memory_leak(%w(-rripper), "#{<<~'begin;'}", "#{<<~'end;'}", rss: true)
|
||||
class MyRipper < Ripper
|
||||
def initialize(src, &blk)
|
||||
super(src)
|
||||
@blk = blk
|
||||
end
|
||||
|
||||
def warn(msg, *args) = @blk.call(msg)
|
||||
end
|
||||
|
||||
$VERBOSE = true
|
||||
def call_parse = MyRipper.new("if true\n end\n") { |msg| return msg }.parse
|
||||
|
||||
# Check that call_parse does warn
|
||||
raise "call_parse should warn" unless call_parse
|
||||
begin;
|
||||
1_000_000.times do
|
||||
call_parse
|
||||
end
|
||||
end;
|
||||
end
|
||||
end if ripper_test
|
||||
|
|
Загрузка…
Ссылка в новой задаче