зеркало из https://github.com/github/ruby.git
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.
This commit is contained in:
Родитель
547f574b63
Коммит
182ae1407b
115
array.c
115
array.c
|
@ -10,7 +10,6 @@
|
||||||
Copyright (C) 2000 Information-technology Promotion Agency, Japan
|
Copyright (C) 2000 Information-technology Promotion Agency, Japan
|
||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "ruby/encoding.h"
|
#include "ruby/encoding.h"
|
||||||
#include "ruby/util.h"
|
#include "ruby/util.h"
|
||||||
#include "ruby/st.h"
|
#include "ruby/st.h"
|
||||||
|
@ -116,21 +115,21 @@ VALUE rb_cArray;
|
||||||
RARRAY(ary)->as.heap.aux.capa = (n); \
|
RARRAY(ary)->as.heap.aux.capa = (n); \
|
||||||
} while (0)
|
} 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 { \
|
#define ARY_SET_SHARED(ary, value) do { \
|
||||||
const VALUE _ary_ = (ary); \
|
const VALUE _ary_ = (ary); \
|
||||||
const VALUE _value_ = (value); \
|
const VALUE _value_ = (value); \
|
||||||
assert(!ARY_EMBED_P(_ary_)); \
|
assert(!ARY_EMBED_P(_ary_)); \
|
||||||
assert(ARY_SHARED_P(_ary_)); \
|
assert(ARY_SHARED_P(_ary_)); \
|
||||||
assert(ARY_SHARED_ROOT_P(_value_)); \
|
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)
|
} while (0)
|
||||||
#define RARRAY_SHARED_ROOT_FLAG FL_USER5
|
#define RARRAY_SHARED_ROOT_FLAG FL_USER5
|
||||||
#define ARY_SHARED_ROOT_P(ary) (FL_TEST((ary), RARRAY_SHARED_ROOT_FLAG))
|
#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)
|
(assert(ARY_SHARED_ROOT_P(ary)), RARRAY(ary)->as.heap.aux.capa)
|
||||||
#define ARY_SHARED_OCCUPIED(ary) (ARY_SHARED_NUM(ary) == 1)
|
#define ARY_SHARED_ROOT_OCCUPIED(ary) (ARY_SHARED_ROOT_REFCNT(ary) == 1)
|
||||||
#define ARY_SET_SHARED_NUM(ary, value) do { \
|
#define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \
|
||||||
assert(ARY_SHARED_ROOT_P(ary)); \
|
assert(ARY_SHARED_ROOT_P(ary)); \
|
||||||
RARRAY(ary)->as.heap.aux.capa = (value); \
|
RARRAY(ary)->as.heap.aux.capa = (value); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -160,7 +159,7 @@ ary_verify_(VALUE ary, const char *file, int line)
|
||||||
assert(RB_TYPE_P(ary, T_ARRAY));
|
assert(RB_TYPE_P(ary, T_ARRAY));
|
||||||
|
|
||||||
if (FL_TEST(ary, ELTS_SHARED)) {
|
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 *ptr = ARY_HEAP_PTR(ary);
|
||||||
const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root);
|
const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root);
|
||||||
long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(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
|
static void
|
||||||
rb_ary_decrement_share(VALUE shared)
|
rb_ary_decrement_share(VALUE shared_root)
|
||||||
{
|
{
|
||||||
if (shared) {
|
if (shared_root) {
|
||||||
long num = ARY_SHARED_NUM(shared) - 1;
|
long num = ARY_SHARED_ROOT_REFCNT(shared_root) - 1;
|
||||||
if (num == 0) {
|
if (num == 0) {
|
||||||
rb_ary_free(shared);
|
rb_ary_free(shared_root);
|
||||||
rb_gc_force_recycle(shared);
|
rb_gc_force_recycle(shared_root);
|
||||||
}
|
}
|
||||||
else if (num > 0) {
|
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
|
static void
|
||||||
rb_ary_unshare(VALUE ary)
|
rb_ary_unshare(VALUE ary)
|
||||||
{
|
{
|
||||||
VALUE shared = RARRAY(ary)->as.heap.aux.shared;
|
VALUE shared_root = RARRAY(ary)->as.heap.aux.shared_root;
|
||||||
rb_ary_decrement_share(shared);
|
rb_ary_decrement_share(shared_root);
|
||||||
FL_UNSET_SHARED(ary);
|
FL_UNSET_SHARED(ary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,21 +500,22 @@ rb_ary_unshare_safe(VALUE ary)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
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) {
|
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
|
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);
|
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
|
static inline void
|
||||||
|
@ -531,28 +531,28 @@ rb_ary_modify(VALUE ary)
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
if (ARY_SHARED_P(ary)) {
|
if (ARY_SHARED_P(ary)) {
|
||||||
long shared_len, len = RARRAY_LEN(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) {
|
if (len <= RARRAY_EMBED_LEN_MAX) {
|
||||||
const VALUE *ptr = ARY_HEAP_PTR(ary);
|
const VALUE *ptr = ARY_HEAP_PTR(ary);
|
||||||
FL_UNSET_SHARED(ary);
|
FL_UNSET_SHARED(ary);
|
||||||
FL_SET_EMBED(ary);
|
FL_SET_EMBED(ary);
|
||||||
MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len);
|
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);
|
ARY_SET_EMBED_LEN(ary, len);
|
||||||
}
|
}
|
||||||
else if (ARY_SHARED_OCCUPIED(shared) && len > ((shared_len = RARRAY_LEN(shared))>>1)) {
|
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);
|
long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root);
|
||||||
FL_UNSET_SHARED(ary);
|
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);
|
ARY_SET_CAPA(ary, shared_len);
|
||||||
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
|
RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
|
||||||
MEMMOVE(ptr, ptr+shift, VALUE, len);
|
MEMMOVE(ptr, ptr+shift, VALUE, len);
|
||||||
});
|
});
|
||||||
FL_SET_EMBED(shared);
|
FL_SET_EMBED(shared_root);
|
||||||
rb_ary_decrement_share(shared);
|
rb_ary_decrement_share(shared_root);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE *ptr = ary_heap_alloc(ary, len);
|
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 (ARY_SHARED_P(ary)) {
|
||||||
if (new_len > RARRAY_EMBED_LEN_MAX) {
|
if (new_len > RARRAY_EMBED_LEN_MAX) {
|
||||||
VALUE shared = ARY_SHARED(ary);
|
VALUE shared_root = ARY_SHARED_ROOT(ary);
|
||||||
if (ARY_SHARED_OCCUPIED(shared)) {
|
if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) {
|
||||||
if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared) + new_len <= RARRAY_LEN(shared)) {
|
if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) {
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
|
|
||||||
ary_verify(ary);
|
ary_verify(ary);
|
||||||
ary_verify(shared);
|
ary_verify(shared_root);
|
||||||
return shared;
|
return shared_root;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* if array is shared, then it is likely it participate in push/shift pattern */
|
/* 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) &&
|
if (!ARY_EMBED_P(ary1) && ARY_SHARED_P(ary1) &&
|
||||||
!ARY_EMBED_P(ary2) && ARY_SHARED_P(ary2) &&
|
!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) {
|
RARRAY(ary1)->as.heap.len == RARRAY(ary2)->as.heap.len) {
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
@ -778,6 +778,13 @@ rb_ary_free(VALUE ary)
|
||||||
else {
|
else {
|
||||||
RB_DEBUG_COUNTER_INC(obj_ary_embed);
|
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
|
RUBY_FUNC_EXPORTED size_t
|
||||||
|
@ -806,7 +813,7 @@ ary_make_shared(VALUE ary)
|
||||||
ary_verify(ary);
|
ary_verify(ary);
|
||||||
|
|
||||||
if (ARY_SHARED_P(ary)) {
|
if (ARY_SHARED_P(ary)) {
|
||||||
return ARY_SHARED(ary);
|
return ARY_SHARED_ROOT(ary);
|
||||||
}
|
}
|
||||||
else if (ARY_SHARED_ROOT_P(ary)) {
|
else if (ARY_SHARED_ROOT_P(ary)) {
|
||||||
return ary;
|
return ary;
|
||||||
|
@ -815,7 +822,7 @@ ary_make_shared(VALUE ary)
|
||||||
rb_ary_transient_heap_evacuate(ary, TRUE);
|
rb_ary_transient_heap_evacuate(ary, TRUE);
|
||||||
ary_shrink_capa(ary);
|
ary_shrink_capa(ary);
|
||||||
FL_SET_SHARED_ROOT(ary);
|
FL_SET_SHARED_ROOT(ary);
|
||||||
ARY_SET_SHARED_NUM(ary, 1);
|
ARY_SET_SHARED_ROOT_REFCNT(ary, 1);
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -831,13 +838,15 @@ ary_make_shared(VALUE ary)
|
||||||
ARY_SET_PTR((VALUE)shared, ptr);
|
ARY_SET_PTR((VALUE)shared, ptr);
|
||||||
ary_mem_clear((VALUE)shared, len, capa - len);
|
ary_mem_clear((VALUE)shared, len, capa - len);
|
||||||
FL_SET_SHARED_ROOT(shared);
|
FL_SET_SHARED_ROOT(shared);
|
||||||
ARY_SET_SHARED_NUM((VALUE)shared, 1);
|
ARY_SET_SHARED_ROOT_REFCNT((VALUE)shared, 1);
|
||||||
FL_SET_SHARED(ary);
|
FL_SET_SHARED(ary);
|
||||||
|
RB_DEBUG_COUNTER_INC(obj_ary_shared_create);
|
||||||
ARY_SET_SHARED(ary, (VALUE)shared);
|
ARY_SET_SHARED(ary, (VALUE)shared);
|
||||||
OBJ_FREEZE(shared);
|
OBJ_FREEZE(shared);
|
||||||
|
|
||||||
ary_verify((VALUE)shared);
|
ary_verify((VALUE)shared);
|
||||||
ary_verify(ary);
|
ary_verify(ary);
|
||||||
|
|
||||||
return (VALUE)shared;
|
return (VALUE)shared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1279,7 +1288,7 @@ rb_ary_shift(VALUE ary)
|
||||||
ARY_SET(ary, 0, Qnil);
|
ARY_SET(ary, 0, Qnil);
|
||||||
ary_make_shared(ary);
|
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);
|
RARRAY_PTR_USE_TRANSIENT(ary, ptr, ptr[0] = Qnil);
|
||||||
}
|
}
|
||||||
ARY_INCREASE_PTR(ary, 1); /* shift ptr */
|
ARY_INCREASE_PTR(ary, 1); /* shift ptr */
|
||||||
|
@ -1338,7 +1347,7 @@ rb_ary_behead(VALUE ary, long n)
|
||||||
|
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
if (ARY_SHARED_P(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:
|
setup_occupied_shared:
|
||||||
ary_mem_clear(ary, 0, n);
|
ary_mem_clear(ary, 0, n);
|
||||||
}
|
}
|
||||||
|
@ -1374,12 +1383,12 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARY_SHARED_P(ary)) {
|
if (ARY_SHARED_P(ary)) {
|
||||||
VALUE shared = ARY_SHARED(ary);
|
VALUE shared_root = ARY_SHARED_ROOT(ary);
|
||||||
capa = RARRAY_LEN(shared);
|
capa = RARRAY_LEN(shared_root);
|
||||||
if (ARY_SHARED_OCCUPIED(shared) && capa > new_len) {
|
if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && capa > new_len) {
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
head = RARRAY_CONST_PTR_TRANSIENT(ary);
|
head = RARRAY_CONST_PTR_TRANSIENT(ary);
|
||||||
sharedp = RARRAY_CONST_PTR_TRANSIENT(shared);
|
sharedp = RARRAY_CONST_PTR_TRANSIENT(shared_root);
|
||||||
goto makeroom_if_need;
|
goto makeroom_if_need;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1410,10 +1419,10 @@ ary_ensure_room_for_unshift(VALUE ary, int argc)
|
||||||
head = sharedp + argc + room;
|
head = sharedp + argc + room;
|
||||||
}
|
}
|
||||||
ARY_SET_PTR(ary, head - argc);
|
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);
|
ary_verify(ary);
|
||||||
return ARY_SHARED(ary);
|
return ARY_SHARED_ROOT(ary);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* sliding items */
|
/* sliding items */
|
||||||
|
@ -3784,24 +3793,24 @@ rb_ary_replace(VALUE copy, VALUE orig)
|
||||||
if (copy == orig) return copy;
|
if (copy == orig) return copy;
|
||||||
|
|
||||||
if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
|
if (RARRAY_LEN(orig) <= RARRAY_EMBED_LEN_MAX) {
|
||||||
VALUE shared = 0;
|
VALUE shared_root = 0;
|
||||||
|
|
||||||
if (ARY_OWNS_HEAP_P(copy)) {
|
if (ARY_OWNS_HEAP_P(copy)) {
|
||||||
ary_heap_free(copy);
|
ary_heap_free(copy);
|
||||||
}
|
}
|
||||||
else if (ARY_SHARED_P(copy)) {
|
else if (ARY_SHARED_P(copy)) {
|
||||||
shared = ARY_SHARED(copy);
|
shared_root = ARY_SHARED_ROOT(copy);
|
||||||
FL_UNSET_SHARED(copy);
|
FL_UNSET_SHARED(copy);
|
||||||
}
|
}
|
||||||
FL_SET_EMBED(copy);
|
FL_SET_EMBED(copy);
|
||||||
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
|
ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig));
|
||||||
if (shared) {
|
if (shared_root) {
|
||||||
rb_ary_decrement_share(shared);
|
rb_ary_decrement_share(shared_root);
|
||||||
}
|
}
|
||||||
ARY_SET_LEN(copy, RARRAY_LEN(orig));
|
ARY_SET_LEN(copy, RARRAY_LEN(orig));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE shared = ary_make_shared(orig);
|
VALUE shared_root = ary_make_shared(orig);
|
||||||
if (ARY_OWNS_HEAP_P(copy)) {
|
if (ARY_OWNS_HEAP_P(copy)) {
|
||||||
ary_heap_free(copy);
|
ary_heap_free(copy);
|
||||||
}
|
}
|
||||||
|
@ -3811,7 +3820,7 @@ rb_ary_replace(VALUE copy, VALUE orig)
|
||||||
FL_UNSET_EMBED(copy);
|
FL_UNSET_EMBED(copy);
|
||||||
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
|
ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
|
||||||
ARY_SET_LEN(copy, ARY_HEAP_LEN(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);
|
ary_verify(copy);
|
||||||
return copy;
|
return copy;
|
||||||
|
|
|
@ -206,6 +206,15 @@ RB_DEBUG_COUNTER(obj_str_fstr)
|
||||||
RB_DEBUG_COUNTER(obj_ary_embed)
|
RB_DEBUG_COUNTER(obj_ary_embed)
|
||||||
RB_DEBUG_COUNTER(obj_ary_transient)
|
RB_DEBUG_COUNTER(obj_ary_transient)
|
||||||
RB_DEBUG_COUNTER(obj_ary_ptr)
|
RB_DEBUG_COUNTER(obj_ary_ptr)
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
RB_DEBUG_COUNTER(obj_ary_shared_create)
|
||||||
|
RB_DEBUG_COUNTER(obj_ary_shared)
|
||||||
|
RB_DEBUG_COUNTER(obj_ary_shared_root_occupied)
|
||||||
|
|
||||||
RB_DEBUG_COUNTER(obj_hash_empty)
|
RB_DEBUG_COUNTER(obj_hash_empty)
|
||||||
RB_DEBUG_COUNTER(obj_hash_under4)
|
RB_DEBUG_COUNTER(obj_hash_under4)
|
||||||
|
|
6
gc.c
6
gc.c
|
@ -5083,7 +5083,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj)
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
if (FL_TEST(obj, ELTS_SHARED)) {
|
if (FL_TEST(obj, ELTS_SHARED)) {
|
||||||
VALUE root = any->as.array.as.heap.aux.shared;
|
VALUE root = any->as.array.as.heap.aux.shared_root;
|
||||||
gc_mark(objspace, root);
|
gc_mark(objspace, root);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -8007,7 +8007,7 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
if (FL_TEST(obj, ELTS_SHARED)) {
|
if (FL_TEST(obj, ELTS_SHARED)) {
|
||||||
UPDATE_IF_MOVED(objspace, any->as.array.as.heap.aux.shared);
|
UPDATE_IF_MOVED(objspace, any->as.array.as.heap.aux.shared_root);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gc_ref_update_array(objspace, obj);
|
gc_ref_update_array(objspace, obj);
|
||||||
|
@ -11219,7 +11219,7 @@ rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
if (FL_TEST(obj, ELTS_SHARED)) {
|
if (FL_TEST(obj, ELTS_SHARED)) {
|
||||||
APPENDF((BUFF_ARGS, "shared -> %s",
|
APPENDF((BUFF_ARGS, "shared -> %s",
|
||||||
rb_obj_info(RARRAY(obj)->as.heap.aux.shared)));
|
rb_obj_info(RARRAY(obj)->as.heap.aux.shared_root)));
|
||||||
}
|
}
|
||||||
else if (FL_TEST(obj, RARRAY_EMBED_FLAG)) {
|
else if (FL_TEST(obj, RARRAY_EMBED_FLAG)) {
|
||||||
APPENDF((BUFF_ARGS, "[%s%s] len: %d (embed)",
|
APPENDF((BUFF_ARGS, "[%s%s] len: %d (embed)",
|
||||||
|
|
|
@ -1054,7 +1054,7 @@ struct RArray {
|
||||||
long len;
|
long len;
|
||||||
union {
|
union {
|
||||||
long capa;
|
long capa;
|
||||||
VALUE shared;
|
VALUE shared_root;
|
||||||
} aux;
|
} aux;
|
||||||
const VALUE *ptr;
|
const VALUE *ptr;
|
||||||
} heap;
|
} heap;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче