summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2022-06-23 15:46:53 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2022-06-23 16:52:00 -0700
commit8d63a0470392f3b5810941bdf36f23d2122df16a (patch)
tree73870c66a57f66427db06c96d2fa8a5d6383851c /iseq.c
parenteb1a84a9c328acf3f77249617115208eacf396cd (diff)
Flatten bitmap when there is only one element
We can avoid allocating a bitmap when the number of elements in the iseq is fewer than the size of an iseq_bits_t
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6058
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/iseq.c b/iseq.c
index 1b9599aeda..b87939037b 100644
--- a/iseq.c
+++ b/iseq.c
@@ -193,7 +193,9 @@ rb_iseq_free(const rb_iseq_t *iseq)
}
ruby_xfree((void *)body->catch_table);
ruby_xfree((void *)body->param.opt_table);
- ruby_xfree((void *)body->mark_offset_bits);
+ if (ISEQ_MBITS_BUFLEN(body->iseq_size) > 1) {
+ ruby_xfree((void *)body->mark_bits.list);
+ }
if (body->param.keyword != NULL) {
ruby_xfree((void *)body->param.keyword->default_values);
@@ -313,6 +315,25 @@ iseq_extract_values(VALUE *code, size_t pos, iseq_value_itr_t * func, void *data
return len;
}
+static inline void
+iseq_scan_bits(unsigned int i, iseq_bits_t bits, VALUE *code, iseq_value_itr_t *func, void *data)
+{
+ unsigned int count = 0;
+
+ while(bits) {
+ if (bits & 0x1) {
+ unsigned int index = (i * ISEQ_MBITS_BITLENGTH) + count;
+ VALUE op = code[index];
+ VALUE newop = func(data, op);
+ if (newop != op) {
+ code[index] = newop;
+ }
+ }
+ bits >>= 1;
+ count++;
+ }
+}
+
static void
rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
{
@@ -363,23 +384,13 @@ rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
}
// Embedded VALUEs
- for (unsigned int i = 0; i < ISEQ_MBITS_BUFLEN(size); i++) {
- iseq_bits_t bits = body->mark_offset_bits[i];
- if (bits) {
- unsigned int count = 0;
-
- while(bits) {
- if (bits & 0x1) {
- unsigned int index = (i * ISEQ_MBITS_BITLENGTH) + count;
- VALUE op = code[index];
- VALUE newop = func(data, op);
- if (newop != op) {
- code[index] = newop;
- }
- }
- bits >>= 1;
- count++;
- }
+ if (ISEQ_MBITS_BUFLEN(size) == 1) {
+ iseq_scan_bits(0, body->mark_bits.single, code, func, data);
+ }
+ else {
+ for (unsigned int i = 0; i < ISEQ_MBITS_BUFLEN(size); i++) {
+ iseq_bits_t bits = body->mark_bits.list[i];
+ iseq_scan_bits(i, bits, code, func, data);
}
}
}