ruby-changes:47187
From: nagachika <ko1@a...>
Date: Mon, 10 Jul 2017 05:24:17 +0900 (JST)
Subject: [ruby-changes:47187] nagachika:r59302 (ruby_2_4): merge revision(s) 56558, 59116, 59136: [Backport #12670]
nagachika 2017-07-10 05:24:02 +0900 (Mon, 10 Jul 2017) New Revision: 59302 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59302 Log: merge revision(s) 56558,59116,59136: [Backport #12670] * gc.c (heap_page_resurrect): do not return tomb_pages when page->freelist == NULL. [Bug #12670] test for [Bug #12670] heap corruption by deferred free. gc.c: expand sorted pages * gc.c (heap_page_allocate): expand sorted pages before inserting allocated new page. [Bug #12670] Modified directories: branches/ruby_2_4/ Modified files: branches/ruby_2_4/ext/-test-/typeddata/typeddata.c branches/ruby_2_4/gc.c branches/ruby_2_4/test/-ext-/typeddata/test_typeddata.rb branches/ruby_2_4/version.h Index: ruby_2_4/gc.c =================================================================== --- ruby_2_4/gc.c (revision 59301) +++ ruby_2_4/gc.c (revision 59302) @@ -1358,6 +1358,29 @@ rb_objspace_free(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/ruby_2_4/gc.c#L1358 } static void +heap_pages_expand_sorted_to(rb_objspace_t *objspace, size_t next_length) +{ + struct heap_page **sorted; + size_t size = next_length * sizeof(struct heap_page *); + + gc_report(3, objspace, "heap_pages_expand_sorted: next_length: %d, size: %d\n", (int)next_length, (int)size); + + if (heap_pages_sorted_length > 0) { + sorted = (struct heap_page **)realloc(heap_pages_sorted, size); + if (sorted) heap_pages_sorted = sorted; + } + else { + sorted = heap_pages_sorted = (struct heap_page **)malloc(size); + } + + if (sorted == 0) { + rb_memerror(); + } + + heap_pages_sorted_length = next_length; +} + +static void heap_pages_expand_sorted(rb_objspace_t *objspace) { size_t next_length = heap_allocatable_pages; @@ -1365,24 +1388,7 @@ heap_pages_expand_sorted(rb_objspace_t * https://github.com/ruby/ruby/blob/trunk/ruby_2_4/gc.c#L1388 next_length += heap_tomb->total_pages; if (next_length > heap_pages_sorted_length) { - struct heap_page **sorted; - size_t size = next_length * sizeof(struct heap_page *); - - gc_report(3, objspace, "heap_pages_expand_sorted: next_length: %d, size: %d\n", (int)next_length, (int)size); - - if (heap_pages_sorted_length > 0) { - sorted = (struct heap_page **)realloc(heap_pages_sorted, size); - if (sorted) heap_pages_sorted = sorted; - } - else { - sorted = heap_pages_sorted = (struct heap_page **)malloc(size); - } - - if (sorted == 0) { - rb_memerror(); - } - - heap_pages_sorted_length = next_length; + heap_pages_expand_sorted_to(objspace, next_length); } } @@ -1520,6 +1526,9 @@ heap_page_allocate(rb_objspace_t *objspa https://github.com/ruby/ruby/blob/trunk/ruby_2_4/gc.c#L1526 rb_bug("same heap page is allocated: %p at %"PRIuVALUE, (void *)page_body, (VALUE)mid); } } + if (heap_allocated_pages >= heap_pages_sorted_length) { + heap_pages_expand_sorted_to(objspace, heap_allocated_pages + 1); + } if (hi < heap_allocated_pages) { MEMMOVE(&heap_pages_sorted[hi+1], &heap_pages_sorted[hi], struct heap_page_header*, heap_allocated_pages - hi); } @@ -1529,7 +1538,10 @@ heap_page_allocate(rb_objspace_t *objspa https://github.com/ruby/ruby/blob/trunk/ruby_2_4/gc.c#L1538 heap_allocated_pages++; objspace->profile.total_allocated_pages++; - if (RGENGC_CHECK_MODE) assert(heap_allocated_pages <= heap_pages_sorted_length); + if (heap_allocated_pages > heap_pages_sorted_length) { + rb_bug("heap_page_allocate: allocated(%"PRIdSIZE") > sorted(%"PRIdSIZE")", + heap_allocated_pages, heap_pages_sorted_length); + } if (heap_pages_lomem == 0 || heap_pages_lomem > start) heap_pages_lomem = start; if (heap_pages_himem < end) heap_pages_himem = end; Index: ruby_2_4/ext/-test-/typeddata/typeddata.c =================================================================== --- ruby_2_4/ext/-test-/typeddata/typeddata.c (revision 59301) +++ ruby_2_4/ext/-test-/typeddata/typeddata.c (revision 59302) @@ -2,19 +2,43 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/ext/-test-/typeddata/typeddata.c#L2 static const rb_data_type_t test_data = { "typed_data", + {NULL, ruby_xfree, NULL}, + NULL, NULL, + 0/* deferred free */, }; static VALUE +test_alloc(VALUE klass) +{ + char *p; + return TypedData_Make_Struct(klass, char, &test_data, p); +} + +static VALUE test_check(VALUE self, VALUE obj) { rb_check_typeddata(obj, &test_data); return obj; } +static VALUE +test_make(VALUE klass, VALUE num) +{ + unsigned long i, n = NUM2UINT(num); + + for (i = 0; i < n; i++) { + test_alloc(klass); + } + + return Qnil; +} + void Init_typeddata(void) { VALUE mBug = rb_define_module("Bug"); VALUE klass = rb_define_class_under(mBug, "TypedData", rb_cData); + rb_define_alloc_func(klass, test_alloc); rb_define_singleton_method(klass, "check", test_check, 1); + rb_define_singleton_method(klass, "make", test_make, 1); } Index: ruby_2_4/test/-ext-/typeddata/test_typeddata.rb =================================================================== --- ruby_2_4/test/-ext-/typeddata/test_typeddata.rb (revision 59301) +++ ruby_2_4/test/-ext-/typeddata/test_typeddata.rb (revision 59302) @@ -17,4 +17,15 @@ class Test_TypedData < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/ruby_2_4/test/-ext-/typeddata/test_typeddata.rb#L17 obj = eval("class C\u{1f5ff}; self; end").new assert_raise_with_message(TypeError, /C\u{1f5ff}/) {Bug::TypedData.check(obj)} end + + def test_deferred_free + assert_ruby_status([], "#{<<-"begin;"}\n#{<<-"end;"}") + require "-test-/typeddata" + begin; + n = 1 << 20 + Bug::TypedData.make(n) + end; + rescue MiniTest::Assertion => e + skip e.message + end end Index: ruby_2_4/version.h =================================================================== --- ruby_2_4/version.h (revision 59301) +++ ruby_2_4/version.h (revision 59302) @@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/version.h#L1 #define RUBY_VERSION "2.4.2" #define RUBY_RELEASE_DATE "2017-07-10" -#define RUBY_PATCHLEVEL 142 +#define RUBY_PATCHLEVEL 143 #define RUBY_RELEASE_YEAR 2017 #define RUBY_RELEASE_MONTH 7 Index: ruby_2_4 =================================================================== --- ruby_2_4 (revision 59301) +++ ruby_2_4 (revision 59302) Property changes on: ruby_2_4 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /trunk:r59116,59136 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/