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

ruby-changes:72367

From: Aaron <ko1@a...>
Date: Thu, 30 Jun 2022 09:08:08 +0900 (JST)
Subject: [ruby-changes:72367] cfc8d7eaec (master): Use iseq bitmap when updating references

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

From cfc8d7eaec9cd56bcbae0389a1739495bdc58098 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Fri, 24 Jun 2022 16:37:53 -0700
Subject: Use iseq bitmap when updating references

This allows us to delete the disassembly code path for reference
updating.
---
 iseq.c | 100 ++++++++---------------------------------------------------------
 1 file changed, 12 insertions(+), 88 deletions(-)

diff --git a/iseq.c b/iseq.c
index cd20297bad..fee2627525 100644
--- a/iseq.c
+++ b/iseq.c
@@ -221,12 +221,6 @@ rb_vm_insn_addr2insn2(const void *addr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L221
 }
 #endif
 
-static VALUE
-rb_vm_insn_null_translator(const void *addr)
-{
-    return (VALUE)addr;
-}
-
 // The translator for OPT_DIRECT_THREADED_CODE and OPT_CALL_THREADED_CODE does
 // some normalization to always return the non-trace version of instructions. To
 // mirror that behavior in token-threaded environments, we normalize in this
@@ -246,85 +240,22 @@ rb_vm_insn_normalizing_translator(const void *addr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L240
 typedef VALUE iseq_value_itr_t(void *ctx, VALUE obj);
 typedef VALUE rb_vm_insns_translator_t(const void *addr);
 
-static int
-iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data, rb_vm_insns_translator_t * translator)
-{
-    VALUE insn = translator((void *)code[pos]);
-    int len = insn_len(insn);
-    int op_no;
-    const char *types = insn_op_types(insn);
-
-    for (op_no = 0; types[op_no]; op_no++) {
-	char type = types[op_no];
-	switch (type) {
-          case TS_CDHASH:
-          case TS_ISEQ:
-          case TS_VALUE:
-            {
-              VALUE op = code[pos + op_no + 1];
-              if (!SPECIAL_CONST_P(op)) {
-                  VALUE newop = func(data, op);
-                  if (newop != op) {
-                      code[pos + op_no + 1] = newop;
-                  }
-              }
-            }
-            break;
-          case TS_IC:
-            {
-                IC ic = (IC)code[pos + op_no + 1];
-                if (ic->entry) {
-                    VALUE nv = func(data, (VALUE)ic->entry);
-                    if ((VALUE)ic->entry != nv) {
-                        ic->entry = (void *)nv;
-                    }
-                }
-            }
-            break;
-          case TS_IVC:
-          case TS_ICVARC:
-            {
-                IVC ivc = (IVC)code[pos + op_no + 1];
-                if (ivc->entry) {
-                    if (RB_TYPE_P(ivc->entry->class_value, T_NONE)) {
-                        rb_bug("!! %u", ivc->entry->index);
-                    }
-                    VALUE nv = func(data, ivc->entry->class_value);
-                    if (ivc->entry->class_value != nv) {
-                        ivc->entry->class_value = nv;
-                    }
-                }
-            }
-            break;
-          case TS_ISE:
-            {
-              union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)code[pos + op_no + 1];
-              if (is->once.value) {
-                  VALUE nv = func(data, is->once.value);
-                  if (is->once.value != nv) {
-                      is->once.value = nv;
-                  }
-              }
-            }
-            break;
-          default:
-            break;
-	}
-    }
-
-    return len;
-}
-
 static inline void
-iseq_scan_bits(iseq_bits_t bits, VALUE *code, iseq_value_itr_t *func, void *data)
+iseq_scan_bits(unsigned int page, iseq_bits_t bits, VALUE *code, iseq_value_itr_t *func, void *data)
 {
     unsigned int offset;
+    unsigned int page_offset = (page * ISEQ_MBITS_BITLENGTH);
+
     while (bits) {
         offset = ntz_intptr(bits);
-        VALUE op = code[offset];
+        VALUE op = code[page_offset + offset];
         VALUE newop = func(data, op);
         if (newop != op) {
-            code[offset] = newop;
+            code[page_offset + offset] = newop;
+            if (data) {
+                VALUE *original_iseq = (VALUE *)data;
+                original_iseq[page_offset + offset] = newop;
+            }
         }
         bits ^= bits & -bits; // Reset Lowest Set Bit (BLSR)
     }
@@ -381,13 +312,13 @@ rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data) https://github.com/ruby/ruby/blob/trunk/iseq.c#L312
 
     // Embedded VALUEs
     if (ISEQ_MBITS_BUFLEN(size) == 1) {
-        iseq_scan_bits(body->mark_bits.single, code, func, data);
+        iseq_scan_bits(0, body->mark_bits.single, code, func, data);
     }
     else {
         if (body->mark_bits.list) {
             for (unsigned int i = 0; i < ISEQ_MBITS_BUFLEN(size); i++) {
                 iseq_bits_t bits = body->mark_bits.list[i];
-                iseq_scan_bits(bits, &code[i * ISEQ_MBITS_BITLENGTH], func, data);
+                iseq_scan_bits(i, bits, code, func, data);
             }
         }
     }
@@ -463,15 +394,8 @@ rb_iseq_update_references(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/iseq.c#L394
             }
         }
         if (FL_TEST((VALUE)iseq, ISEQ_MARKABLE_ISEQ)) {
-            rb_iseq_each_value(iseq, update_each_insn_value, NULL);
             VALUE *original_iseq = ISEQ_ORIGINAL_ISEQ(iseq);
-            if (original_iseq) {
-                size_t n = 0;
-                const unsigned int size = body->iseq_size;
-                while (n < size) {
-                    n += iseq_extract_values(original_iseq, n, update_each_insn_value, NULL, rb_vm_insn_null_translator);
-                }
-            }
+            rb_iseq_each_value(iseq, update_each_insn_value, (void *)original_iseq);
         }
 
         if (body->param.flags.has_kw && ISEQ_COMPILE_DATA(iseq) == NULL) {
-- 
cgit v1.2.1


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

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