summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <tenderlove@ruby-lang.org>2022-06-23 16:02:42 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2022-06-23 16:52:00 -0700
commit0b58059f15d8ec7bd9dbe1638a77b4a531b0df25 (patch)
tree2c1677460b6aa416c70f391ac6fff5e531ce9852
parent8d63a0470392f3b5810941bdf36f23d2122df16a (diff)
Free bitmap buffer if it's not used
If the iseqs don't have any objects in them that need marking, then immediately free the bitmap buffer
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6058
-rw-r--r--compile.c23
-rw-r--r--iseq.c10
2 files changed, 27 insertions, 6 deletions
diff --git a/compile.c b/compile.c
index 8ebe6f33ad..074d157bf0 100644
--- a/compile.c
+++ b/compile.c
@@ -2340,6 +2340,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
int code_size = code_index;
iseq_bits_t tmp[1] = {0};
+ bool needs_bitmap = false;
if (ISEQ_MBITS_BUFLEN(code_index) == 1) {
mark_offset_bits = tmp;
@@ -2397,6 +2398,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
ISEQ_MBITS_SET(mark_offset_bits, code_index + 1 + j);
RB_OBJ_WRITTEN(iseq, Qundef, map);
FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ needs_bitmap = true;
break;
}
case TS_LINDEX:
@@ -2413,6 +2415,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
RB_OBJ_WRITTEN(iseq, Qundef, v);
ISEQ_MBITS_SET(mark_offset_bits, code_index + 1 + j);
FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ needs_bitmap = true;
}
break;
}
@@ -2542,7 +2545,13 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
body->mark_bits.single = mark_offset_bits[0];
}
else {
- body->mark_bits.list = mark_offset_bits;
+ if (needs_bitmap) {
+ body->mark_bits.list = mark_offset_bits;
+ }
+ else {
+ body->mark_bits.list = 0;
+ ruby_xfree(mark_offset_bits);
+ }
}
/* get rid of memory leak when REALLOC failed */
@@ -11217,6 +11226,7 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
else {
mark_offset_bits = ZALLOC_N(iseq_bits_t, ISEQ_MBITS_BUFLEN(iseq_size));
}
+ bool needs_bitmap = false;
unsigned int min_ic_index, min_ise_index, min_ivc_index;
min_ic_index = min_ise_index = min_ivc_index = UINT_MAX;
@@ -11243,6 +11253,7 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
RB_OBJ_WRITTEN(iseqv, Qundef, v);
ISEQ_MBITS_SET(mark_offset_bits, code_index);
FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ needs_bitmap = true;
}
break;
}
@@ -11264,6 +11275,7 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
ISEQ_MBITS_SET(mark_offset_bits, code_index);
RB_OBJ_WRITTEN(iseqv, Qundef, v);
FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ needs_bitmap = true;
break;
}
case TS_ISEQ:
@@ -11275,6 +11287,7 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
RB_OBJ_WRITTEN(iseqv, Qundef, v);
ISEQ_MBITS_SET(mark_offset_bits, code_index);
FL_SET(iseqv, ISEQ_MARKABLE_ISEQ);
+ needs_bitmap = true;
}
break;
}
@@ -11359,7 +11372,13 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod
load_body->mark_bits.single = mark_offset_bits[0];
}
else {
- load_body->mark_bits.list = mark_offset_bits;
+ if (needs_bitmap) {
+ load_body->mark_bits.list = mark_offset_bits;
+ }
+ else {
+ load_body->mark_bits.list = 0;
+ ruby_xfree(mark_offset_bits);
+ }
}
assert(code_index == iseq_size);
diff --git a/iseq.c b/iseq.c
index b87939037b..12a1b80bf3 100644
--- a/iseq.c
+++ b/iseq.c
@@ -193,7 +193,7 @@ rb_iseq_free(const rb_iseq_t *iseq)
}
ruby_xfree((void *)body->catch_table);
ruby_xfree((void *)body->param.opt_table);
- if (ISEQ_MBITS_BUFLEN(body->iseq_size) > 1) {
+ if (ISEQ_MBITS_BUFLEN(body->iseq_size) > 1 && body->mark_bits.list) {
ruby_xfree((void *)body->mark_bits.list);
}
@@ -388,9 +388,11 @@ rb_iseq_each_value(const rb_iseq_t *iseq, iseq_value_itr_t * func, void *data)
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);
+ if (body->mark_bits.list) {
+ 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);
+ }
}
}
}