From 182ae1407b3f6597cdbf6872f788c1ed3aa22a35 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 19 Jul 2019 13:02:38 +0900 Subject: fix shared array terminology. Shared arrays created by Array#dup and so on points a shared_root object to manage lifetime of Array buffer. However, sometimes shared_root is called only shared so it is confusing. So I fixed these wording "shared" to "shared_root". * RArray::heap::aux::shared -> RArray::heap::aux::shared_root * ARY_SHARED() -> ARY_SHARED_ROOT() * ARY_SHARED_NUM() -> ARY_SHARED_ROOT_REFCNT() Also, add some debug_counters to count shared array objects. * ary_shared_create: shared ary by Array#dup and so on. * ary_shared: finished in shard. * ary_shared_root_occupied: shared_root but has only 1 refcnt. The number (ary_shared - ary_shared_root_occupied) is meaningful. --- array.c | 115 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 62 insertions(+), 53 deletions(-) (limited to 'array.c') diff --git a/array.c b/array.c index c693b00755..a84361f05c 100644 --- a/array.c +++ b/array.c @@ -10,7 +10,6 @@ Copyright (C) 2000 Information-technology Promotion Agency, Japan **********************************************************************/ - #include "ruby/encoding.h" #include "ruby/util.h" #include "ruby/st.h" @@ -116,21 +115,21 @@ VALUE rb_cArray; RARRAY(ary)->as.heap.aux.capa = (n); \ } while (0) -#define ARY_SHARED(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared) +#define ARY_SHARED_ROOT(ary) (assert(ARY_SHARED_P(ary)), RARRAY(ary)->as.heap.aux.shared_root) #define ARY_SET_SHARED(ary, value) do { \ const VALUE _ary_ = (ary); \ const VALUE _value_ = (value); \ assert(!ARY_EMBED_P(_ary_)); \ assert(ARY_SHARED_P(_ary_)); \ assert(ARY_SHARED_ROOT_P(_value_)); \ - RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared, _value_); \ + RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \ } while (0) #define RARRAY_SHARED_ROOT_FLAG FL_USER5 #define ARY_SHARED_ROOT_P(ary) (FL_TEST((ary), RARRAY_SHARED_ROOT_FLAG)) -#define ARY_SHARED_NUM(ary) \ +#define ARY_SHARED_ROOT_REFCNT(ary) \ (assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa) -#define ARY_SHARED_OCCUPIED(ary) (ARY_SHARED_NUM(ary) == 1) -#define ARY_SET_SHARED_NUM(ary, value) do { \ +#define ARY_SHARED_ROOT_OCCUPIED(ary) (ARY_SHARED_ROOT_REFCNT(ary) == 1) +#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \ assert(ARY_SHARED_ROOT_P(ary)); \ RARRAY(ary)->as.heap.aux.capa = (value); \ } while (0) @@ -160,7 +159,7 @@ ary_verify_(VALUE ary, const char *file, int line) assert(RB_TYPE_P(ary, T_ARRAY)); if (FL_TEST(ary, ELTS_SHARED)) { - VALUE root = RARRAY(ary)->as.heap.aux.shared; + VALUE root = RARRAY(ary)->as.heap.aux.shared_root; const VALUE *ptr = ARY_HEAP_PTR(ary); const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root); long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root); @@ -470,16 +469,16 @@ ary_double_capa(VALUE ary, long min) } static void -rb_ary_decrement_share(VALUE shared) +rb_ary_decrement_share(VALUE shared_root) { - if (shared) { - long num = ARY_SHARED_NUM(shared) - 1; + if (shared_root) { + long num = ARY_SHARED_ROOT_REFCNT(shared_root) - 1; if (num == 0) { - rb_ary_free(shared); - rb_gc_force_recycle(shared); + rb_ary_free(shared_root); + rb_gc_force_recycle(shared_root); } else if (num > 0) { - ARY_SET_SHARED_NUM(shared, num); + ARY_SET_SHARED_ROOT_REFCNT(shared_root, num); } } } @@ -487,8 +486,8 @@ rb_ary_decrement_share(VALUE shared) static void rb_ary_unshare(VALUE ary) { - VALUE shared = RARRAY(ary)->as.heap.aux.shared; - rb_ary_decrement_share(shared); + VALUE shared_root = RARRAY(ary)->as.heap.aux.shared_root; + rb_ary_decrement_share(shared_root); FL_UNSET_SHARED(ary); } @@ -501,21 +500,22 @@ rb_ary_unshare_safe(VALUE ary) } static VALUE -rb_ary_increment_share(VALUE shared) +rb_ary_increment_share(VALUE shared_root) { - long num = ARY_SHARED_NUM(shared); + long num = ARY_SHARED_ROOT_REFCNT(shared_root); if (num >= 0) { - ARY_SET_SHARED_NUM(shared, num + 1); + ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1); } - return shared; + return shared_root; } static void -rb_ary_set_shared(VALUE ary, VALUE shared) +rb_ary_set_shared(VALUE ary, VALUE shared_root) { - rb_ary_increment_share(shared); + rb_ary_increment_share(shared_root); FL_SET_SHARED(ary); - ARY_SET_SHARED(ary, shared); + RB_DEBUG_COUNTER_INC(obj_ary_shared_create); + ARY_SET_SHARED(ary, shared_root); } static inline void @@ -531,28 +531,28 @@ rb_ary_modify(VALUE ary) rb_ary_modify_check(ary); if (ARY_SHARED_P(ary)) { long shared_len, len = RARRAY_LEN(ary); - VALUE shared = ARY_SHARED(ary); + VALUE shared_root = ARY_SHARED_ROOT(ary); - ary_verify(shared); + ary_verify(shared_root); if (len <= RARRAY_EMBED_LEN_MAX) { const VALUE *ptr = ARY_HEAP_PTR(ary); FL_UNSET_SHARED(ary); FL_SET_EMBED(ary); MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len); - rb_ary_decrement_share(shared); + rb_ary_decrement_share(shared_root); ARY_SET_EMBED_LEN(ary, len); } - else if (ARY_SHARED_OCCUPIED(shared) && len > ((shared_len = RARRAY_LEN(shared))>>1)) { - long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared); + else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) { + long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root); FL_UNSET_SHARED(ary); - ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared)); + ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared_root)); ARY_SET_CAPA(ary, shared_len); RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMMOVE(ptr, ptr+shift, VALUE, len); }); - FL_SET_EMBED(shared); - rb_ary_decrement_share(shared); + FL_SET_EMBED(shared_root); + rb_ary_decrement_share(shared_root); } else { VALUE *ptr = ary_heap_alloc(ary, len); @@ -579,14 +579,14 @@ ary_ensure_room_for_push(VALUE ary, long add_len) } if (ARY_SHARED_P(ary)) { if (new_len > RARRAY_EMBED_LEN_MAX) { - VALUE shared = ARY_SHARED(ary); - if (ARY_SHARED_OCCUPIED(shared)) { - if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared) + new_len <= RARRAY_LEN(shared)) { + VALUE shared_root = ARY_SHARED_ROOT(ary); + if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) { + if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) { rb_ary_modify_check(ary); ary_verify(ary); - ary_verify(shared); - return shared; + ary_verify(shared_root); + return shared_root; } else { /* if array is shared, then it is likely it participate in push/shift pattern */ @@ -643,7 +643,7 @@ rb_ary_shared_with_p(VALUE ary1, VALUE ary2) { if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) && !ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) && - RARRAY(ary1)->as.heap.aux.shared == RARRAY(ary2)->as.heap.aux.shared && + RARRAY(ary1)->as.heap.aux.shared_root == RARRAY(ary2)->as.heap.aux.shared_root && RARRAY(ary1)->as.heap.len == RARRAY(ary2)->as.heap.len) { return Qtrue; } @@ -778,6 +778,13 @@ rb_ary_free(VALUE ary) else { RB_DEBUG_COUNTER_INC(obj_ary_embed); } + + if (ARY_SHARED_P(ary)) { + RB_DEBUG_COUNTER_INC(obj_ary_shared); + } + if (ARY_SHARED_ROOT_P(ary) && ARY_SHARED_ROOT_OCCUPIED(ary)) { + RB_DEBUG_COUNTER_INC(obj_ary_shared_root_occupied); + } } RUBY_FUNC_EXPORTED size_t @@ -806,7 +813,7 @@ ary_make_shared(VALUE ary) ary_verify(ary); if (ARY_SHARED_P(ary)) { - return ARY_SHARED(ary); + return ARY_SHARED_ROOT(ary); } else if (ARY_SHARED_ROOT_P(ary)) { return ary; @@ -815,7 +822,7 @@ ary_make_shared(VALUE ary) rb_ary_transient_heap_evacuate(ary, TRUE); ary_shrink_capa(ary); FL_SET_SHARED_ROOT(ary); - ARY_SET_SHARED_NUM(ary, 1); + ARY_SET_SHARED_ROOT_REFCNT(ary, 1); return ary; } else { @@ -831,13 +838,15 @@ ary_make_shared(VALUE ary) ARY_SET_PTR((VALUE)shared, ptr); ary_mem_clear((VALUE)shared, len, capa - len); FL_SET_SHARED_ROOT(shared); - ARY_SET_SHARED_NUM((VALUE)shared, 1); + ARY_SET_SHARED_ROOT_REFCNT((VALUE)shared, 1); FL_SET_SHARED(ary); + RB_DEBUG_COUNTER_INC(obj_ary_shared_create); ARY_SET_SHARED(ary, (VALUE)shared); OBJ_FREEZE(shared); ary_verify((VALUE)shared); ary_verify(ary); + return (VALUE)shared; } } @@ -1279,7 +1288,7 @@ rb_ary_shift(VALUE ary) ARY_SET(ary, 0, Qnil); ary_make_shared(ary); } - else if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) { + else if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) { RARRAY_PTR_USE_TRANSIENT(ary, ptr, ptr[0] = Qnil); } ARY_INCREASE_PTR(ary, 1); /* shift ptr */ @@ -1338,7 +1347,7 @@ rb_ary_behead(VALUE ary, long n) rb_ary_modify_check(ary); if (ARY_SHARED_P(ary)) { - if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) { + if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) { setup_occupied_shared: ary_mem_clear(ary, 0, n); } @@ -1374,12 +1383,12 @@ ary_ensure_room_for_unshift(VALUE ary, int argc) } if (ARY_SHARED_P(ary)) { - VALUE shared = ARY_SHARED(ary); - capa = RARRAY_LEN(shared); - if (ARY_SHARED_OCCUPIED(shared) && capa > new_len) { + VALUE shared_root = ARY_SHARED_ROOT(ary); + capa = RARRAY_LEN(shared_root); + if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && capa > new_len) { rb_ary_modify_check(ary); head = RARRAY_CONST_PTR_TRANSIENT(ary); - sharedp = RARRAY_CONST_PTR_TRANSIENT(shared); + sharedp = RARRAY_CONST_PTR_TRANSIENT(shared_root); goto makeroom_if_need; } } @@ -1410,10 +1419,10 @@ ary_ensure_room_for_unshift(VALUE ary, int argc) head = sharedp + argc + room; } ARY_SET_PTR(ary, head - argc); - assert(ARY_SHARED_OCCUPIED(ARY_SHARED(ary))); + assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))); ary_verify(ary); - return ARY_SHARED(ary); + return ARY_SHARED_ROOT(ary); } else { /* sliding items */ @@ -3784,24 +3793,24 @@ rb_ary_replace(VALUE copy, VALUE orig) if (copy == orig) return copy; if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) { - VALUE shared = 0; + VALUE shared_root = 0; if (ARY_OWNS_HEAP_P(copy)) { ary_heap_free(copy); } else if (ARY_SHARED_P(copy)) { - shared = ARY_SHARED(copy); + shared_root = ARY_SHARED_ROOT(copy); FL_UNSET_SHARED(copy); } FL_SET_EMBED(copy); ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig)); - if (shared) { - rb_ary_decrement_share(shared); + if (shared_root) { + rb_ary_decrement_share(shared_root); } ARY_SET_LEN(copy, RARRAY_LEN(orig)); } else { - VALUE shared = ary_make_shared(orig); + VALUE shared_root = ary_make_shared(orig); if (ARY_OWNS_HEAP_P(copy)) { ary_heap_free(copy); } @@ -3811,7 +3820,7 @@ rb_ary_replace(VALUE copy, VALUE orig) FL_UNSET_EMBED(copy); ARY_SET_PTR(copy, ARY_HEAP_PTR(orig)); ARY_SET_LEN(copy, ARY_HEAP_LEN(orig)); - rb_ary_set_shared(copy, shared); + rb_ary_set_shared(copy, shared_root); } ary_verify(copy); return copy; -- cgit v1.2.3