summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2022-11-22 15:28:14 -0500
committerGitHub <noreply@github.com>2022-11-22 15:28:14 -0500
commit9c5e3671ebd9c07c178ca5dac08ad15ad1eae411 (patch)
tree06f4f0560176011f14832d82f9e141ead7cac3f2 /iseq.c
parent20b9d7b9fde83c98046eacdfcb40e8cb6607963e (diff)
downloadruby-9c5e3671ebd9c07c178ca5dac08ad15ad1eae411.tar.gz
Increment max_iv_count on class based on number of set_iv in initialize (#6788)
We can loosely predict the number of ivar sets on a class based on the number of iv set instructions in the initialize method. This should give us a more accurate estimate to use for initial size pool allocation, which should in turn give us more cache hits.
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/iseq.c b/iseq.c
index a2e79cd55b..b366f03823 100644
--- a/iseq.c
+++ b/iseq.c
@@ -2491,6 +2491,45 @@ rb_iseq_disasm(const rb_iseq_t *iseq)
}
/*
+ * Estimates the number of instance variables that will be set on
+ * a given `class` with the initialize method defined in
+ * `initialize_iseq`
+ */
+attr_index_t
+rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq)
+{
+ bool calls_super = false;
+
+ struct rb_id_table * iv_names = rb_id_table_create(0);
+
+ VALUE * code = ISEQ_BODY(initialize_iseq)->iseq_encoded;
+
+ for (unsigned int i = 0; i < ISEQ_BODY(initialize_iseq)->iseq_size; ) {
+ VALUE insn = code[i];
+ int original_insn = rb_vm_insn_addr2insn((const void *)insn);
+
+ if (BIN(setinstancevariable) == original_insn) {
+ ID name = (ID)code[i + 1];
+ rb_id_table_insert(iv_names, name, Qtrue);
+ }
+ else if (BIN(invokesuper) == original_insn) {
+ calls_super = true;
+ }
+
+ i += insn_len(original_insn);
+ }
+
+ attr_index_t count = (attr_index_t)rb_id_table_size(iv_names);
+
+ if (calls_super) {
+ VALUE superclass = rb_class_superclass(klass);
+ count += RCLASS_EXT(superclass)->max_iv_count;
+ }
+
+ return count;
+}
+
+/*
* call-seq:
* iseq.disasm -> str
* iseq.disassemble -> str