aboutsummaryrefslogtreecommitdiffstats
path: root/thread.c
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2023-08-24 16:27:17 +0930
committerJohn Hawthorn <john@hawthorn.email>2023-09-07 13:51:15 -0700
commited712e0e9d591bdaa84e9eaac832a9632aee5139 (patch)
treea6609964f38d76e30955f979b47ea5365c305bd0 /thread.c
parentfcdedf7f47b0ec495a0e3adca4c3f44b84afa98e (diff)
downloadruby-ed712e0e9d591bdaa84e9eaac832a9632aee5139.tar.gz
Skip allocation if handle_interrupt arg is already usable
If the supplied hash is already frozen and compare-by-identity, we can use it directly (still checking its contents are valid symbols), without making a new copy.
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/thread.c b/thread.c
index 4073325b9d..80a097f6f4 100644
--- a/thread.c
+++ b/thread.c
@@ -2018,10 +2018,12 @@ handle_interrupt_arg_check_i(VALUE key, VALUE val, VALUE args)
rb_raise(rb_eArgError, "unknown mask signature");
}
- if (!*maskp) {
- *maskp = rb_ident_hash_new();
+ if (maskp) {
+ if (!*maskp) {
+ *maskp = rb_ident_hash_new();
+ }
+ rb_hash_aset(*maskp, key, val);
}
- rb_hash_aset(*maskp, key, val);
return ST_CONTINUE;
}
@@ -2147,13 +2149,20 @@ rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg)
rb_raise(rb_eArgError, "block is needed.");
}
- mask = 0;
mask_arg = rb_to_hash_type(mask_arg);
- rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, (VALUE)&mask);
- if (!mask) {
- return rb_yield(Qnil);
+
+ if (OBJ_FROZEN(mask_arg) && rb_hash_compare_by_id_p(mask_arg)) {
+ rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, 0);
+ mask = mask_arg;
+ } else {
+ mask = 0;
+ rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, (VALUE)&mask);
+ if (!mask) {
+ return rb_yield(Qnil);
+ }
+ OBJ_FREEZE_RAW(mask);
}
- OBJ_FREEZE_RAW(mask);
+
rb_ary_push(th->pending_interrupt_mask_stack, mask);
if (!rb_threadptr_pending_interrupt_empty_p(th)) {
th->pending_interrupt_queue_checked = 0;