diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-07-17 11:15:07 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-07-17 11:15:07 +0900 |
| commit | f00657ead7c3e5f6f9a346d7797a280b5c9f02fa (patch) | |
| tree | d1c96256f8537ae6a408fb51d3cf3e0ad62f8ff9 /mrbgems/mruby-objectspace | |
| parent | 2e56da5a78befb93a1e4debe42d783c4b7be4c30 (diff) | |
| download | mruby-f00657ead7c3e5f6f9a346d7797a280b5c9f02fa.tar.gz mruby-f00657ead7c3e5f6f9a346d7797a280b5c9f02fa.zip | |
Remove recursive `memsize_of`; #5032
This is enhancement from CRuby's `memsize_of`. We need to change the
CRuby first for the enhancement.
Diffstat (limited to 'mrbgems/mruby-objectspace')
| -rw-r--r-- | mrbgems/mruby-objectspace/src/mruby_objectspace.c | 134 | ||||
| -rw-r--r-- | mrbgems/mruby-objectspace/test/objectspace.rb | 69 |
2 files changed, 51 insertions, 152 deletions
diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index 971f81c97..71a7e1b8b 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -176,83 +176,66 @@ os_each_object(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(d.count); } -static void os_memsize_of_object(mrb_state*,mrb_value,mrb_value,mrb_int*); - -struct os_memsize_cb_data { - mrb_int *t; - mrb_value recurse; -}; - -static int -os_memsize_ivar_cb(mrb_state *mrb, mrb_sym _name, mrb_value obj, void *data) +static mrb_int +os_memsize_of_ivars(mrb_state* mrb, mrb_value obj) { - struct os_memsize_cb_data *cb_data = (struct os_memsize_cb_data *)(data); - os_memsize_of_object(mrb, obj, cb_data->recurse, cb_data->t); - return 0; -} - -static void -os_memsize_of_ivars(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int *t) -{ - (*t) += mrb_obj_iv_tbl_memsize(mrb, obj); - if(!mrb_nil_p(recurse)) { - struct os_memsize_cb_data cb_data = {t, recurse}; - mrb_iv_foreach(mrb, obj, os_memsize_ivar_cb, &cb_data); - } + return mrb_obj_iv_tbl_memsize(mrb, obj); } -static void -os_memsize_of_irep(mrb_state* state, struct mrb_irep *irep, mrb_int* t) +static mrb_int +os_memsize_of_irep(mrb_state* state, struct mrb_irep *irep) { - mrb_int i; - (*t) += (irep->slen * sizeof(mrb_sym)) + - (irep->plen * sizeof(mrb_code)) + - (irep->ilen * sizeof(mrb_code)); + mrb_int size, i; + size = (irep->slen * sizeof(mrb_sym)) + + (irep->plen * sizeof(mrb_code)) + + (irep->ilen * sizeof(mrb_code)); for(i = 0; i < irep->rlen; i++) { - os_memsize_of_irep(state, irep->reps[i], t); + size += os_memsize_of_irep(state, irep->reps[i]); } + return size; } -static void -os_memsize_of_method(mrb_state* mrb, mrb_value method_obj, mrb_int* t) +static mrb_int +os_memsize_of_method(mrb_state* mrb, mrb_value method_obj) { + mrb_int size; mrb_value proc_value = mrb_obj_iv_get(mrb, mrb_obj_ptr(method_obj), mrb_intern_lit(mrb, "_proc")); struct RProc *proc = mrb_proc_ptr(proc_value); - (*t) += sizeof(struct RProc); - if(!MRB_PROC_CFUNC_P(proc)) os_memsize_of_irep(mrb, proc->body.irep, t); + size = sizeof(struct RProc); + if(!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep); + return size; } -static void -os_memsize_of_methods(mrb_state* mrb, mrb_value obj, mrb_int* t) +static mrb_int +os_memsize_of_methods(mrb_state* mrb, mrb_value obj) { mrb_value method_list; + mrb_int size = 0; mrb_int i; - if(!mrb_respond_to(mrb, obj, mrb_intern_lit(mrb, "instance_methods"))) return; + + if(!mrb_respond_to(mrb, obj, mrb_intern_lit(mrb, "instance_methods"))) return 0; method_list = mrb_funcall(mrb, obj, "instance_methods", 1, mrb_false_value()); for(i = 0; i < RARRAY_LEN(method_list); i++) { mrb_value method = mrb_funcall(mrb, obj, "instance_method", 1, mrb_ary_ref(mrb, method_list, i)); - os_memsize_of_method(mrb, method, t); + size += os_memsize_of_method(mrb, method); } + return size; } -static void -os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int* t) +static mrb_int +os_memsize_of_object(mrb_state* mrb, mrb_value obj) { - if(!mrb_nil_p(recurse)) { - const mrb_value obj_id = mrb_fixnum_value(mrb_obj_id(obj)); - if(mrb_hash_key_p(mrb, recurse, obj_id)) return; - mrb_hash_set(mrb, recurse, obj_id, mrb_true_value()); - } + mrb_int size = 0; switch(obj.tt) { case MRB_TT_STRING: - (*t) += mrb_objspace_page_slot_size(); + size += mrb_objspace_page_slot_size(); if (!RSTR_EMBED_P(RSTRING(obj)) && !RSTR_SHARED_P(RSTRING(obj))) { - (*t) += RSTRING_CAPA(obj); + size += RSTRING_CAPA(obj); } break; case MRB_TT_CLASS: @@ -261,61 +244,50 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int* case MRB_TT_SCLASS: case MRB_TT_ICLASS: case MRB_TT_OBJECT: { - (*t) += mrb_objspace_page_slot_size(); - os_memsize_of_ivars(mrb, obj, recurse, t); + size += mrb_objspace_page_slot_size(); + size += os_memsize_of_ivars(mrb, obj); if(mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "UnboundMethod"))) { - os_memsize_of_method(mrb, obj, t); + size += os_memsize_of_method(mrb, obj); } else { - os_memsize_of_methods(mrb, obj, t); + size += os_memsize_of_methods(mrb, obj); } break; } case MRB_TT_HASH: { - (*t) += mrb_objspace_page_slot_size() + + size += mrb_objspace_page_slot_size() + mrb_os_memsize_of_hash_table(obj); - if(!mrb_nil_p(recurse)) { - os_memsize_of_object(mrb, mrb_hash_keys(mrb, obj), recurse, t); - os_memsize_of_object(mrb, mrb_hash_values(mrb, obj), recurse, t); - } break; } case MRB_TT_ARRAY: { - mrb_int len, i; - len = RARRAY_LEN(obj); + mrb_int len = RARRAY_LEN(obj); /* Arrays that do not fit within an RArray perform a heap allocation * storing an array of pointers to the original objects*/ - (*t) += mrb_objspace_page_slot_size(); - if(len > MRB_ARY_EMBED_LEN_MAX) (*t) += sizeof(mrb_value *) * len; - - if(!mrb_nil_p(recurse)) { - for(i = 0; i < len; i++) { - os_memsize_of_object(mrb, ARY_PTR(mrb_ary_ptr(obj))[i], recurse, t); - } - } + size += mrb_objspace_page_slot_size(); + if(len > MRB_ARY_EMBED_LEN_MAX) size += sizeof(mrb_value *) * len; break; } case MRB_TT_PROC: { struct RProc* proc = mrb_proc_ptr(obj); - (*t) += mrb_objspace_page_slot_size(); - (*t) += MRB_ENV_LEN(proc->e.env) * sizeof(mrb_value); - if(!MRB_PROC_CFUNC_P(proc)) os_memsize_of_irep(mrb, proc->body.irep, t); + size += mrb_objspace_page_slot_size(); + size += MRB_ENV_LEN(proc->e.env) * sizeof(mrb_value); + if(!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep); break; } case MRB_TT_DATA: - (*t) += mrb_objspace_page_slot_size(); + size += mrb_objspace_page_slot_size(); break; #ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: #ifdef MRB_WORD_BOXING - (*t) += mrb_objspace_page_slot_size() + + size += mrb_objspace_page_slot_size() + sizeof(struct RFloat); #endif break; #endif case MRB_TT_RANGE: #ifndef MRB_RANGE_EMBED - (*t) += mrb_objspace_page_slot_size() + + size += mrb_objspace_page_slot_size() + sizeof(struct mrb_range_edges); #endif break; @@ -327,17 +299,17 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int* mrb_int i = 0; while(ci_p < f->cxt->ciend) { - if(ci_p->proc) os_memsize_of_irep(mrb, ci_p->proc->body.irep, t); + if(ci_p->proc) size += os_memsize_of_irep(mrb, ci_p->proc->body.irep); ci_p++; } if(f->cxt->esize) { for(i = 0; i <= f->cxt->esize; i++) { - os_memsize_of_irep(mrb, f->cxt->ensure[i]->body.irep, t); + size += os_memsize_of_irep(mrb, f->cxt->ensure[i]->body.irep); } } - (*t) += mrb_objspace_page_slot_size() + + size += mrb_objspace_page_slot_size() + sizeof(struct RFiber) + sizeof(struct mrb_context) + sizeof(struct RProc *) * f->cxt->esize + @@ -347,7 +319,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int* break; } case MRB_TT_ISTRUCT: - (*t) += mrb_objspace_page_slot_size(); + size += mrb_objspace_page_slot_size(); break; /* zero heap size types. * immediate VM stack values, contained within mrb_state, or on C stack */ @@ -366,6 +338,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj, mrb_value recurse, mrb_int* case MRB_TT_MAXDEFINE: break; } + return size; } /* @@ -394,17 +367,10 @@ os_memsize_of(mrb_state *mrb, mrb_value self) { mrb_int total; mrb_value obj; - mrb_value recurse; - const char *kw_names[1] = { "recurse" }; - mrb_value kw_values[1]; - const mrb_kwargs kwargs = { 1, kw_values, kw_names, 0, NULL }; - - mrb_get_args(mrb, "o:", &obj, &kwargs); - recurse = (!mrb_undef_p(kw_values[0]) && mrb_test(kw_values[0]))? mrb_hash_new(mrb) : mrb_nil_value(); - total = 0; - os_memsize_of_object(mrb, obj, recurse, &total); + mrb_get_args(mrb, "o", &obj); + total = os_memsize_of_object(mrb, obj); return mrb_fixnum_value(total); } diff --git a/mrbgems/mruby-objectspace/test/objectspace.rb b/mrbgems/mruby-objectspace/test/objectspace.rb index 610cdfbfa..c8f0c4d24 100644 --- a/mrbgems/mruby-objectspace/test/objectspace.rb +++ b/mrbgems/mruby-objectspace/test/objectspace.rb @@ -1,4 +1,4 @@ -# coding: utf-8 +# coding: cp932 assert('ObjectSpace.count_objects') do h = {} f = Fiber.new {} if Object.const_defined?(:Fiber) @@ -134,71 +134,4 @@ assert 'ObjectSpace.memsize_of' do #hash assert_not_equal ObjectSpace.memsize_of({}), 0, 'empty hash size not zero' - - # recursion - foo_str = 'foo' * 10 - bar_str = 'bar' * 10 - caz_str = 'caz' * 10 - fbc_ary = [foo_str, bar_str, caz_str] - assert_operator ObjectSpace.memsize_of(fbc_ary), - :<, - ObjectSpace.memsize_of(fbc_ary, recurse: true), - 'basic array recursion' - - big_ary = [ 'a' * 10, - [ 'b' * 10, - [ 'c' * 10, - [ 'd' * 10, - [ 'e' * 10, - [ 'f' * 10, - ['g' * 10] - ] * 10, - ] * 10, - ] * 10, - ] * 10, - ] * 10, - ] * 10 - assert_operator ObjectSpace.memsize_of(big_ary), - :<, - ObjectSpace.memsize_of(big_ary, recurse: true), - 'large array recursion' - - assert_nothing_raised 'infinite array recursion' do - ObjectSpace.memsize_of(fbc_ary.push(fbc_ary)) - end - - basic_hsh = {a: [foo_str, bar_str], b: caz_str, 'c' => {}} - assert_operator ObjectSpace.memsize_of(basic_hsh), - :<, - ObjectSpace.memsize_of(basic_hsh, recurse: true), - 'hash recursion with basic keys' - - weird_keys = {big_ary => foo_str} - assert_operator ObjectSpace.memsize_of(weird_keys), - :<, - ObjectSpace.memsize_of(weird_keys, recurse: true), - 'hash recursion with collection as key' - - basic_hsh.store('d', basic_hsh) - assert_nothing_raised 'hash value recursion' do - ObjectSpace.memsize_of basic_hsh, recurse: true - end - - foo_klass = Class.new do - def bar= b - @bar = b - end - end - - fk_one = foo_klass.new - fk_one.bar = fbc_ary - assert_operator ObjectSpace.memsize_of(fk_one), - :<, - ObjectSpace.memsize_of(fk_one, recurse: true), - 'basic ivar recursion' - - fk_one.bar = fk_one - assert_nothing_raised 'ivar infinite recursion' do - ObjectSpace.memsize_of(fk_one, recurse: true) - end end |
