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,15 +2731,63 @@ 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_at_exit_list(rb_at_exit_list *at_exit) +{ + size_t size = 0; + + 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) { - size_t size = sizeof(rb_vm_t); + 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 - // size += vmobj->ractor_num * sizeof(rb_ractor_t); - - return size; + // 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 = { 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) {