[前][次][番号順一覧][スレッド一覧]

ruby-changes:58040

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 30 Sep 2019 11:03:24 +0900 (JST)
Subject: [ruby-changes:58040] 3207979278 (master): refactor delete rb_method_definition_set

https://git.ruby-lang.org/ruby.git/commit/?id=3207979278

From 3207979278bea11c50cb84f4044047b9c503230b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Tue, 24 Sep 2019 15:41:52 +0900
Subject: refactor delete rb_method_definition_set

Instead of destructively write fields of method entries, create a
new entry and let it overwrite its owner.

diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 0919f6e..0a43f94 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -20,7 +20,7 @@ https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L20
 #include "debug_counter.h"
 
 extern const rb_method_definition_t *rb_method_definition_create(rb_method_type_t type, ID mid, const void *opts);
-extern void rb_method_definition_set(const rb_method_entry_t *me, const rb_method_definition_t *def);
+extern void rb_method_entry_spoof(const rb_method_entry_t *me);
 extern int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2);
 extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj,
                                          int argc, const VALUE *argv, int priv);
@@ -2574,32 +2574,39 @@ find_defined_class_by_owner(VALUE current_class, VALUE target_owner) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2574
     return current_class; /* maybe module function */
 }
 
-static const rb_callable_method_entry_t *
-aliased_callable_method_entry(const rb_callable_method_entry_t *me)
+static const void*
+aliased_callable_method_entry0(const rb_method_entry_t *me)
 {
     const rb_method_entry_t *orig_me = me->def->body.alias.original_me;
     const rb_callable_method_entry_t *cme;
 
-    if (orig_me->defined_class == 0) {
+    if (orig_me->defined_class != 0) {
+        VM_ASSERT(callable_method_entry_p(orig_me));
+        return orig_me;
+    }
+    else {
 	VALUE defined_class = find_defined_class_by_owner(me->defined_class, orig_me->owner);
 	VM_ASSERT(RB_TYPE_P(orig_me->owner, T_MODULE));
 	cme = rb_method_entry_complement_defined_class(orig_me, me->called_id, defined_class);
-
-	if (me->def->alias_count + me->def->complemented_count == 0) {
-	    RB_OBJ_WRITE(me, &me->def->body.alias.original_me, cme);
-	}
-	else {
-	    const rb_method_definition_t *def =
-                rb_method_definition_create(VM_METHOD_TYPE_ALIAS, me->def->original_id, cme);
-            rb_method_definition_set((rb_method_entry_t *)me, def);
-	}
-    }
-    else {
-	cme = (const rb_callable_method_entry_t *)orig_me;
-    }
-
-    VM_ASSERT(callable_method_entry_p(cme));
-    return cme;
+        rb_method_entry_t *ret =
+            rb_method_entry_create(
+                me->called_id,
+                me->owner,
+                me->defined_class,
+                rb_method_definition_create(
+                    VM_METHOD_TYPE_ALIAS,
+                    me->def->original_id,
+                    cme));
+        METHOD_ENTRY_FLAGS_COPY(ret, (const void*)me);
+        rb_method_entry_spoof(ret);
+        return ret;
+    }
+}
+
+static const rb_callable_method_entry_t*
+aliased_callable_method_entry(const rb_callable_method_entry_t *me)
+{
+    return aliased_callable_method_entry0((const void*)me);
 }
 
 static const rb_callable_method_entry_t *
diff --git a/vm_method.c b/vm_method.c
index bde8c1b..7bb675e 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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L443
 }
 
 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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L498
     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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L557
     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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L580
                     .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) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L598
     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 https://github.com/ruby/ruby/blob/trunk/vm_method.c#L734
     }
 
     if (make_refined) {
-	make_method_entry_refined(klass, me);
+        me = make_method_entry_refined(klass, me);
     }
 
     rb_id_table_insert(mtbl, mid, (VALUE)me);
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]