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

ruby-changes:69781

From: Koichi <ko1@a...>
Date: Wed, 17 Nov 2021 22:22:01 +0900 (JST)
Subject: [ruby-changes:69781] b2255153cf (master): `vm_empty_cc_for_super`

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

From b2255153cf2fe9d7b851c59cc09b358c0630e0a2 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Tue, 16 Nov 2021 17:57:49 +0900
Subject: `vm_empty_cc_for_super`

Same as `vm_empty_cc`, introduce a global variable which has
`.call_ = vm_call_super_method`. Use it if the `cme == NULL` on
`vm_search_super_method`.
---
 vm.c            | 16 ++++++++++++++++
 vm_callinfo.h   |  1 +
 vm_insnhelper.c | 37 +++++++++++++++++++++++++++----------
 3 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/vm.c b/vm.c
index f13e07cef3d..a868355bbe5 100644
--- a/vm.c
+++ b/vm.c
@@ -439,6 +439,16 @@ static const struct rb_callcache vm_empty_cc = { https://github.com/ruby/ruby/blob/trunk/vm.c#L439
     }
 };
 
+static const struct rb_callcache vm_empty_cc_for_super = {
+    .flags = T_IMEMO | (imemo_callcache << FL_USHIFT) | VM_CALLCACHE_UNMARKABLE,
+    .klass = Qfalse,
+    .cme_  = NULL,
+    .call_ = vm_call_super_method,
+    .aux_  = {
+        .v = Qfalse,
+    }
+};
+
 static void thread_free(void *ptr);
 
 void
@@ -4176,6 +4186,12 @@ rb_vm_empty_cc(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L4186
     return &vm_empty_cc;
 }
 
+MJIT_FUNC_EXPORTED const struct rb_callcache *
+rb_vm_empty_cc_for_super(void)
+{
+    return &vm_empty_cc_for_super;
+}
+
 #endif /* #ifndef MJIT_HEADER */
 
 #include "vm_call_iseq_optimized.inc" /* required from vm_insnhelper.c */
diff --git a/vm_callinfo.h b/vm_callinfo.h
index fa35c98d174..2641ee79c52 100644
--- a/vm_callinfo.h
+++ b/vm_callinfo.h
@@ -382,6 +382,7 @@ vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *c https://github.com/ruby/ruby/blob/trunk/vm_callinfo.h#L382
 }
 
 extern const struct rb_callcache *rb_vm_empty_cc(void);
+extern const struct rb_callcache *rb_vm_empty_cc_for_super(void);
 #define vm_cc_empty() rb_vm_empty_cc()
 
 /* callcache: mutate */
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 5e5554cb675..ff02f141410 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -38,6 +38,7 @@ extern VALUE rb_make_no_method_exception(VALUE exc, VALUE format, VALUE obj, https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L38
 
 #ifndef MJIT_HEADER
 static const struct rb_callcache vm_empty_cc;
+static const struct rb_callcache vm_empty_cc_for_super;
 #endif
 
 /* control stack frame */
@@ -3711,6 +3712,11 @@ vm_call_super_method(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, st https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3712
 {
     RB_DEBUG_COUNTER_INC(ccf_super_method);
 
+    // This line is introduced to make different from `vm_call_general` because some compilers (VC we found)
+    // can merge the function and the address of the function becomes same.
+    // The address of `vm_call_super_method` is used in `search_refined_method`, so it should be different.
+    if (ec == NULL) rb_bug("unreachable");
+
     /* this check is required to distinguish with other functions. */
     VM_ASSERT(vm_cc_call(calling->cc) == vm_call_super_method);
     return vm_call_method(ec, reg_cfp, calling);
@@ -3737,6 +3743,16 @@ vm_super_outside(void) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3743
     rb_raise(rb_eNoMethodError, "super called outside of method");
 }
 
+static const struct rb_callcache *
+empty_cc_for_super(void)
+{
+#ifdef MJIT_HEADER
+    return rb_vm_empty_cc_for_super();
+#else
+    return &vm_empty_cc_for_super;
+#endif
+}
+
 static const struct rb_callcache *
 vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *cd, VALUE recv)
 {
@@ -3800,19 +3816,18 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3816
 
         // define_method can cache for different method id
         if (cached_cme == NULL) {
-            // temporary CC. revisit it
-            static const struct rb_callcache *empty_cc_for_super = NULL;
-            if (empty_cc_for_super == NULL) {
-                empty_cc_for_super = vm_cc_new(0, NULL, vm_call_super_method);
-                FL_SET_RAW((VALUE)empty_cc_for_super, VM_CALLCACHE_UNMARKABLE);
-                rb_gc_register_mark_object((VALUE)empty_cc_for_super);
-            }
-            RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc = empty_cc_for_super);
+            // empty_cc_for_super is not markable object
+            cd->cc = empty_cc_for_super();
         }
         else if (cached_cme->called_id != mid) {
             const rb_callable_method_entry_t *cme = rb_callable_method_entry(klass, mid);
-            cc = vm_cc_new(klass, cme, vm_call_super_method);
-            RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc);
+            if (cme) {
+                cc = vm_cc_new(klass, cme, vm_call_super_method);
+                RB_OBJ_WRITE(reg_cfp->iseq, &cd->cc, cc);
+            }
+            else {
+                cd->cc = cc = empty_cc_for_super();
+            }
         }
         else {
             switch (cached_cme->def->type) {
@@ -3829,6 +3844,8 @@ vm_search_super_method(const rb_control_frame_t *reg_cfp, struct rb_call_data *c https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L3844
         }
     }
 
+    VM_ASSERT((vm_cc_cme(cc), true));
+
     return cc;
 }
 
-- 
cgit v1.2.1


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

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