diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-10-30 22:03:42 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-10-30 22:03:42 +0000 |
commit | 198ff42258d9bfde8b2056d923510c52c957b5a1 (patch) | |
tree | 88b52dc706d767cd39f6bd26d00c33adf5cf0376 /struct.c | |
parent | 873d57347fca4fc7f407c2bca45f90797ab6f864 (diff) | |
download | ruby-198ff42258d9bfde8b2056d923510c52c957b5a1.tar.gz |
support theap for T_STRUCT.
* struct.c: members memory can use theap.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65452 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'struct.c')
-rw-r--r-- | struct.c | 42 |
1 files changed, 39 insertions, 3 deletions
@@ -12,6 +12,7 @@ #include "internal.h" #include "vm_core.h" #include "id.h" +#include "transient_heap.h" /* only for struct[:field] access */ enum { @@ -654,6 +655,41 @@ rb_struct_initialize(VALUE self, VALUE values) return rb_struct_initialize_m(RARRAY_LENINT(values), RARRAY_CONST_PTR(values), self); } +static VALUE * +struct_heap_alloc(VALUE st, size_t len) +{ + VALUE *ptr = rb_transient_heap_alloc((VALUE)st, sizeof(VALUE) * len); + + if (ptr) { + FL_SET_RAW(st, RSTRUCT_TRANSIENT_FLAG); + return ptr; + } + else { + FL_UNSET_RAW(st, RSTRUCT_TRANSIENT_FLAG); + return ALLOC_N(VALUE, len); + } +} + +void +rb_struct_transient_heap_evacuate(VALUE obj, int promote) +{ + if (RSTRUCT_TRANSIENT_P(obj)) { + const VALUE *old_ptr = rb_struct_const_heap_ptr(obj); + VALUE *new_ptr; + long len = RSTRUCT_LEN(obj); + + if (promote) { + new_ptr = ALLOC_N(VALUE, len); + FL_UNSET_RAW(obj, RSTRUCT_TRANSIENT_FLAG); + } + else { + new_ptr = struct_heap_alloc(obj, len); + } + MEMCPY(new_ptr, old_ptr, VALUE, len); + RSTRUCT(obj)->as.heap.ptr = new_ptr; + } +} + static VALUE struct_alloc(VALUE klass) { @@ -668,9 +704,9 @@ struct_alloc(VALUE klass) rb_mem_clear((VALUE *)st->as.ary, n); } else { - st->as.heap.ptr = ALLOC_N(VALUE, n); - rb_mem_clear((VALUE *)st->as.heap.ptr, n); - st->as.heap.len = n; + 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; |