diff options
author | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-09-24 15:41:52 +0900 |
---|---|---|
committer | 卜部昌平 <shyouhei@ruby-lang.org> | 2019-09-30 10:26:38 +0900 |
commit | 3207979278bea11c50cb84f4044047b9c503230b (patch) | |
tree | 3aacc896e9801b42f0aa79931c78f335004eee89 /vm_method.c | |
parent | 595b3c4fddc5cde58add2fa2637acb2664694194 (diff) |
refactor delete rb_method_definition_set
Instead of destructively write fields of method entries, create a
new entry and let it overwrite its owner.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2486
Diffstat (limited to 'vm_method.c')
-rw-r--r-- | vm_method.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/vm_method.c b/vm_method.c index bde8c1bd26..7bb675ebcc 100644 --- a/vm_method.c +++ b/vm_method.c @@ -443,10 +443,13 @@ rb_method_definition_new(rb_method_type_t type, ID mid, const void *opts) } MJIT_FUNC_EXPORTED void -rb_method_definition_set(const rb_method_entry_t *me, const rb_method_definition_t *def) +rb_method_entry_spoof(const rb_method_entry_t *me) { - memcpy((void *)&me->def, &def, sizeof def); - method_definition_reset(me); + VALUE v = (VALUE)me; + VALUE o = me->owner; + rb_id_table_insert(RCLASS_M_TBL(o), me->called_id, v); + RB_OBJ_WRITTEN(o, Qundef, v); + rb_clear_method_cache_by_class(o); } MJIT_FUNC_EXPORTED const rb_method_definition_t * @@ -495,7 +498,7 @@ filter_defined_class(VALUE klass) rb_bug("filter_defined_class: %s", rb_obj_info(klass)); } -rb_method_entry_t * +MJIT_FUNC_EXPORTED rb_method_entry_t * rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def) { rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def); @@ -554,11 +557,11 @@ rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src) METHOD_ENTRY_FLAGS_COPY(dst, src); } -static void +static rb_method_entry_t* make_method_entry_refined(VALUE owner, rb_method_entry_t *me) { if (me->def->type == VM_METHOD_TYPE_REFINED) { - return; + return me; } else { rb_vm_check_redefinition_opt_method(me, me->owner); @@ -577,8 +580,15 @@ make_method_entry_refined(VALUE owner, rb_method_entry_t *me) .owner = owner, } ); - rb_method_definition_set(me, def); - METHOD_ENTRY_VISI_SET(me, METHOD_VISI_PUBLIC); + rb_method_entry_t *new_me = + rb_method_entry_create( + me->called_id, + me->owner, + me->defined_class, + def); + METHOD_ENTRY_FLAGS_COPY(new_me, me); + METHOD_ENTRY_VISI_SET(new_me, METHOD_VISI_PUBLIC); + return new_me; } } @@ -588,7 +598,8 @@ rb_add_refined_method_entry(VALUE refined_class, ID mid) rb_method_entry_t *me = lookup_method_table(refined_class, mid); if (me) { - make_method_entry_refined(refined_class, me); + me = make_method_entry_refined(refined_class, me); + rb_method_entry_spoof(me); rb_clear_method_cache_by_class(refined_class); } else { @@ -723,7 +734,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil } if (make_refined) { - make_method_entry_refined(klass, me); + me = make_method_entry_refined(klass, me); } rb_id_table_insert(mtbl, mid, (VALUE)me); |