[前][次][番号順一覧][スレッド一覧]

ruby-changes:47119

From: usa <ko1@a...>
Date: Fri, 30 Jun 2017 21:36:01 +0900 (JST)
Subject: [ruby-changes:47119] usa:r59234 (ruby_2_3): merge revision(s) 56558, 59116, 59136: [Backport #12670]

usa	2017-06-30 21:35:49 +0900 (Fri, 30 Jun 2017)

  New Revision: 59234

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59234

  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_3/
  Modified files:
    branches/ruby_2_3/ChangeLog
    branches/ruby_2_3/ext/-test-/typeddata/typeddata.c
    branches/ruby_2_3/gc.c
    branches/ruby_2_3/test/-ext-/typeddata/test_typeddata.rb
    branches/ruby_2_3/version.h
Index: ruby_2_3/version.h
===================================================================
--- ruby_2_3/version.h	(revision 59233)
+++ ruby_2_3/version.h	(revision 59234)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_3/version.h#L1
 #define RUBY_VERSION "2.3.5"
 #define RUBY_RELEASE_DATE "2017-06-30"
-#define RUBY_PATCHLEVEL 330
+#define RUBY_PATCHLEVEL 331
 
 #define RUBY_RELEASE_YEAR 2017
 #define RUBY_RELEASE_MONTH 6
Index: ruby_2_3/ext/-test-/typeddata/typeddata.c
===================================================================
--- ruby_2_3/ext/-test-/typeddata/typeddata.c	(revision 59233)
+++ ruby_2_3/ext/-test-/typeddata/typeddata.c	(revision 59234)
@@ -2,19 +2,43 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_3/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_3/gc.c
===================================================================
--- ruby_2_3/gc.c	(revision 59233)
+++ ruby_2_3/gc.c	(revision 59234)
@@ -1314,6 +1314,29 @@ rb_objspace_free(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/ruby_2_3/gc.c#L1314
 }
 
 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;
@@ -1321,24 +1344,7 @@ heap_pages_expand_sorted(rb_objspace_t * https://github.com/ruby/ruby/blob/trunk/ruby_2_3/gc.c#L1344
     next_length += heap_tomb->page_length;
 
     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);
     }
 }
 
@@ -1477,6 +1483,9 @@ heap_page_allocate(rb_objspace_t *objspa https://github.com/ruby/ruby/blob/trunk/ruby_2_3/gc.c#L1483
 	    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);
     }
@@ -1486,7 +1495,10 @@ heap_page_allocate(rb_objspace_t *objspa https://github.com/ruby/ruby/blob/trunk/ruby_2_3/gc.c#L1495
     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);
+    }
 
     /* adjust obj_limit (object number available in this page) */
     start = (RVALUE*)((VALUE)page_body + sizeof(struct heap_page_header));
@@ -1516,12 +1528,16 @@ heap_page_allocate(rb_objspace_t *objspa https://github.com/ruby/ruby/blob/trunk/ruby_2_3/gc.c#L1528
 static struct heap_page *
 heap_page_resurrect(rb_objspace_t *objspace)
 {
-    struct heap_page *page;
+    struct heap_page *page = heap_tomb->pages;
 
-    if ((page = heap_tomb->pages) != NULL) {
-	heap_unlink_page(objspace, heap_tomb, page);
-	return page;
+    while (page) {
+	if (page->freelist != NULL) {
+	    heap_unlink_page(objspace, heap_tomb, page);
+	    return page;
+	}
+	page = page->next;
     }
+
     return NULL;
 }
 
Index: ruby_2_3/ChangeLog
===================================================================
--- ruby_2_3/ChangeLog	(revision 59233)
+++ ruby_2_3/ChangeLog	(revision 59234)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_3/ChangeLog#L1
+Fri Jun 30 21:35:16 2017  Nobuyoshi Nakada  <nobu@r...>
+
+	* gc.c (heap_page_allocate): expand sorted pages before inserting
+	  allocated new page. [Bug #12670]
+
+Fri Jun 30 21:33:39 2017  Koichi Sasada  <ko1@a...>
+
+	* gc.c (heap_page_resurrect): do not return tomb_pages when
+	  page->freelist == NULL.
+	  [Bug #12670]
+
 Fri Jun 30 21:23:20 2017  Nobuyoshi Nakada  <nobu@r...>
 
 	* vsnprintf.c (BSD_vfprintf): sign and hex-prefix should not be counted
Index: ruby_2_3/test/-ext-/typeddata/test_typeddata.rb
===================================================================
--- ruby_2_3/test/-ext-/typeddata/test_typeddata.rb	(revision 59233)
+++ ruby_2_3/test/-ext-/typeddata/test_typeddata.rb	(revision 59234)
@@ -17,4 +17,15 @@ class Test_TypedData < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/ruby_2_3/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_3
===================================================================
--- ruby_2_3	(revision 59233)
+++ ruby_2_3	(revision 59234)

Property changes on: ruby_2_3
___________________________________________________________________
Modified: svn:mergeinfo
## -0,0 +0,1 ##
   Merged /trunk:r56558,59116,59136

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]