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

ruby-changes:57959

From: Aaron <ko1@a...>
Date: Fri, 27 Sep 2019 06:07:54 +0900 (JST)
Subject: [ruby-changes:57959] 50fadefb7e (master): Scan the ISEQ arena for markables and mark them

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

From 50fadefb7ed275148b2266712b923b8cca1ed785 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Mon, 16 Sep 2019 17:19:44 -0700
Subject: Scan the ISEQ arena for markables and mark them

This commit scans the ISEQ arena for objects that can be marked and
marks them.  This should make the mark array unnecessary.

diff --git a/compile.c b/compile.c
index 9ba55e5..f441b7d 100644
--- a/compile.c
+++ b/compile.c
@@ -8953,6 +8953,57 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords) https://github.com/ruby/ruby/blob/trunk/compile.c#L8953
 }
 
 void
+rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
+{
+    INSN *iobj = 0;
+    size_t size = sizeof(INSN);
+    unsigned int pos = 0;
+
+    while (storage) {
+#ifdef STRICT_ALIGNMENT
+        size_t padding = calc_padding((void *)&storage->buff[pos], size);
+#else
+        const size_t padding = 0; /* expected to be optimized by compiler */
+#endif /* STRICT_ALIGNMENT */
+        size_t offset = pos + size + padding;
+        if (offset > storage->size || offset > storage->pos) {
+            pos = 0;
+            storage = storage->next;
+        } else {
+#ifdef STRICT_ALIGNMENT
+            pos += (int)padding;
+#endif /* STRICT_ALIGNMENT */
+
+            iobj = (INSN *)&storage->buff[pos];
+
+            if (iobj->operands) {
+                int j;
+                const char *types = insn_op_types(iobj->insn_id);
+
+                for(j = 0; types[j]; j++) {
+                    char type = types[j];
+                    switch(type) {
+                        case TS_CDHASH:
+                        case TS_ISEQ:
+                        case TS_VALUE:
+                        {
+                            VALUE op = OPERAND_AT(iobj, j);
+                            if (!SPECIAL_CONST_P(op)) {
+                                rb_gc_mark(op);
+                            }
+                            break;
+                        }
+                        default:
+                            break;
+                    }
+                }
+            }
+            pos += (int)size;
+        }
+    }
+}
+
+void
 rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params,
 			 VALUE exception, VALUE body)
 {
diff --git a/iseq.c b/iseq.c
index b5417cb..f76b350 100644
--- a/iseq.c
+++ b/iseq.c
@@ -336,6 +336,9 @@ rb_iseq_mark(const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L336
     }
     else if (FL_TEST_RAW(iseq, ISEQ_USE_COMPILE_DATA)) {
 	const struct iseq_compile_data *const compile_data = ISEQ_COMPILE_DATA(iseq);
+
+        rb_iseq_mark_insn_storage(compile_data->insn.storage_head);
+
         if (RTEST(compile_data->mark_ary)) {
             rb_gc_mark(compile_data->mark_ary);
         }
diff --git a/iseq.h b/iseq.h
index 8bb4f30..f1d446c 100644
--- a/iseq.h
+++ b/iseq.h
@@ -174,6 +174,7 @@ VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq); https://github.com/ruby/ruby/blob/trunk/iseq.h#L174
 void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
 			    VALUE locals, VALUE args,
 			    VALUE exception, VALUE body);
+void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *arena);
 
 /* iseq.c */
 VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
-- 
cgit v0.10.2


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

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