summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--process.c15
-rw-r--r--thread.c15
-rw-r--r--vm.c56
-rw-r--r--vm_trace.c23
4 files changed, 105 insertions, 4 deletions
diff --git a/process.c b/process.c
index 83c44fdd48..8eee6f772a 100644
--- a/process.c
+++ b/process.c
@@ -1090,6 +1090,21 @@ waitpid_signal(struct waitpid_state *w)
return FALSE;
}
+// Used for VM memsize reporting. Returns the size of a list of waitpid_state
+// structs. Defined here because the struct definition lives here as well.
+size_t
+rb_vm_memsize_waiting_list(struct list_head *waiting_list)
+{
+ struct waitpid_state *waitpid = 0;
+ size_t size = 0;
+
+ list_for_each(waiting_list, waitpid, wnode) {
+ size += sizeof(struct waitpid_state);
+ }
+
+ return size;
+}
+
/*
* When a thread is done using sigwait_fd and there are other threads
* sleeping on waitpid, we must kick one of the threads out of
diff --git a/thread.c b/thread.c
index 95daed6668..46ae21b589 100644
--- a/thread.c
+++ b/thread.c
@@ -5575,6 +5575,21 @@ rb_check_deadlock(rb_ractor_t *r)
}
}
+// Used for VM memsize reporting. Returns the size of a list of waiting_fd
+// structs. Defined here because the struct definition lives here as well.
+size_t
+rb_vm_memsize_waiting_fds(struct list_head *waiting_fds)
+{
+ struct waiting_fd *waitfd = 0;
+ size_t size = 0;
+
+ list_for_each(waiting_fds, waitfd, wfd_node) {
+ size += sizeof(struct waiting_fd);
+ }
+
+ return size;
+}
+
static void
update_line_coverage(VALUE data, const rb_trace_arg_t *trace_arg)
{
diff --git a/vm.c b/vm.c
index 634ed15884..cb7007ac13 100644
--- a/vm.c
+++ b/vm.c
@@ -2731,17 +2731,65 @@ ruby_vm_destruct(rb_vm_t *vm)
return 0;
}
+size_t rb_vm_memsize_waiting_list(struct list_head *waiting_list); // process.c
+size_t rb_vm_memsize_waiting_fds(struct list_head *waiting_fds); // thread.c
+size_t rb_vm_memsize_postponed_job_buffer(); // vm_trace.c
+size_t rb_vm_memsize_workqueue(struct list_head *workqueue); // vm_trace.c
+
+// Used for VM memsize reporting. Returns the size of the at_exit list by
+// looping through the linked list and adding up the size of the structs.
static size_t
-vm_memsize(const void *ptr)
+vm_memsize_at_exit_list(rb_at_exit_list *at_exit)
{
- size_t size = sizeof(rb_vm_t);
+ size_t size = 0;
- // TODO
- // size += vmobj->ractor_num * sizeof(rb_ractor_t);
+ while (at_exit) {
+ size += sizeof(rb_at_exit_list);
+ at_exit = at_exit->next;
+ }
return size;
}
+// Used for VM memsize reporting. Returns the size of the builtin function
+// table if it has been defined.
+static size_t
+vm_memsize_builtin_function_table(const struct rb_builtin_function *builtin_function_table)
+{
+ return builtin_function_table == NULL ? 0 : sizeof(struct rb_builtin_function);
+}
+
+// Reports the memsize of the VM struct object and the structs that are
+// associated with it.
+static size_t
+vm_memsize(const void *ptr)
+{
+ rb_vm_t *vm = GET_VM();
+
+ return (
+ sizeof(rb_vm_t) +
+ rb_vm_memsize_waiting_list(&vm->waiting_pids) +
+ rb_vm_memsize_waiting_list(&vm->waiting_grps) +
+ rb_vm_memsize_waiting_fds(&vm->waiting_fds) +
+ rb_st_memsize(vm->loaded_features_index) +
+ rb_st_memsize(vm->loading_table) +
+ rb_st_memsize(vm->ensure_rollback_table) +
+ rb_vm_memsize_postponed_job_buffer() +
+ rb_vm_memsize_workqueue(&vm->workqueue) +
+ rb_st_memsize(vm->defined_module_hash) +
+ vm_memsize_at_exit_list(vm->at_exit) +
+ rb_st_memsize(vm->frozen_strings) +
+ vm_memsize_builtin_function_table(vm->builtin_function_table) +
+ rb_id_table_memsize(vm->negative_cme_table) +
+ rb_st_memsize(vm->overloaded_cme_table)
+ );
+
+ // TODO
+ // struct { struct list_head set; } ractor;
+ // void *main_altstack; #ifdef USE_SIGALTSTACK
+ // struct rb_objspace *objspace;
+}
+
static const rb_data_type_t vm_data_type = {
"VM",
{0, 0, vm_memsize,},
diff --git a/vm_trace.c b/vm_trace.c
index 466856341d..7f6a60b0cb 100644
--- a/vm_trace.c
+++ b/vm_trace.c
@@ -1578,6 +1578,29 @@ struct rb_workqueue_job {
rb_postponed_job_t job;
};
+// Used for VM memsize reporting. Returns the size of a list of rb_workqueue_job
+// structs. Defined here because the struct definition lives here as well.
+size_t
+rb_vm_memsize_workqueue(struct list_head *workqueue)
+{
+ struct rb_workqueue_job *work = 0;
+ size_t size = 0;
+
+ list_for_each(workqueue, work, jnode) {
+ size += sizeof(struct rb_workqueue_job);
+ }
+
+ return size;
+}
+
+// Used for VM memsize reporting. Returns the total size of the postponed job
+// buffer that was allocated at initialization.
+size_t
+rb_vm_memsize_postponed_job_buffer()
+{
+ return sizeof(rb_postponed_job_t) * MAX_POSTPONED_JOB;
+}
+
void
Init_vm_postponed_job(void)
{