diff options
author | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2021-06-23 09:39:04 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2021-06-23 10:55:22 +0900 |
commit | 0700ee0e946ff278699eb9aa068e7abbc3700dda (patch) | |
tree | 519e8ebc7faec3728dcadcf65b03ed8e4977789e | |
parent | 46ff44ef17cc6ed48f4c5657b26ee8c8c7cab9c8 (diff) |
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.
-rw-r--r-- | variable.c | 7 | ||||
-rw-r--r-- | vm_insnhelper.c | 69 |
2 files changed, 31 insertions, 45 deletions
diff --git a/variable.c b/variable.c index 778778c866..a2f485a9d4 100644 --- a/variable.c +++ b/variable.c @@ -3407,14 +3407,17 @@ rb_cvar_set(VALUE klass, ID id, VALUE val) } 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 72c90a8a5c..20863f971f 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 } } -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 } 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 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 |