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

ruby-changes:65126

From: Koichi <ko1@a...>
Date: Wed, 3 Feb 2021 17:28:36 +0900 (JST)
Subject: [ruby-changes:65126] 583f364f71 (master): use goto intead of recursion on vm_call0_body()

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

From 583f364f7187337b284061b78a47b29875398e33 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Wed, 3 Feb 2021 15:29:26 +0900
Subject: use goto intead of recursion on vm_call0_body()

"alias" type method entries can chain another aliased method
so that machine stack can be overflow on nested alias chain.
http://ci.rvm.jp/results/trunk-repeat20@phosphorus-docker/3344209

This patch fix this issue by use goto instead of recursion if possible.

TODO: Essentially, the alias method should not points another aliased
method entry. Try to fix it later.
---
 vm_eval.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/vm_eval.c b/vm_eval.c
index 0f3d1e4..eae9464 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -157,6 +157,8 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L157
     const struct rb_callcache *cc = calling->cc;
     VALUE ret;
 
+  retry:
+
     switch (vm_cc_cme(cc)->def->type) {
       case VM_METHOD_TYPE_ISEQ:
 	{
@@ -222,7 +224,20 @@ vm_call0_body(rb_execution_context_t *ec, struct rb_calling_info *calling, const https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L224
             return vm_call0_super(ec, calling, argv, klass, 0);
 	}
       case VM_METHOD_TYPE_ALIAS:
-        return vm_call0_cme(ec, calling, argv, aliased_callable_method_entry(vm_cc_cme(cc)));
+        {
+            const rb_callable_method_entry_t *cme = vm_cc_cme(cc);
+            const rb_callable_method_entry_t *orig_cme = aliased_callable_method_entry(cme);
+
+            if (cme == orig_cme) rb_bug("same!!");
+
+            if (vm_cc_markable(cc)) {
+                return vm_call0_cme(ec, calling, argv, orig_cme);
+            }
+            else {
+                *((const rb_callable_method_entry_t **)&cc->cme_) = orig_cme;
+                goto retry;
+            }
+        }
       case VM_METHOD_TYPE_MISSING:
 	{
             vm_passed_block_handler_set(ec, calling->block_handler);
-- 
cgit v1.1


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

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