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

ruby-changes:51861

From: k0kubun <ko1@a...>
Date: Fri, 27 Jul 2018 17:24:16 +0900 (JST)
Subject: [ruby-changes:51861] k0kubun:r64075 (trunk): mjit.c: release memory for unloaded unit

k0kubun	2018-07-27 17:24:10 +0900 (Fri, 27 Jul 2018)

  New Revision: 64075

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

  Log:
    mjit.c: release memory for unloaded unit
    
    `xfree(unit)` was missing.

  Modified files:
    trunk/mjit.c
Index: mjit.c
===================================================================
--- mjit.c	(revision 64074)
+++ mjit.c	(revision 64075)
@@ -535,11 +535,18 @@ clean_so_file(struct rb_mjit_unit *unit) https://github.com/ruby/ruby/blob/trunk/mjit.c#L535
 #endif
 }
 
+/* This is called in the following situations:
+   1) On dequeue or `unload_units()`, associated ISeq is already GCed.
+   2) The unit is not called often and unloaded by `unload_units()`.
+
+   `jit_func` state for 1 can be ignored because ISeq GC means it'll never be used.
+   For the situation 2, this sets the ISeq's JIT state to NOT_READY_JIT_ISEQ_FUNC
+   to prevent the situation that the same methods are continously compiled.  */
 static void
 free_unit(struct rb_mjit_unit *unit)
 {
     if (unit->iseq) /* ISeq is not GCed */
-        unit->iseq->body->jit_func = (mjit_func_t)NOT_ADDED_JIT_ISEQ_FUNC;
+        unit->iseq->body->jit_func = (mjit_func_t)NOT_READY_JIT_ISEQ_FUNC;
     if (unit->handle) /* handle is NULL if it's in queue */
         dlclose(unit->handle);
     clean_so_file(unit);
@@ -1219,7 +1226,6 @@ unload_units(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1226
     rb_vm_t *vm = GET_THREAD()->vm;
     rb_thread_t *th = NULL;
     struct rb_mjit_unit_node *node, *next, *worst_node;
-    struct rb_mjit_unit *unit;
     struct mjit_cont *cont;
     int delete_num, units_num = active_units.length;
 
@@ -1246,6 +1252,8 @@ unload_units(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1252
     }
 
     /* Remove 1/10 units more to decrease unloading calls.  */
+    /* TODO: Calculate max total_calls in unit_queue and don't unload units
+       whose total_calls are larger than the max. */
     delete_num = active_units.length / 10;
     for (; active_units.length > mjit_opts.max_cache_size - delete_num;) {
         /* Find one unit that has the minimum total_calls. */
@@ -1263,14 +1271,9 @@ unload_units(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1271
 
         /* Unload the worst node. */
         verbose(2, "Unloading unit %d (calls=%lu)", worst_node->unit->id, worst_node->unit->iseq->body->total_calls);
-        unit = worst_node->unit;
-        unit->iseq->body->jit_func = (mjit_func_t)NOT_READY_JIT_ISEQ_FUNC;
+        assert(worst_node->unit->handle != NULL);
+        free_unit(worst_node->unit);
         remove_from_list(worst_node, &active_units);
-
-        assert(unit->handle != NULL);
-        dlclose(unit->handle);
-        unit->handle = NULL;
-        clean_so_file(unit);
     }
     verbose(1, "Too many JIT code -- %d units unloaded", units_num - active_units.length);
 }

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

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