diff options
-rw-r--r-- | compile.c | 4 | ||||
-rw-r--r-- | gc.c | 11 | ||||
-rw-r--r-- | rjit_c.rb | 1 | ||||
-rw-r--r-- | vm_callinfo.h | 4 |
4 files changed, 18 insertions, 2 deletions
@@ -4327,6 +4327,7 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); VALUE *keywords = kw_arg->keywords; int i = 0; + kw_arg->references = 0; kw_arg->keyword_len = len; *kw_arg_ptr = kw_arg; @@ -7275,6 +7276,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no fin = NEW_LABEL(line); kw_arg = rb_xmalloc_mul_add(2, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); + kw_arg->references = 0; kw_arg->keyword_len = 2; kw_arg->keywords[0] = ID2SYM(rb_intern("matchee")); kw_arg->keywords[1] = ID2SYM(rb_intern("key")); @@ -10469,6 +10471,7 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op) size_t n = rb_callinfo_kwarg_bytes(len); kw_arg = xmalloc(n); + kw_arg->references = 0; kw_arg->keyword_len = len; for (i = 0; i < len; i++) { VALUE kw = RARRAY_AREF(vkw_arg, i); @@ -11957,6 +11960,7 @@ ibf_load_ci_entries(const struct ibf_load *load, int kwlen = (int)ibf_load_small_value(load, &reading_pos); if (kwlen > 0) { kwarg = rb_xmalloc_mul_add(kwlen, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); + kwarg->references = 0; kwarg->keyword_len = kwlen; for (int j=0; j<kwlen; j++) { VALUE keyword = ibf_load_small_value(load, &reading_pos); @@ -3681,8 +3681,15 @@ obj_free(rb_objspace_t *objspace, VALUE obj) RB_DEBUG_COUNTER_INC(obj_imemo_parser_strterm); break; case imemo_callinfo: - RB_DEBUG_COUNTER_INC(obj_imemo_callinfo); - break; + { + const struct rb_callinfo * ci = ((const struct rb_callinfo *)obj); + if (ci->kwarg) { + ((struct rb_callinfo_kwarg *)ci->kwarg)->references--; + if (ci->kwarg->references == 0) xfree((void *)ci->kwarg); + } + RB_DEBUG_COUNTER_INC(obj_imemo_callinfo); + break; + } case imemo_callcache: RB_DEBUG_COUNTER_INC(obj_imemo_callcache); break; @@ -1037,6 +1037,7 @@ module RubyVM::RJIT # :nodoc: all @rb_callinfo_kwarg ||= CType::Struct.new( "rb_callinfo_kwarg", Primitive.cexpr!("SIZEOF(struct rb_callinfo_kwarg)"), keyword_len: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo_kwarg *)NULL)), keyword_len)")], + references: [CType::Immediate.parse("int"), Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo_kwarg *)NULL)), references)")], keywords: [CType::Immediate.parse("void *"), Primitive.cexpr!("OFFSETOF((*((struct rb_callinfo_kwarg *)NULL)), keywords)")], ) end diff --git a/vm_callinfo.h b/vm_callinfo.h index 91c92854d7..fb6998b8b3 100644 --- a/vm_callinfo.h +++ b/vm_callinfo.h @@ -43,6 +43,7 @@ enum vm_call_flag_bits { struct rb_callinfo_kwarg { int keyword_len; + int references; VALUE keywords[]; }; @@ -199,6 +200,9 @@ vm_ci_dump(const struct rb_callinfo *ci) static inline const struct rb_callinfo * vm_ci_new_(ID mid, unsigned int flag, unsigned int argc, const struct rb_callinfo_kwarg *kwarg, const char *file, int line) { + if (kwarg) { + ((struct rb_callinfo_kwarg *)kwarg)->references++; + } if (USE_EMBED_CI && VM_CI_EMBEDDABLE_P(mid, flag, argc, kwarg)) { RB_DEBUG_COUNTER_INC(ci_packed); return vm_ci_new_id(mid, flag, argc, kwarg); |