The benchmark results show that this feature has either a positive or
no impact on performance. The memory usage is also mostly unchanged,
except in hexapdf, where there is a decrease in RSS.

--------------  -----------  ----------  ---------  -----------  ----------  ---------  --------------  -------------
bench           master (ms)  stddev (%)  RSS (MiB)  branch (ms)  stddev (%)  RSS (MiB)  branch 1st itr  master/branch
activerecord    70.8         2.2         56.0       71.7         2.2         56.0       0.99            0.99
erubi_rails     20.5         13.6        94.7       20.5         14.3        94.2       0.93            1.00
hexapdf         2541.0       0.7         212.8      2544.4       0.7         203.4      1.00            1.00
liquid-c        65.6         0.3         38.9       65.3         0.3         38.9       1.01            1.01
liquid-compile  63.7         0.3         34.6       61.1         0.2         34.6       1.04            1.04
liquid-render   163.1        0.1         37.1       163.3        0.1         37.1       1.00            1.00
mail            139.3        0.1         50.5       137.0        0.1         50.1       0.99            1.02
psych-load      2065.7       0.1         36.9       2068.2       0.1         37.3       1.00            1.00
railsbench      2034.6       0.5         103.9      2031.9       0.5         103.8      1.02            1.00
ruby-lsp        65.3         3.1         89.8       66.2         3.0         89.7       1.01            0.99
sequel          73.2         1.0         40.3       73.4         1.0         40.3       1.00            1.00
--------------  -----------  ----------  ---------  -----------  ----------  ---------  --------------  -------------
This commit is contained in:
Peter Zhu 2023-05-29 11:38:15 -04:00
Родитель 45ff2f4a89
Коммит 2543a6573f
4 изменённых файлов: 26 добавлений и 16 удалений

Просмотреть файл

@ -24,13 +24,13 @@ RANGE_BEG(VALUE r)
static inline VALUE
RANGE_END(VALUE r)
{
return RSTRUCT(r)->as.ary[1];
return RSTRUCT_GET(r, 1);
}
static inline VALUE
RANGE_EXCL(VALUE r)
{
return RSTRUCT(r)->as.ary[2];
return RSTRUCT_GET(r, 2);
}
VALUE

Просмотреть файл

@ -12,10 +12,10 @@
#include "ruby/ruby.h" /* for struct RBasic */
enum {
RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
RSTRUCT_EMBED_LEN_MASK = RUBY_FL_USER7 | RUBY_FL_USER6 | RUBY_FL_USER5 | RUBY_FL_USER4 |
RUBY_FL_USER3 | RUBY_FL_USER2 | RUBY_FL_USER1,
RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
RSTRUCT_TRANSIENT_FLAG = FL_USER3,
RSTRUCT_TRANSIENT_FLAG = RUBY_FL_USER8,
};
struct RStruct {
@ -25,7 +25,12 @@ struct RStruct {
long len;
const VALUE *ptr;
} heap;
const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
/* This is a length 1 array because:
* 1. GCC has a bug that does not optimize C flexible array members
* (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
* 2. Zero length arrays are not supported by all compilers
*/
const VALUE ary[1];
} as;
};
@ -145,7 +150,7 @@ RSTRUCT_GET(VALUE st, long k)
static inline const VALUE *
rb_struct_const_heap_ptr(VALUE st)
{
/* TODO: check embed on debug mode */
assert(!FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK));
return RSTRUCT(st)->as.heap.ptr;
}

Просмотреть файл

@ -835,23 +835,28 @@ rb_struct_transient_heap_evacuate(VALUE obj, int promote)
static VALUE
struct_alloc(VALUE klass)
{
long n;
NEWOBJ_OF(st, struct RStruct, klass, T_STRUCT | (RGENGC_WB_PROTECTED_STRUCT ? FL_WB_PROTECTED : 0), sizeof(struct RStruct), 0);
long n = num_members(klass);
size_t embedded_size = offsetof(struct RStruct, as.ary) + (sizeof(VALUE) * n);
VALUE flags = T_STRUCT | (RGENGC_WB_PROTECTED_STRUCT ? FL_WB_PROTECTED : 0);
n = num_members(klass);
if (n > 0 && rb_gc_size_allocatable_p(embedded_size)) {
flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
NEWOBJ_OF(st, struct RStruct, klass, flags, embedded_size, 0);
if (0 < n && n <= RSTRUCT_EMBED_LEN_MAX) {
RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
RBASIC(st)->flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
rb_mem_clear((VALUE *)st->as.ary, n);
return (VALUE)st;
}
else {
NEWOBJ_OF(st, struct RStruct, klass, flags, embedded_size, 0);
st->as.heap.ptr = struct_heap_alloc((VALUE)st, n);
rb_mem_clear((VALUE *)st->as.heap.ptr, n);
st->as.heap.len = n;
}
return (VALUE)st;
return (VALUE)st;
}
}
VALUE

Просмотреть файл

@ -695,7 +695,7 @@ mod manual_defs {
pub const VM_CALL_OPT_SEND : u32 = 1 << VM_CALL_OPT_SEND_bit;
// From internal/struct.h - in anonymous enum, so we can't easily import it
pub const RSTRUCT_EMBED_LEN_MASK: usize = (RUBY_FL_USER2 | RUBY_FL_USER1) as usize;
pub const RSTRUCT_EMBED_LEN_MASK: usize = (RUBY_FL_USER7 | RUBY_FL_USER6 | RUBY_FL_USER5 | RUBY_FL_USER4 | RUBY_FL_USER3 |RUBY_FL_USER2 | RUBY_FL_USER1) as usize;
// From iseq.h - via a different constant, which seems to confuse bindgen
pub const ISEQ_TRANSLATED: usize = RUBY_FL_USER7 as usize;