aboutsummaryrefslogtreecommitdiffstats
path: root/array.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2019-07-19 13:02:38 +0900
committerKoichi Sasada <ko1@atdot.net>2019-07-19 13:07:59 +0900
commit182ae1407b3f6597cdbf6872f788c1ed3aa22a35 (patch)
tree043184ff9daa64e4e3cea797226b84eed92b75b0 /array.c
parent547f574b639cd8586568ebb8570c51faf102c313 (diff)
downloadruby-182ae1407b3f6597cdbf6872f788c1ed3aa22a35.tar.gz
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.
Diffstat (limited to 'array.c')
-rw-r--r--array.c115
1 files changed, 62 insertions, 53 deletions
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;