Implement Struct on VWA

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
parent 45ff2f4a89
commit 2543a6573f
Notes: git 2023-06-05 19:47:36 +00:00
4 changed files with 26 additions and 16 deletions

View file

@ -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