summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-06-23 09:39:04 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2021-06-23 10:55:22 +0900
commit0700ee0e946ff278699eb9aa068e7abbc3700dda (patch)
tree519e8ebc7faec3728dcadcf65b03ed8e4977789e /vm_insnhelper.c
parent46ff44ef17cc6ed48f4c5657b26ee8c8c7cab9c8 (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.
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c69
1 files changed, 26 insertions, 43 deletions
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