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

ruby-changes:72595

From: Jemma <ko1@a...>
Date: Tue, 19 Jul 2022 06:06:49 +0900 (JST)
Subject: [ruby-changes:72595] 85ea46730d (master): Separate TS_IVC and TS_ICVARC in is_entries buffers

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

From 85ea46730deff70172a9f50172f0011a7401f371 Mon Sep 17 00:00:00 2001
From: Jemma Issroff <jemmaissroff@g...>
Date: Mon, 18 Jul 2022 15:38:12 -0400
Subject: Separate TS_IVC and TS_ICVARC in is_entries buffers

This allows us to treat cvar caches differently than ivar caches.
---
 compile.c                               | 35 +++++++++++++++++++++++++++++----
 iseq.c                                  | 19 ++++++++++++++----
 tool/ruby_vm/views/_insn_type_chars.erb |  3 ++-
 vm_core.h                               | 11 ++++++-----
 4 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/compile.c b/compile.c
index 17f870e3e5..f95b3bb143 100644
--- a/compile.c
+++ b/compile.c
@@ -2074,6 +2074,25 @@ get_ivar_ic_value(rb_iseq_t *iseq,ID id) https://github.com/ruby/ruby/blob/trunk/compile.c#L2074
     return val;
 }
 
+static inline VALUE
+get_cvar_ic_value(rb_iseq_t *iseq,ID id)
+{
+    VALUE val;
+    struct rb_id_table *tbl = ISEQ_COMPILE_DATA(iseq)->ivar_cache_table;
+    if (tbl) {
+	if (rb_id_table_lookup(tbl,id,&val)) {
+	    return val;
+	}
+    }
+    else {
+	tbl = rb_id_table_create(1);
+	ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = tbl;
+    }
+    val = INT2FIX(ISEQ_BODY(iseq)->icvarc_size++);
+    rb_id_table_insert(tbl,id,val);
+    return val;
+}
+
 #define BADINSN_DUMP(anchor, list, dest) \
     dump_disasm_list_with_cursor(FIRST_ELEMENT(anchor), list, dest)
 
@@ -2412,7 +2431,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) https://github.com/ruby/ruby/blob/trunk/compile.c#L2431
 			    }
 			    break;
 			}
-                      /* [ TS_(ICVARC|IVC) ... | TS_ISE | TS_IC ] */
+                      /* [ TS_IVC | TS_ICVARC | TS_ISE | TS_IC ] */
                       case TS_IC: /* inline cache: constants */
                       case TS_ISE: /* inline storage entry: `once` insn */
                       case TS_ICVARC: /* inline cvar cache */
@@ -9336,7 +9355,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no https://github.com/ruby/ruby/blob/trunk/compile.c#L9355
 	}
         ADD_INSN2(ret, node, setclassvariable,
                   ID2SYM(node->nd_vid),
-                  get_ivar_ic_value(iseq,node->nd_vid));
+                  get_cvar_ic_value(iseq,node->nd_vid));
 	break;
       }
       case NODE_OP_ASGN1:
@@ -9463,7 +9482,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no https://github.com/ruby/ruby/blob/trunk/compile.c#L9482
 	if (!popped) {
 	    ADD_INSN2(ret, node, getclassvariable,
 		      ID2SYM(node->nd_vid),
-		      get_ivar_ic_value(iseq,node->nd_vid));
+		      get_cvar_ic_value(iseq,node->nd_vid));
 	}
 	break;
       }
@@ -10339,12 +10358,17 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, https://github.com/ruby/ruby/blob/trunk/compile.c#L10358
                         }
                         break;
                       case TS_IVC:  /* inline ivar cache */
-                      case TS_ICVARC:  /* inline cvar cache */
 			argv[j] = op;
                         if (NUM2UINT(op) >= ISEQ_BODY(iseq)->ivc_size) {
                             ISEQ_BODY(iseq)->ivc_size = NUM2INT(op) + 1;
                         }
 			break;
+                      case TS_ICVARC:  /* inline cvar cache */
+			argv[j] = op;
+                        if (NUM2UINT(op) >= ISEQ_BODY(iseq)->icvarc_size) {
+                            ISEQ_BODY(iseq)->icvarc_size = NUM2INT(op) + 1;
+                        }
+			break;
                       case TS_CALLDATA:
 			argv[j] = iseq_build_callinfo_from_hash(iseq, op);
 			break;
@@ -11807,6 +11831,7 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/compile.c#L11831
     ibf_dump_write_small_value(dump, body->variable.flip_count);
     ibf_dump_write_small_value(dump, body->local_table_size);
     ibf_dump_write_small_value(dump, body->ivc_size);
+    ibf_dump_write_small_value(dump, body->icvarc_size);
     ibf_dump_write_small_value(dump, body->ise_size);
     ibf_dump_write_small_value(dump, body->ic_size);
     ibf_dump_write_small_value(dump, body->ci_size);
@@ -11918,6 +11943,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) https://github.com/ruby/ruby/blob/trunk/compile.c#L11943
     const unsigned int local_table_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
 
     const unsigned int ivc_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
+    const unsigned int icvarc_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
     const unsigned int ise_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
     const unsigned int ic_size = (unsigned int)ibf_load_small_value(load, &reading_pos);
 
@@ -11966,6 +11992,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) https://github.com/ruby/ruby/blob/trunk/compile.c#L11992
     load_body->builtin_inline_p = builtin_inline_p;
 
     load_body->ivc_size             = ivc_size;
+    load_body->icvarc_size          = icvarc_size;
     load_body->ise_size             = ise_size;
     load_body->ic_size              = ic_size;
     load_body->is_entries           = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body));
diff --git a/iseq.c b/iseq.c
index 20ca93b596..0369830bdd 100644
--- a/iseq.c
+++ b/iseq.c
@@ -274,13 +274,11 @@ 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#L274
     union iseq_inline_storage_entry *is_entries = body->is_entries;
 
     if (body->is_entries) {
-        // IVC and ICVARC entries
+        // IVC entries
         for (unsigned int i = 0; i < body->ivc_size; i++, is_entries++) {
             IVC ivc = (IVC)is_entries;
             if (ivc->entry) {
-                if (RB_TYPE_P(ivc->entry->class_value, T_NONE)) {
-                    rb_bug("!! %u", ivc->entry->index);
-                }
+                RUBY_ASSERT(!RB_TYPE_P(ivc->entry->class_value, T_NONE));
 
                 VALUE nv = func(data, ivc->entry->class_value);
                 if (ivc->entry->class_value != nv) {
@@ -289,6 +287,19 @@ 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#L287
             }
         }
 
+        // ICVARC entries
+        for (unsigned int i = 0; i < body->icvarc_size; i++, is_entries++) {
+            ICVARC icvarc = (ICVARC)is_entries;
+            if (icvarc->entry) {
+                RUBY_ASSERT(!RB_TYPE_P(icvarc->entry->class_value, T_NONE));
+
+                VALUE nv = func(data, icvarc->entry->class_value);
+                if (icvarc->entry->class_value != nv) {
+                    icvarc->entry->class_value = nv;
+                }
+            }
+        }
+
         // ISE entries
         for (unsigned int i = 0; i < body->ise_size; i++, is_entries++) {
             union iseq_inline_storage_entry *const is = (union iseq_inline_storage_entry *)is_entries;
diff --git a/tool/ruby_vm/views/_insn_type_chars.erb b/tool/ruby_vm/views/_insn_type_chars.erb
index e2ef222548..27daec6c6d 100644
--- a/tool/ruby_vm/views/_insn_type_chars.erb
+++ b/tool/ruby_vm/views/_insn_type_chars.erb
@@ -20,9 +20,10 @@ ISEQ_IS_ENTRY_START(const struct rb_iseq_constant_body *body, char op_type) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_insn_type_chars.erb#L20
       case TS_IC:
         relative_ic_offset += body->ise_size;
       case TS_ISE:
+        relative_ic_offset += body->icvarc_size;
+      case TS_ICVARC:
         relative_ic_offset += body->ivc_size;
       case TS_IVC:
-      case TS_ICVARC:
         break;
       default:
         rb_bug("Wrong op type");
diff --git a/vm_core.h b/vm_core.h
index f8eea13750..2a6d15bfbc 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -337,7 +337,7 @@ struct rb_mjit_unit; https://github.com/ruby/ruby/blob/trunk/vm_core.h#L337
 
 typedef uintptr_t iseq_bits_t;
 
-#define ISEQ_IS_SIZE(body) (body->ic_size + body->ivc_size + body->ise_size)
+#define ISEQ_IS_SIZE(body) (body->ic_size + body->ivc_size + body->ise_size + body->icvarc_size)
 
 struct rb_iseq_constant_body {
     enum iseq_type {
@@ -448,7 +448,7 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L448
     const struct rb_iseq_struct *parent_iseq;
     struct rb_iseq_struct *local_iseq; /* local_iseq->flip_cnt can be modified */
 
-    union iseq_inline_storage_entry *is_entries; /* [ TS_(ICVARC|IVC) ... | TS_ISE | TS_IC ] */
+    union iseq_inline_storage_entry *is_entries; /* [ TS_IVC | TS_ICVARC | TS_ISE | TS_IC ] */
     struct rb_call_data *call_data; //struct rb_call_data calls[ci_size];
 
     struct {
@@ -460,9 +460,10 @@ struct rb_iseq_constant_body { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L460
     } variable;
 
     unsigned int local_table_size;
-    unsigned int ic_size;  // Number of IC caches
-    unsigned int ise_size; // Number of ISE caches
-    unsigned int ivc_size; // Number of IVC and ICVARC caches
+    unsigned int ic_size;     // Number of IC caches
+    unsigned int ise_size;    // Number of ISE caches
+    unsigned int ivc_size;    // Number of IVC caches
+    unsigned int icvarc_size; // Number of ICVARC caches
     unsigned int ci_size;
     unsigned int stack_max; /* for stack overflow check */
     union {
-- 
cgit v1.2.1


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

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