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

ruby-changes:66564

From: Nobuyoshi <ko1@a...>
Date: Wed, 23 Jun 2021 10:56:07 +0900 (JST)
Subject: [ruby-changes:66564] 0700ee0e94 (master): Refactor class variable cache functions

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

From 0700ee0e946ff278699eb9aa068e7abbc3700dda Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Wed, 23 Jun 2021 09:39:04 +0900
Subject: Refactor class variable cache functions

Extracted repeated code as update_classvariable_cache.  When cvc
table is not set in getclassvariable, an empty table was created
but it has no id and would cause [BUG], so made the code same as
setclassvariable.
---
 variable.c      |  7 ++++--
 vm_insnhelper.c | 69 ++++++++++++++++++++++-----------------------------------
 2 files changed, 31 insertions(+), 45 deletions(-)

diff --git a/variable.c b/variable.c
index 778778c..a2f485a 100644
--- a/variable.c
+++ b/variable.c
@@ -3407,14 +3407,17 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) https://github.com/ruby/ruby/blob/trunk/variable.c#L3407
     }
 
     struct rb_cvar_class_tbl_entry *ent;
+    VALUE ent_data;
 
-    if (!rb_id_table_lookup(rb_cvc_tbl, id, (VALUE*)&ent)) {
+    if (!rb_id_table_lookup(rb_cvc_tbl, id, &ent_data)) {
         ent = ALLOC(struct rb_cvar_class_tbl_entry);
         ent->class_value = target;
         ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
         rb_id_table_insert(rb_cvc_tbl, id, (VALUE)ent);
         RB_DEBUG_COUNTER_INC(cvar_inline_miss);
-    } else {
+    }
+    else {
+        ent = (void *)ent_data;
         ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
     }
 
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 72c90a8..20863f9 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1281,21 +1281,10 @@ vm_setivar(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic, const str https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1281
     }
 }
 
-static inline VALUE
-vm_getclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_control_frame_t *cfp, ID id, ICVARC ic)
+static VALUE
+update_classvariable_cache(const rb_iseq_t *iseq, VALUE klass, ID id, ICVARC ic)
 {
-    if (ic->entry && ic->entry->global_cvar_state == GET_GLOBAL_CVAR_STATE()) {
-        VALUE v = Qundef;
-        RB_DEBUG_COUNTER_INC(cvar_read_inline_hit);
-
-        if (st_lookup(RCLASS_IV_TBL(ic->entry->class_value), (st_data_t)id, &v)) {
-            return v;
-        }
-    }
-
-    VALUE klass = vm_get_cvar_base(cref, cfp, 1);
     VALUE defined_class = 0;
-
     VALUE cvar_value = rb_cvar_find(klass, id, &defined_class);
 
     if (RB_TYPE_P(defined_class, T_ICLASS)) {
@@ -1303,25 +1292,41 @@ vm_getclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_contr https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1292
     }
 
     struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(defined_class);
-
     if (!rb_cvc_tbl) {
-        rb_cvc_tbl = RCLASS_CVC_TBL(defined_class) = rb_id_table_create(2);
+        rb_bug("the cvc table should be set");
     }
 
-    struct rb_cvar_class_tbl_entry *ent;
-
-    if (!rb_id_table_lookup(rb_cvc_tbl, id, (VALUE*)&ent)) {
+    VALUE ent_data;
+    if (!rb_id_table_lookup(rb_cvc_tbl, id, &ent_data)) {
         rb_bug("should have cvar cache entry");
-    } else {
-        ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
     }
 
+    struct rb_cvar_class_tbl_entry *ent = (void *)ent_data;
+    ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
+
     ic->entry = ent;
     RB_OBJ_WRITTEN(iseq, Qundef, ent->class_value);
 
     return cvar_value;
 }
 
+static inline VALUE
+vm_getclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_control_frame_t *cfp, ID id, ICVARC ic)
+{
+    if (ic->entry && ic->entry->global_cvar_state == GET_GLOBAL_CVAR_STATE()) {
+        VALUE v = Qundef;
+        RB_DEBUG_COUNTER_INC(cvar_read_inline_hit);
+
+        if (st_lookup(RCLASS_IV_TBL(ic->entry->class_value), (st_data_t)id, &v)) {
+            return v;
+        }
+    }
+
+    VALUE klass = vm_get_cvar_base(cref, cfp, 1);
+
+    return update_classvariable_cache(iseq, klass, id, ic);
+}
+
 static inline void
 vm_setclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_control_frame_t *cfp, ID id, VALUE val, ICVARC ic)
 {
@@ -1336,29 +1341,7 @@ vm_setclassvariable(const rb_iseq_t *iseq, const rb_cref_t *cref, const rb_contr https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L1341
 
     rb_cvar_set(klass, id, val);
 
-    VALUE defined_class = 0;
-    rb_cvar_find(klass, id, &defined_class);
-
-    if (RB_TYPE_P(defined_class, T_ICLASS)) {
-        defined_class = RBASIC(defined_class)->klass;
-    }
-
-    struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(defined_class);
-
-    if (!rb_cvc_tbl) {
-        rb_bug("the cvc table should be set");
-    }
-
-    struct rb_cvar_class_tbl_entry *ent;
-
-    if (!rb_id_table_lookup(rb_cvc_tbl, id, (VALUE*)&ent)) {
-        rb_bug("should have cvar cache entry");
-    } else {
-        ent->global_cvar_state = GET_GLOBAL_CVAR_STATE();
-    }
-
-    ic->entry = ent;
-    RB_OBJ_WRITTEN(iseq, Qundef, ent->class_value);
+    update_classvariable_cache(iseq, klass, id, ic);
 }
 
 static inline VALUE
-- 
cgit v1.1


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

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