зеркало из https://github.com/github/ruby.git
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.
This commit is contained in:
Родитель
7b7dde37f5
Коммит
6ee9a08d32
34
array.c
34
array.c
|
@ -892,17 +892,29 @@ rb_ary_free(VALUE ary)
|
|||
}
|
||||
}
|
||||
|
||||
VALUE
|
||||
rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len, bool freeze)
|
||||
static VALUE fake_ary_flags;
|
||||
|
||||
static VALUE
|
||||
init_fake_ary_flags(void)
|
||||
{
|
||||
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;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче