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

ruby-changes:47346

From: ko1 <ko1@a...>
Date: Wed, 2 Aug 2017 09:50:48 +0900 (JST)
Subject: [ruby-changes:47346] ko1:r59462 (trunk): release VM stack properly.

ko1	2017-08-02 09:50:42 +0900 (Wed, 02 Aug 2017)

  New Revision: 59462

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

  Log:
    release VM stack properly.
    
    * cont.c: r55766 change the handling method of Fiber's VM stack.
      Resumed Fiber points NULL as VM stack and running Thread has
      responsibility to manage it (marking and releasing).
    
      However, thread_start_func_2()@thread.c and thread_free()@vm.c
      doesn't free the VM stack if corresponding root Fiber is exist.
      This causes memory leak. [Bug #13772]
    
    * cont.c (root_fiber_alloc): fib->cont.saved_thread.ec.stack should be NULL
      because running thread has responsibility to manage this stack.
    
    * vm.c (rb_thread_recycle_stack_release): assert given stack is not NULL
      (callers should care it).

  Modified files:
    trunk/cont.c
    trunk/thread.c
    trunk/vm.c
Index: thread.c
===================================================================
--- thread.c	(revision 59461)
+++ thread.c	(revision 59462)
@@ -694,10 +694,8 @@ thread_start_func_2(rb_thread_t *th, VAL https://github.com/ruby/ruby/blob/trunk/thread.c#L694
 	rb_threadptr_unlock_all_locking_mutexes(th);
 	rb_check_deadlock(th->vm);
 
-	if (!th->root_fiber) {
-	    rb_thread_recycle_stack_release(th->ec.stack);
-	    th->ec.stack = 0;
-	}
+	rb_thread_recycle_stack_release(th->ec.stack);
+	th->ec.stack = NULL;
     }
     native_mutex_lock(&th->vm->thread_destruct_lock);
     /* make sure vm->running_thread never point me after this point.*/
Index: cont.c
===================================================================
--- cont.c	(revision 59461)
+++ cont.c	(revision 59462)
@@ -1288,6 +1288,7 @@ root_fiber_alloc(rb_thread_t *th) https://github.com/ruby/ruby/blob/trunk/cont.c#L1288
     rb_fiber_t *fib;
     /* no need to allocate vm stack */
     fib = fiber_t_alloc(fiber_alloc(rb_cFiber));
+    fib->cont.saved_thread.ec.stack = NULL;
     fib->cont.type = ROOT_FIBER_CONTEXT;
 #if FIBER_USE_NATIVE
 #ifdef _WIN32
Index: vm.c
===================================================================
--- vm.c	(revision 59461)
+++ vm.c	(revision 59462)
@@ -2330,7 +2330,7 @@ static int thread_recycle_stack_count = https://github.com/ruby/ruby/blob/trunk/vm.c#L2330
 static VALUE *
 thread_recycle_stack(size_t size)
 {
-    if (thread_recycle_stack_count) {
+    if (thread_recycle_stack_count > 0) {
 	/* TODO: check stack size if stack sizes are variable */
 	return thread_recycle_stack_slot[--thread_recycle_stack_count];
     }
@@ -2346,6 +2346,8 @@ thread_recycle_stack(size_t size) https://github.com/ruby/ruby/blob/trunk/vm.c#L2346
 void
 rb_thread_recycle_stack_release(VALUE *stack)
 {
+    VM_ASSERT(stack != NULL);
+
 #if USE_THREAD_DATA_RECYCLE
     if (thread_recycle_stack_count < RECYCLE_MAX) {
 	thread_recycle_stack_slot[thread_recycle_stack_count++] = stack;
@@ -2429,8 +2431,9 @@ thread_free(void *ptr) https://github.com/ruby/ruby/blob/trunk/vm.c#L2431
     rb_thread_t *th = ptr;
     RUBY_FREE_ENTER("thread");
 
-    if (!th->root_fiber) {
-	RUBY_FREE_UNLESS_NULL(th->ec.stack);
+    if (th->ec.stack != NULL) {
+	rb_thread_recycle_stack_release(th->ec.stack);
+	th->ec.stack = NULL;
     }
 
     if (th->locking_mutex != Qfalse) {

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

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