From d4790d00e93cbb659187e9cd0f09d3829f04c28a Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 10 Mar 2025 13:05:18 +0100 Subject: [PATCH 1/3] Extract vm_icc_is_set --- vm_core.h | 6 ++++++ vm_insnhelper.c | 5 ++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/vm_core.h b/vm_core.h index a0d2b1ed2df4e5..36fb83ccaf0727 100644 --- a/vm_core.h +++ b/vm_core.h @@ -305,6 +305,12 @@ vm_icc_has_entry(const struct iseq_inline_constant_cache *cc) return vm_icc_flags(cc) & IMEMO_CONST_CACHE_HAS_ENTRY; } +static inline bool +vm_icc_is_set(const struct iseq_inline_constant_cache *cc) +{ + return !UNDEF_P(cc->value); +} + static inline void vm_icc_init(struct iseq_inline_constant_cache *cc, const ID *segments) { diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 68eec7edbe675c..1b8e0d67ebf1cf 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -6388,7 +6388,6 @@ vm_inlined_ic_hit_p(VALUE flags, VALUE value, const rb_cref_t *ic_cref, const VA static bool vm_ic_hit_p(const struct iseq_inline_constant_cache *ic, const VALUE *reg_ep) { - VM_ASSERT(IMEMO_TYPE_P(ice, imemo_constcache)); return vm_inlined_ic_hit_p(vm_icc_flags(ic), vm_icc_value(ic), vm_icc_cref(ic), reg_ep); } @@ -6396,7 +6395,7 @@ vm_ic_hit_p(const struct iseq_inline_constant_cache *ic, const VALUE *reg_ep) bool rb_vm_ic_hit_p(IC ic, const VALUE *reg_ep) { - return ic->entry && vm_ic_hit_p(ic, reg_ep); + return vm_icc_is_set(ic) && vm_ic_hit_p(ic, reg_ep); } static void @@ -6433,7 +6432,7 @@ rb_vm_opt_getconstant_path(rb_execution_context_t *ec, rb_control_frame_t *const { VALUE val; const ID *segments = vm_icc_segments(ic); - if (!UNDEF_P(ic->value) && vm_ic_hit_p(ic, GET_EP())) { + if (vm_icc_is_set(ic) && vm_ic_hit_p(ic, GET_EP())) { val = vm_icc_value(ic); VM_ASSERT(val == vm_get_ev_const_chain(ec, segments)); From 73a568b79608c7052498a5230df8c01cc843cee7 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 10 Mar 2025 13:15:01 +0100 Subject: [PATCH 2/3] Handle const_missing --- vm_insnhelper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 1b8e0d67ebf1cf..aaa1deb3c81123 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -6403,7 +6403,9 @@ vm_ic_update(const rb_iseq_t *iseq, IC ic, VALUE val, const VALUE *reg_ep, const { if (ruby_vm_const_missing_count > 0) { ruby_vm_const_missing_count = 0; - ic->entry = NULL; + if (!vm_icc_is_set(ic)) { + ic->value = Qundef; + } return; } From ac53689ae3be8a57577636bd10992654bb0f3c10 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Mon, 10 Mar 2025 13:21:37 +0100 Subject: [PATCH 3/3] Fix reseting inline constant caches --- vm_core.h | 8 ++++++++ vm_insnhelper.c | 4 +--- vm_method.c | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/vm_core.h b/vm_core.h index 36fb83ccaf0727..119a0fd3b249c1 100644 --- a/vm_core.h +++ b/vm_core.h @@ -311,6 +311,14 @@ vm_icc_is_set(const struct iseq_inline_constant_cache *cc) return !UNDEF_P(cc->value); } +static inline void +vm_icc_reset(struct iseq_inline_constant_cache *cc) +{ + if (!UNDEF_P(cc->value)) { + cc->value = Qundef; + } +} + static inline void vm_icc_init(struct iseq_inline_constant_cache *cc, const ID *segments) { diff --git a/vm_insnhelper.c b/vm_insnhelper.c index aaa1deb3c81123..f5a2d67119434a 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -6403,9 +6403,7 @@ vm_ic_update(const rb_iseq_t *iseq, IC ic, VALUE val, const VALUE *reg_ep, const { if (ruby_vm_const_missing_count > 0) { ruby_vm_const_missing_count = 0; - if (!vm_icc_is_set(ic)) { - ic->value = Qundef; - } + vm_icc_reset(ic); return; } diff --git a/vm_method.c b/vm_method.c index e4f71648acb3aa..fb43cb8d242d97 100644 --- a/vm_method.c +++ b/vm_method.c @@ -129,7 +129,7 @@ vm_cme_invalidate(rb_callable_method_entry_t *cme) static int rb_clear_constant_cache_for_id_i(st_data_t ic, st_data_t idx, st_data_t arg) { - ((IC) ic)->entry = NULL; + vm_icc_reset((IC) ic); return ST_CONTINUE; }