summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authork0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-27 08:24:10 +0000
committerk0kubun <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-07-27 08:24:10 +0000
commit0d753d4f293c65855bcefb4db38e94126740e240 (patch)
treeb5e2d94b5d96fb96e7cce6841fa997b0c76dc25f
parentca494df3e0f4782a931ffb27ea3be8f3d41c2303 (diff)
mjit.c: release memory for unloaded unit
`xfree(unit)` was missing. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64075 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--mjit.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/mjit.c b/mjit.c
index 15f798a..81c7242 100644
--- a/mjit.c
+++ b/mjit.c
@@ -535,11 +535,18 @@ clean_so_file(struct rb_mjit_unit *unit)
#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)
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)
}
/* 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)
/* 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);
}