summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2024-08-08 14:11:37 +0200
committerJean Boussier <[email protected]>2024-08-10 10:09:14 +0200
commit6ee9a08d32800974c596a01e9190cc8e778a6ee5 (patch)
tree33ab4c838bb9b26c6359cae978c7e11139145809
parent7b7dde37f546b74f1dd15e482235fec139b80b70 (diff)
rb_setup_fake_ary: use precomputed flags
Setting up the fake array is a bit more expensive than would be expected because `rb_ary_freeze` does a lot of checks and lookup a shape transition. If we assume fake arrays will always be frozen, we can precompute the flags state and just assign it.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11344
-rw-r--r--array.c34
-rw-r--r--vm_insnhelper.c4
2 files changed, 26 insertions, 12 deletions
diff --git a/array.c b/array.c
index 319aed7cfd..20b9e61daa 100644
--- a/array.c
+++ b/array.c
@@ -892,17 +892,29 @@ rb_ary_free(VALUE ary)
}
}
+static VALUE fake_ary_flags;
+
+static VALUE
+init_fake_ary_flags(void)
+{
+ struct RArray fake_ary = {0};
+ fake_ary.basic.flags = T_ARRAY;
+ VALUE ary = (VALUE)&fake_ary;
+ rb_ary_freeze(ary);
+ return fake_ary.basic.flags;
+}
+
VALUE
-rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len, bool freeze)
-{
- fake_ary->basic.flags = T_ARRAY;
- VALUE ary = (VALUE)fake_ary;
- RBASIC_CLEAR_CLASS(ary);
- ARY_SET_PTR(ary, list);
- ARY_SET_HEAP_LEN(ary, len);
- ARY_SET_CAPA(ary, len);
- if (freeze) rb_ary_freeze(ary);
- return ary;
+rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len)
+{
+ fake_ary->basic.flags = fake_ary_flags;
+ RBASIC_CLEAR_CLASS((VALUE)fake_ary);
+
+ // bypass frozen checks
+ fake_ary->as.heap.ptr = list;
+ fake_ary->as.heap.len = len;
+ fake_ary->as.heap.aux.capa = len;
+ return (VALUE)fake_ary;
}
size_t
@@ -8677,6 +8689,8 @@ rb_ary_deconstruct(VALUE ary)
void
Init_Array(void)
{
+ fake_ary_flags = init_fake_ary_flags();
+
rb_cArray = rb_define_class("Array", rb_cObject);
rb_include_module(rb_cArray, rb_mEnumerable);
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 077d0cea21..29e6f28dec 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -6199,7 +6199,7 @@ rb_vm_opt_newarray_hash(rb_execution_context_t *ec, rb_num_t num, const VALUE *p
return vm_opt_newarray_hash(ec, num, ptr);
}
-VALUE rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len, bool freeze);
+VALUE rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len);
VALUE rb_ec_pack_ary(rb_execution_context_t *ec, VALUE ary, VALUE fmt, VALUE buffer);
static VALUE
@@ -6207,7 +6207,7 @@ vm_opt_newarray_pack_buffer(rb_execution_context_t *ec, rb_num_t num, const VALU
{
if (BASIC_OP_UNREDEFINED_P(BOP_PACK, ARRAY_REDEFINED_OP_FLAG)) {
struct RArray fake_ary;
- VALUE ary = rb_setup_fake_ary(&fake_ary, ptr, num, true);
+ VALUE ary = rb_setup_fake_ary(&fake_ary, ptr, num);
return rb_ec_pack_ary(ec, ary, fmt, (UNDEF_P(buffer) ? Qnil : buffer));
}
else {