diff options
author | Aaron Patterson <tenderlove@ruby-lang.org> | 2021-02-22 16:18:10 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2021-05-03 14:11:48 -0700 |
commit | 9a6226c61ea8a8ae7b3516b693a0d6e73526a99f (patch) | |
tree | 7cb87204a9fd0acc988a0eb84f05eb0a526aad2b /object.c | |
parent | a6ff1dc6f98b29661fd1147d84bc3b928bed618f (diff) |
Eagerly allocate instance variable tables along with object
This allows us to allocate the right size for the object in advance,
meaning that we don't have to pay the cost of ivar table extension
later. The idea is that if an object type ever became "extended" at
some point, then it is very likely it will become extended again. So we
may as well allocate the ivar table up front.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/4216
Diffstat (limited to 'object.c')
-rw-r--r-- | object.c | 35 |
1 files changed, 22 insertions, 13 deletions
@@ -324,24 +324,33 @@ rb_obj_singleton_class(VALUE obj) MJIT_FUNC_EXPORTED void rb_obj_copy_ivar(VALUE dest, VALUE obj) { - RUBY_ASSERT(RBASIC(dest)->flags & ROBJECT_EMBED); + VALUE *dst_buf = 0; + VALUE *src_buf = 0; + uint32_t len = ROBJECT_EMBED_LEN_MAX; if (RBASIC(obj)->flags & ROBJECT_EMBED) { - MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX); - RBASIC(dest)->flags |= ROBJECT_EMBED; + src_buf = ROBJECT(obj)->as.ary; + + // embedded -> embedded + if (RBASIC(dest)->flags & ROBJECT_EMBED) { + dst_buf = ROBJECT(dest)->as.ary; + } + // embedded -> extended + else { + dst_buf = ROBJECT(dest)->as.heap.ivptr; + } } + // extended -> extended else { - uint32_t len = ROBJECT(obj)->as.heap.numiv; - VALUE *ptr = 0; - if (len > 0) { - ptr = ALLOC_N(VALUE, len); - MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len); - } - ROBJECT(dest)->as.heap.ivptr = ptr; - ROBJECT(dest)->as.heap.numiv = len; - ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl; - RBASIC(dest)->flags &= ~ROBJECT_EMBED; + uint32_t src_len = ROBJECT(obj)->as.heap.numiv; + uint32_t dst_len = ROBJECT(dest)->as.heap.numiv; + + len = src_len < dst_len ? src_len : dst_len; + dst_buf = ROBJECT(dest)->as.heap.ivptr; + src_buf = ROBJECT(obj)->as.heap.ivptr; } + + MEMCPY(dst_buf, src_buf, VALUE, len); } static void |