summaryrefslogtreecommitdiff
path: root/ruby_parser.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <[email protected]>2024-05-01 15:36:36 +0900
committerYuichiro Kaneko <[email protected]>2024-05-02 10:14:54 +0900
commitd22dfce1cc5e5425e062dc7883b522ef85fe06db (patch)
treefba19866835ba4b52cef60f9195fc91028c126a3 /ruby_parser.c
parent5108bed5130be00fd4df45eb12cc8ceee4533cf0 (diff)
Fix memory leak of `rb_ast_t` in parser
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
Diffstat (limited to 'ruby_parser.c')
-rw-r--r--ruby_parser.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/ruby_parser.c b/ruby_parser.c
index 17b98a37d7..4c981df29d 100644
--- a/ruby_parser.c
+++ b/ruby_parser.c
@@ -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
@@ -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,