diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-08-27 21:43:20 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-10-12 18:20:06 +0900 |
| commit | 397b005715b443ff8175ffe3549f13ebfc6a9e7f (patch) | |
| tree | 51f9799d21389daee0b090915039ac613002f58f /src/kernel.c | |
| parent | bf118b90064ad41412f918458f8082c7e0e14bce (diff) | |
| download | mruby-397b005715b443ff8175ffe3549f13ebfc6a9e7f.tar.gz mruby-397b005715b443ff8175ffe3549f13ebfc6a9e7f.zip | |
Replace the implementation of method tables in classes/modules.
They are basically the copy of instance variable tables. On my Linux
box, memory consumption of `mrbtest` measured by `valgrind` is:
- old: 17,683,830 bytes
- new: 14,283,749 bytes
Diffstat (limited to 'src/kernel.c')
| -rw-r--r-- | src/kernel.c | 191 |
1 files changed, 1 insertions, 190 deletions
diff --git a/src/kernel.c b/src/kernel.c index a23eeea4e..c34d0bb6e 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -218,191 +218,6 @@ mrb_obj_class_m(mrb_state *mrb, mrb_value self) return mrb_obj_value(mrb_obj_class(mrb, self)); } -static struct RClass* -mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) -{ - struct RClass *klass = mrb_basic_ptr(obj)->c; - - if (klass->tt != MRB_TT_SCLASS) - return klass; - else { - /* copy singleton(unnamed) class */ - struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class); - - switch (mrb_type(obj)) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - break; - default: - clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); - break; - } - clone->super = klass->super; - if (klass->iv) { - mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass)); - mrb_obj_iv_set(mrb, (struct RObject*)clone, MRB_SYM(__attached__), obj); - } - if (klass->mt) { - clone->mt = kh_copy(mt, mrb, klass->mt); - } - else { - clone->mt = kh_init(mt, mrb); - } - clone->tt = MRB_TT_SCLASS; - return clone; - } -} - -static void -copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) -{ - struct RClass *dc = mrb_class_ptr(dst); - struct RClass *sc = mrb_class_ptr(src); - /* if the origin is not the same as the class, then the origin and - the current class need to be copied */ - if (sc->flags & MRB_FL_CLASS_IS_PREPENDED) { - struct RClass *c0 = sc->super; - struct RClass *c1 = dc; - - /* copy prepended iclasses */ - while (!(c0->flags & MRB_FL_CLASS_IS_ORIGIN)) { - c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); - c1 = c1->super; - c0 = c0->super; - } - c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); - c1->super->flags |= MRB_FL_CLASS_IS_ORIGIN; - } - if (sc->mt) { - dc->mt = kh_copy(mt, mrb, sc->mt); - } - else { - dc->mt = kh_init(mt, mrb); - } - dc->super = sc->super; - MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); -} - -static mrb_value mrb_obj_init_copy(mrb_state *mrb, mrb_value self); - -static void -init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) -{ - switch (mrb_type(obj)) { - case MRB_TT_ICLASS: - copy_class(mrb, dest, obj); - return; - case MRB_TT_CLASS: - case MRB_TT_MODULE: - copy_class(mrb, dest, obj); - mrb_iv_copy(mrb, dest, obj); - mrb_iv_remove(mrb, dest, MRB_SYM(__classname__)); - break; - case MRB_TT_OBJECT: - case MRB_TT_SCLASS: - case MRB_TT_HASH: - case MRB_TT_DATA: - case MRB_TT_EXCEPTION: - mrb_iv_copy(mrb, dest, obj); - break; - case MRB_TT_ISTRUCT: - mrb_istruct_copy(dest, obj); - break; - - default: - break; - } - if (!mrb_func_basic_p(mrb, dest, MRB_SYM(initialize_copy), mrb_obj_init_copy)) { - mrb_funcall_id(mrb, dest, MRB_SYM(initialize_copy), 1, obj); - } -} - -/* 15.3.1.3.8 */ -/* - * call-seq: - * obj.clone -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. Copies - * the frozen state of <i>obj</i>. See also the discussion - * under <code>Object#dup</code>. - * - * class Klass - * attr_accessor :str - * end - * s1 = Klass.new #=> #<Klass:0x401b3a38> - * s1.str = "Hello" #=> "Hello" - * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> - * s2.str[1,4] = "i" #=> "i" - * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" - * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - * - * Some Class(True False Nil Symbol Integer Float) Object cannot clone. - */ -MRB_API mrb_value -mrb_obj_clone(mrb_state *mrb, mrb_value self) -{ - struct RObject *p; - mrb_value clone; - - if (mrb_immediate_p(self)) { - return self; - } - if (mrb_sclass_p(self)) { - mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); - } - p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); - p->c = mrb_singleton_class_clone(mrb, self); - mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); - clone = mrb_obj_value(p); - init_copy(mrb, clone, self); - p->flags |= mrb_obj_ptr(self)->flags & MRB_FL_OBJ_IS_FROZEN; - - return clone; -} - -/* 15.3.1.3.9 */ -/* - * call-seq: - * obj.dup -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. - * <code>dup</code> copies the frozen state of <i>obj</i>. See also - * the discussion under <code>Object#clone</code>. In general, - * <code>clone</code> and <code>dup</code> may have different semantics - * in descendant classes. While <code>clone</code> is used to duplicate - * an object, including its internal state, <code>dup</code> typically - * uses the class of the descendant object to create the new instance. - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - */ - -MRB_API mrb_value -mrb_obj_dup(mrb_state *mrb, mrb_value obj) -{ - struct RBasic *p; - mrb_value dup; - - if (mrb_immediate_p(obj)) { - return obj; - } - if (mrb_sclass_p(obj)) { - mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); - } - p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj)); - dup = mrb_obj_value(p); - init_copy(mrb, dup, obj); - - return dup; -} - static mrb_value mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj) { @@ -493,7 +308,7 @@ mrb_obj_hash(mrb_state *mrb, mrb_value self) } /* 15.3.1.3.16 */ -static mrb_value +mrb_value mrb_obj_init_copy(mrb_state *mrb, mrb_value self) { mrb_value orig = mrb_get_arg1(mrb); @@ -505,7 +320,6 @@ mrb_obj_init_copy(mrb_state *mrb, mrb_value self) return self; } - MRB_API mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c) { @@ -568,9 +382,6 @@ mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, c)); } -KHASH_DECLARE(st, mrb_sym, char, FALSE) -KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal) - /* 15.3.1.3.32 */ /* * call_seq: |
