From: Nobuyoshi Nakada Date: Wed, 1 May 2024 06:36:36 +0000 (+0900) Subject: Fix memory leak of `rb_ast_t` in parser X-Git-Tag: v3_4_0_preview1~191 X-Git-Url: https://repo.or.cz/ruby.git/commitdiff_plain/d22dfce1cc5e5425e062dc7883b522ef85fe06db 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 --- 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,