From 639703cf018f54a5962a19fc8df5bcfa48308238 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 Jul 2020 23:32:30 +0900 Subject: Remove unnecessory methods in `mruby-objectspace`; ref #5041 The `ObjectSpace#memsize_of` and `ObjectSpace#memsize_of_all` in `mruby-objectspace` ware migrated to `mruby-os-memsize` mrbgem. --- mrbgems/mruby-objectspace/src/mruby_objectspace.c | 211 ---------------------- 1 file changed, 211 deletions(-) diff --git a/mrbgems/mruby-objectspace/src/mruby_objectspace.c b/mrbgems/mruby-objectspace/src/mruby_objectspace.c index 6804a99ae..408d3c0af 100644 --- a/mrbgems/mruby-objectspace/src/mruby_objectspace.c +++ b/mrbgems/mruby-objectspace/src/mruby_objectspace.c @@ -172,223 +172,12 @@ os_each_object(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(d.count); } -static mrb_int -os_memsize_of_ivars(mrb_state* mrb, mrb_value obj) -{ - return mrb_obj_iv_tbl_memsize(mrb, obj); -} - -static mrb_int -os_memsize_of_irep(mrb_state* state, const struct mrb_irep *irep) -{ - 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++) { - size += os_memsize_of_irep(state, irep->reps[i]); - } - return size; -} - -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); - - size = sizeof(struct RProc); - if (!MRB_PROC_CFUNC_P(proc)) size += os_memsize_of_irep(mrb, proc->body.irep); - return size; -} - -static mrb_int -os_memsize_of_object(mrb_state* mrb, mrb_value obj) -{ - mrb_int size = 0; - - switch(mrb_type(obj)) { - case MRB_TT_STRING: - size += mrb_objspace_page_slot_size(); - if (!RSTR_EMBED_P(RSTRING(obj)) && !RSTR_SHARED_P(RSTRING(obj))) { - size += RSTRING_CAPA(obj); - } - break; - case MRB_TT_CLASS: - case MRB_TT_MODULE: - case MRB_TT_SCLASS: - case MRB_TT_ICLASS: - size += mrb_gc_mark_mt_size(mrb, mrb_class_ptr(obj)) * sizeof(mrb_method_t); - /* fall through */ - case MRB_TT_EXCEPTION: - case MRB_TT_OBJECT: { - 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")) || - mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "Method"))){ - size += os_memsize_of_method(mrb, obj); - } - break; - } - case MRB_TT_HASH: { - size += mrb_objspace_page_slot_size() + - mrb_os_memsize_of_hash_table(obj); - break; - } - case MRB_TT_ARRAY: { - 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*/ - 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); - 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: - size += mrb_objspace_page_slot_size(); - break; -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING - size += mrb_objspace_page_slot_size() + - sizeof(struct RFloat); -#endif - break; -#endif - case MRB_TT_RANGE: -#ifndef MRB_RANGE_EMBED - size += mrb_objspace_page_slot_size() + - sizeof(struct mrb_range_edges); -#endif - break; - case MRB_TT_FIBER: { - struct RFiber* f = (struct RFiber *)mrb_ptr(obj); - ptrdiff_t stack_size = f->cxt->stend - f->cxt->stbase; - ptrdiff_t ci_size = f->cxt->ciend - f->cxt->cibase; - - size += mrb_objspace_page_slot_size() + - sizeof(struct RFiber) + - sizeof(struct mrb_context) + - sizeof(struct RProc *) * f->cxt->esize + - sizeof(uint16_t *) * f->cxt->rsize + - sizeof(mrb_value) * stack_size + - sizeof(mrb_callinfo) * ci_size; - break; - } - case MRB_TT_ISTRUCT: - size += mrb_objspace_page_slot_size(); - break; - /* zero heap size types. - * immediate VM stack values, contained within mrb_state, or on C stack */ - case MRB_TT_TRUE: - case MRB_TT_FALSE: - case MRB_TT_FIXNUM: - case MRB_TT_BREAK: - case MRB_TT_CPTR: - case MRB_TT_SYMBOL: - case MRB_TT_FREE: - case MRB_TT_UNDEF: - case MRB_TT_ENV: - /* never used, silences compiler warning - * not having a default: clause lets the compiler tell us when there is a new - * TT not accounted for */ - case MRB_TT_MAXDEFINE: - break; - } - return size; -} - -/* - * call-seq: - * ObjectSpace.memsize_of(obj, recurse: false) -> Numeric - * - * Returns the amount of heap memory allocated for object in size_t units. - * - * The return value depends on the definition of size_t on that platform, - * therefore the value is not comparable across platform types. - * - * Immediate values such as integers, booleans, symbols and unboxed float numbers - * return 0. Additionally special objects which are small enough to fit inside an - * object pointer, termed embedded objects, will return the size of the object pointer. - * Strings and arrays below a compile-time defined size may be embedded. - * - * Setting recurse: true descends into instance variables, array members, - * hash keys and hash values recursively, calculating the child objects and adding to - * the final sum. It avoids infinite recursion and over counting objects by - * internally tracking discovered object ids. - * - */ - -static mrb_value -os_memsize_of(mrb_state *mrb, mrb_value self) -{ - mrb_int total; - mrb_value obj; - - mrb_get_args(mrb, "o", &obj); - - total = os_memsize_of_object(mrb, obj); - return mrb_fixnum_value(total); -} - -struct os_memsize_of_all_cb_data { - mrb_int t; - struct RClass *type; -}; - -static int -os_memsize_of_all_cb(mrb_state *mrb, struct RBasic *obj, void *d) -{ - struct os_memsize_of_all_cb_data *data = (struct os_memsize_of_all_cb_data *)d; - switch (obj->tt) { - case MRB_TT_FREE: case MRB_TT_ENV: - case MRB_TT_BREAK: case MRB_TT_ICLASS: - /* internal objects that should not be counted */ - return MRB_EACH_OBJ_OK; - default: - break; - } - /* skip Proc objects for methods */ - if (obj->c == NULL) return 0; - if (data->type == NULL || mrb_obj_is_kind_of(mrb, mrb_obj_value(obj), data->type)) - data->t += os_memsize_of_object(mrb, mrb_obj_value(obj)); - return MRB_EACH_OBJ_OK; -} - -/* - * call-seq: - * ObjectSpace.memsize_of_all([klass]) -> Numeric - * - * Return consuming memory size of all living objects of type klass. - * - */ - -static mrb_value -os_memsize_of_all(mrb_state *mrb, mrb_value self) -{ - struct os_memsize_of_all_cb_data data = { 0 }; - mrb_get_args(mrb, "|c", &data.type); - mrb_objspace_each_objects(mrb, os_memsize_of_all_cb, &data); - return mrb_fixnum_value(data.t); -} - void mrb_mruby_objectspace_gem_init(mrb_state *mrb) { struct RClass *os = mrb_define_module(mrb, "ObjectSpace"); mrb_define_class_method(mrb, os, "count_objects", os_count_objects, MRB_ARGS_OPT(1)); mrb_define_class_method(mrb, os, "each_object", os_each_object, MRB_ARGS_OPT(1)); - mrb_define_class_method(mrb, os, "memsize_of", os_memsize_of, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, os, "memsize_of_all", os_memsize_of_all, MRB_ARGS_OPT(1)); } void -- cgit v1.2.3 From 97f71b5a67d753c0949e31c7a90efb821387c637 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 Jul 2020 23:37:39 +0900 Subject: Fixed garbled characters; ref #5041 --- mrbgems/mruby-os-memsize/test/memsize.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-os-memsize/test/memsize.rb b/mrbgems/mruby-os-memsize/test/memsize.rb index c6b1b7b2d..9e8d41165 100644 --- a/mrbgems/mruby-os-memsize/test/memsize.rb +++ b/mrbgems/mruby-os-memsize/test/memsize.rb @@ -12,7 +12,7 @@ assert 'ObjectSpace.memsize_of' do assert_not_equal ObjectSpace.memsize_of('a'), 0, 'memsize of str' if __ENCODING__ == "UTF-8" - assert_not_equal ObjectSpace.memsize_of("縺薙s縺ォ縺。縺ッ荳也阜"), 0, 'memsize of utf8 str' + assert_not_equal ObjectSpace.memsize_of("こんにちは世界"), 0, 'memsize of utf8 str' end # class defs -- cgit v1.2.3 From 2b588b8566a50ed33f4f9878aa10fdbe05a3feeb Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 Jul 2020 23:40:37 +0900 Subject: Add NUL terminator to string object size calculation; ref #5032 --- mrbgems/mruby-os-memsize/src/memsize.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mrbgems/mruby-os-memsize/src/memsize.c b/mrbgems/mruby-os-memsize/src/memsize.c index d82c6b7ed..70887a3ae 100644 --- a/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mrbgems/mruby-os-memsize/src/memsize.c @@ -54,6 +54,7 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) size += mrb_objspace_page_slot_size(); if (!RSTR_EMBED_P(RSTRING(obj)) && !RSTR_SHARED_P(RSTRING(obj))) { size += RSTRING_CAPA(obj); + size++; /* NUL terminator */ } break; case MRB_TT_CLASS: -- cgit v1.2.3 From c9ba761b9e23e720da9200be1c4df103a04e51b2 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 Jul 2020 23:45:53 +0900 Subject: Support without `mruby-method` for `mruby-os-memsize`; ref #5032 --- mrbgems/mruby-os-memsize/src/memsize.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-os-memsize/src/memsize.c b/mrbgems/mruby-os-memsize/src/memsize.c index 70887a3ae..14f90109d 100644 --- a/mrbgems/mruby-os-memsize/src/memsize.c +++ b/mrbgems/mruby-os-memsize/src/memsize.c @@ -44,6 +44,19 @@ os_memsize_of_method(mrb_state* mrb, mrb_value method_obj) return size; } +static mrb_bool +obj_is_kind_of_checked(mrb_state *mrb, mrb_value obj, const char *classname) +{ + mrb_value objclass = mrb_obj_value(mrb->object_class); + + if (mrb_const_defined(mrb, objclass, mrb_intern_cstr(mrb, classname))) { + struct RClass *klass = mrb_class_get(mrb, classname); + return mrb_obj_is_kind_of(mrb, obj, klass); + } + + return FALSE; +} + static mrb_int os_memsize_of_object(mrb_state* mrb, mrb_value obj) { @@ -67,8 +80,8 @@ os_memsize_of_object(mrb_state* mrb, mrb_value obj) case MRB_TT_OBJECT: { 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")) || - mrb_obj_is_kind_of(mrb, obj, mrb_class_get(mrb, "Method"))){ + if (obj_is_kind_of_checked(mrb, obj, "UnboundMethod") || + obj_is_kind_of_checked(mrb, obj, "Method")) { size += os_memsize_of_method(mrb, obj); } break; -- cgit v1.2.3 From 5c2b11d21581cf472929b21f28f1a388a16f0865 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 Jul 2020 23:55:26 +0900 Subject: Avoid using FPU with `mruby-os-memsize`; ref #5032 And, in the calculation of the instance variable size, the fraction was always rounded down because of division of integers, so fix it. At the same time, test items that are no longer passed due to this change are deleted. --- mrbgems/mruby-os-memsize/test/memsize.rb | 14 -------------- src/variable.c | 7 +++---- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/mrbgems/mruby-os-memsize/test/memsize.rb b/mrbgems/mruby-os-memsize/test/memsize.rb index 9e8d41165..6be8f1b06 100644 --- a/mrbgems/mruby-os-memsize/test/memsize.rb +++ b/mrbgems/mruby-os-memsize/test/memsize.rb @@ -22,20 +22,6 @@ assert 'ObjectSpace.memsize_of' do empty_class_def_size = ObjectSpace.memsize_of Class.new assert_not_equal empty_class_def_size, 0, 'Class def not zero' - class_without_methods = Class.new do - @a = 1 - @b = 2 - end - class_total_size = empty_class_def_size + (int_size * 2) - assert_equal ObjectSpace.memsize_of(class_without_methods), class_total_size, 'class without methods size' - - module_without_methods = Module.new do - @a = 1 - @b = 2 - end - module_total_size = empty_class_def_size + (int_size * 2) - assert_equal ObjectSpace.memsize_of(module_without_methods), module_total_size, 'module without methods size' - proc_size = ObjectSpace.memsize_of Proc.new { x = 1; x } assert_not_equal proc_size, 0 diff --git a/src/variable.c b/src/variable.c index 0755f7d92..8c16b2d4f 100644 --- a/src/variable.c +++ b/src/variable.c @@ -4,7 +4,6 @@ ** See Copyright Notice in mruby.h */ -#include #include #include #include @@ -1132,9 +1131,9 @@ mrb_class_find_path(mrb_state *mrb, struct RClass *c) mrb_int mrb_obj_iv_tbl_memsize(mrb_state* mrb, mrb_value obj) { - return sizeof(iv_tbl) + - (sizeof(segment) * ceil(iv_size(mrb, mrb_obj_ptr(obj)->iv)/ - MRB_IV_SEGMENT_SIZE)); + size_t ivsize = iv_size(mrb, mrb_obj_ptr(obj)->iv); + size_t ivsegs = (ivsize + MRB_IV_SEGMENT_SIZE - 1) / MRB_IV_SEGMENT_SIZE; + return sizeof(iv_tbl) + (sizeof(segment) * ivsegs); } #define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) -- cgit v1.2.3 From ccd5f203bf1e7c54cb08fc9eecfe2772277b5a58 Mon Sep 17 00:00:00 2001 From: dearblue Date: Wed, 22 Jul 2020 00:18:28 +0900 Subject: Improve prototype for `mrb_objspace_page_slot_size()`; ref #5032 If it qualify a return type that is not a pointer with `const`, the compiler ignores it. --- include/mruby/gc.h | 2 +- src/gc.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mruby/gc.h b/include/mruby/gc.h index 3b2ded9d4..1beffba2a 100644 --- a/include/mruby/gc.h +++ b/include/mruby/gc.h @@ -21,7 +21,7 @@ struct mrb_state; #define MRB_EACH_OBJ_BREAK 1 typedef int (mrb_each_object_callback)(struct mrb_state *mrb, struct RBasic *obj, void *data); void mrb_objspace_each_objects(struct mrb_state *mrb, mrb_each_object_callback *callback, void *data); -const mrb_int mrb_objspace_page_slot_size(); +mrb_int mrb_objspace_page_slot_size(void); MRB_API void mrb_free_context(struct mrb_state *mrb, struct mrb_context *c); #ifndef MRB_GC_ARENA_SIZE diff --git a/src/gc.c b/src/gc.c index fd4fb2406..fa7f30889 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1599,8 +1599,8 @@ mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, vo } } -const mrb_int -mrb_objspace_page_slot_size() +mrb_int +mrb_objspace_page_slot_size(void) { const mrb_int i = sizeof(RVALUE); return i; -- cgit v1.2.3