ruby-changes:38579
From: nobu <ko1@a...>
Date: Thu, 28 May 2015 16:17:57 +0900 (JST)
Subject: [ruby-changes:38579] nobu:r50660 (trunk): parser.rl: allocate structs with wrapper
nobu 2015-05-28 16:17:42 +0900 (Thu, 28 May 2015) New Revision: 50660 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50660 Log: parser.rl: allocate structs with wrapper * ext/json/parser/parser.rl (cJSON_parser_s_allocate): allocate structs with making new wrapper objects and get rid of potential memory leak. Modified files: trunk/ext/json/parser/parser.c trunk/ext/json/parser/parser.h trunk/ext/json/parser/parser.rl trunk/test/json/test_json.rb Index: ext/json/parser/parser.h =================================================================== --- ext/json/parser/parser.h (revision 50659) +++ ext/json/parser/parser.h (revision 50660) @@ -68,7 +68,6 @@ static char *JSON_parse_string(JSON_Pars https://github.com/ruby/ruby/blob/trunk/ext/json/parser/parser.h#L68 static VALUE convert_encoding(VALUE source); static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self); static VALUE cParser_parse(VALUE self); -static JSON_Parser *JSON_allocate(void); static void JSON_mark(void *json); static void JSON_free(void *json); static VALUE cJSON_parser_s_allocate(VALUE klass); @@ -82,11 +81,11 @@ static inline void *ruby_zalloc(size_t n https://github.com/ruby/ruby/blob/trunk/ext/json/parser/parser.h#L81 return p; } #endif -#ifdef TypedData_Wrap_Struct +#ifdef TypedData_Make_Struct static const rb_data_type_t JSON_Parser_type; #define NEW_TYPEDDATA_WRAPPER 1 #else -#define TypedData_Wrap_Struct(klass, ignore, json) Data_Wrap_Struct(klass, JSON_mark, JSON_free, json) +#define TypedData_Make_Struct(klass, type, ignore, json) Data_Make_Struct(klass, type, NULL, JSON_free, json) #define TypedData_Get_Struct(self, JSON_Parser, ignore, json) Data_Get_Struct(self, JSON_Parser, json) #endif Index: ext/json/parser/parser.rl =================================================================== --- ext/json/parser/parser.rl (revision 50659) +++ ext/json/parser/parser.rl (revision 50660) @@ -833,14 +833,6 @@ static VALUE cParser_parse(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/json/parser/parser.rl#L833 } } - -static JSON_Parser *JSON_allocate(void) -{ - JSON_Parser *json = ZALLOC(JSON_Parser); - json->fbuffer = fbuffer_alloc(0); - return json; -} - static void JSON_mark(void *ptr) { JSON_Parser *json = ptr; @@ -877,8 +869,10 @@ static const rb_data_type_t JSON_Parser_ https://github.com/ruby/ruby/blob/trunk/ext/json/parser/parser.rl#L869 static VALUE cJSON_parser_s_allocate(VALUE klass) { - JSON_Parser *json = JSON_allocate(); - return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json); + JSON_Parser *json; + VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json); + json->fbuffer = fbuffer_alloc(0); + return obj; } /* Index: ext/json/parser/parser.c =================================================================== --- ext/json/parser/parser.c (revision 50659) +++ ext/json/parser/parser.c (revision 50660) @@ -2110,14 +2110,6 @@ static VALUE cParser_parse(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/json/parser/parser.c#L2110 } } - -static JSON_Parser *JSON_allocate(void) -{ - JSON_Parser *json = ZALLOC(JSON_Parser); - json->fbuffer = fbuffer_alloc(0); - return json; -} - static void JSON_mark(void *ptr) { JSON_Parser *json = ptr; @@ -2154,8 +2146,10 @@ static const rb_data_type_t JSON_Parser_ https://github.com/ruby/ruby/blob/trunk/ext/json/parser/parser.c#L2146 static VALUE cJSON_parser_s_allocate(VALUE klass) { - JSON_Parser *json = JSON_allocate(); - return TypedData_Wrap_Struct(klass, &JSON_Parser_type, json); + JSON_Parser *json; + VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json); + json->fbuffer = fbuffer_alloc(0); + return obj; } /* Index: test/json/test_json.rb =================================================================== --- test/json/test_json.rb (revision 50659) +++ test/json/test_json.rb (revision 50660) @@ -560,4 +560,17 @@ EOT https://github.com/ruby/ruby/blob/trunk/test/json/test_json.rb#L560 assert_equal(Encoding::UTF_8, e.message.encoding, bug10705) assert_include(e.message, json, bug10705) end if defined?(Encoding::UTF_8) + + if EnvUtil.gc_stress_to_class? + def assert_no_memory_leak(code, *rest, **opt) + code = "8.times {20_000.times {begin #{code}; rescue NoMemoryError; end}; GC.start}" + super(["-rjson/ext/parser"], + "GC.add_stress_to_class(JSON::Ext::Parser); "\ + "#{code}", code, *rest, rss: true, limit: 1.1, **opt) + end + + def test_no_memory_leak_allocate + assert_no_memory_leak("JSON::Ext::Parser.allocate") + end + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/