* ruby.h (struct RArray): revert embedding ptr in RVALUE.
* array.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11256 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
11e562f34a
commit
15df557a4d
@ -1,3 +1,9 @@
|
|||||||
|
Wed Nov 1 23:24:42 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* ruby.h (struct RArray): revert embedding ptr in RVALUE.
|
||||||
|
|
||||||
|
* array.c: ditto.
|
||||||
|
|
||||||
Wed Nov 1 23:01:55 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Wed Nov 1 23:01:55 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* string.c (hash): use Bob Jenkins' hash algorithm.
|
* string.c (hash): use Bob Jenkins' hash algorithm.
|
||||||
|
259
array.c
259
array.c
@ -40,66 +40,37 @@ memfill(register VALUE *mem, register long size, register VALUE val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define ARY_TMPLOCK FL_USER1
|
#define ARY_TMPLOCK FL_USER1
|
||||||
#define ARY_NOEMBED FL_USER3
|
|
||||||
#define ARY_SHARED_P(a) FL_TEST(a, ELTS_SHARED)
|
#define ARY_SHARED_P(a) FL_TEST(a, ELTS_SHARED)
|
||||||
|
|
||||||
#define ARY_SET_NOEMBED(ary) do {\
|
|
||||||
FL_SET(ary, ARY_NOEMBED);\
|
|
||||||
ARY_SET_EMBED_LEN(ary, 0);\
|
|
||||||
} while (0)
|
|
||||||
#define ARY_SET_EMBED(str) FL_UNSET(str, ARY_NOEMBED)
|
|
||||||
#define ARY_EMBED_P(ary) (!FL_TEST(ary, ARY_NOEMBED))
|
|
||||||
#define ARY_SET_EMBED_LEN(ary, n) do { \
|
|
||||||
long tmp_n = (n);\
|
|
||||||
RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK;\
|
|
||||||
RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT;\
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ARY_SET_LEN(ary, n) do { \
|
#define ARY_SET_LEN(ary, n) do { \
|
||||||
if (ARY_EMBED_P(ary)) {\
|
RARRAY(ary)->len = (n);\
|
||||||
ARY_SET_EMBED_LEN(ary, n);\
|
|
||||||
}\
|
|
||||||
else {\
|
|
||||||
RARRAY(ary)->as.heap.len = (n);\
|
|
||||||
}\
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ARY_LFREE FL_USER6
|
#define ARY_LFREE FL_USER6
|
||||||
#define ARY_LFREE_P(ary) FL_TEST(ary, ARY_LFREE)
|
#define ARY_LFREE_P(ary) FL_TEST(ary, ARY_LFREE)
|
||||||
#define LFREE_SIZE(ary) RARRAY(ary)->as.heap.ptr[-1]
|
#define LFREE_SIZE(ary) RARRAY(ary)->ptr[-1]
|
||||||
#define LFREE_CAPA(ary) (LFREE_SIZE(ary)+RARRAY(ary)->as.heap.aux.capa)
|
#define LFREE_CAPA(ary) (LFREE_SIZE(ary)+RARRAY(ary)->aux.capa)
|
||||||
|
|
||||||
#define ARY_CAPA(ary) ((ARY_EMBED_P(ary)) ? RARRAY_EMBED_LEN_MAX : RARRAY(ary)->as.heap.aux.capa)
|
#define ARY_CAPA(ary) RARRAY(ary)->aux.capa
|
||||||
#define RESIZE_CAPA(ary,capacity) do {\
|
#define RESIZE_CAPA(ary,capacity) do {\
|
||||||
if (ARY_EMBED_P(ary)) {\
|
if (ARY_LFREE_P(ary)) {\
|
||||||
if ((capacity) > RARRAY_EMBED_LEN_MAX) {\
|
VALUE *ptr = RARRAY(ary)->ptr - LFREE_SIZE(ary);\
|
||||||
VALUE *tmp = ALLOC_N(VALUE, capacity);\
|
|
||||||
long len = RARRAY_LEN(ary);\
|
|
||||||
MEMCPY(tmp, RARRAY_PTR(ary), VALUE, len);\
|
|
||||||
RARRAY(ary)->as.heap.ptr = tmp;\
|
|
||||||
RARRAY(ary)->as.heap.len = len;\
|
|
||||||
ARY_SET_NOEMBED(ary);\
|
|
||||||
RARRAY(ary)->as.heap.aux.capa = (capacity);\
|
|
||||||
}\
|
|
||||||
}\
|
|
||||||
else if (ARY_LFREE_P(ary)) {\
|
|
||||||
VALUE *ptr = RARRAY(ary)->as.heap.ptr - LFREE_SIZE(ary);\
|
|
||||||
if (LFREE_CAPA(ary) >= (capacity)) {\
|
if (LFREE_CAPA(ary) >= (capacity)) {\
|
||||||
RARRAY(ary)->as.heap.aux.capa = LFREE_CAPA(ary);\
|
RARRAY(ary)->aux.capa = LFREE_CAPA(ary);\
|
||||||
MEMMOVE(ptr, RARRAY(ary)->as.heap.ptr, VALUE, RARRAY_LEN(ary));\
|
MEMMOVE(ptr, RARRAY(ary)->ptr, VALUE, RARRAY_LEN(ary));\
|
||||||
FL_UNSET(ary, ARY_LFREE);\
|
FL_UNSET(ary, ARY_LFREE);\
|
||||||
RARRAY(ary)->as.heap.ptr = ptr;\
|
RARRAY(ary)->ptr = ptr;\
|
||||||
}\
|
}\
|
||||||
else {\
|
else {\
|
||||||
long offset = LFREE_SIZE(ary);\
|
long offset = LFREE_SIZE(ary);\
|
||||||
REALLOC_N(ptr, VALUE, offset+(capacity));\
|
REALLOC_N(ptr, VALUE, offset+(capacity));\
|
||||||
RARRAY(ary)->as.heap.aux.capa = (capacity);\
|
RARRAY(ary)->aux.capa = (capacity);\
|
||||||
RARRAY(ary)->as.heap.ptr = ptr + offset;\
|
RARRAY(ary)->ptr = ptr + offset;\
|
||||||
}\
|
}\
|
||||||
}\
|
}\
|
||||||
else {\
|
else {\
|
||||||
REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, (capacity));\
|
REALLOC_N(RARRAY(ary)->ptr, VALUE, (capacity));\
|
||||||
RARRAY(ary)->as.heap.aux.capa = (capacity);\
|
RARRAY(ary)->aux.capa = (capacity);\
|
||||||
}\
|
}\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -125,13 +96,12 @@ rb_ary_modify(VALUE ary)
|
|||||||
VALUE *ptr;
|
VALUE *ptr;
|
||||||
|
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
if (ARY_EMBED_P(ary)) return;
|
|
||||||
if (ARY_SHARED_P(ary)) {
|
if (ARY_SHARED_P(ary)) {
|
||||||
ptr = ALLOC_N(VALUE, RARRAY_LEN(ary));
|
ptr = ALLOC_N(VALUE, RARRAY_LEN(ary));
|
||||||
FL_UNSET(ary, ELTS_SHARED);
|
FL_UNSET(ary, ELTS_SHARED);
|
||||||
RARRAY(ary)->as.heap.aux.capa = RARRAY_LEN(ary);
|
RARRAY(ary)->aux.capa = RARRAY_LEN(ary);
|
||||||
MEMCPY(ptr, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
|
MEMCPY(ptr, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
|
||||||
RARRAY(ary)->as.heap.ptr = ptr;
|
RARRAY(ary)->ptr = ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,9 +133,9 @@ ary_alloc(VALUE klass)
|
|||||||
NEWOBJ(ary, struct RArray);
|
NEWOBJ(ary, struct RArray);
|
||||||
OBJSETUP(ary, klass, T_ARRAY);
|
OBJSETUP(ary, klass, T_ARRAY);
|
||||||
|
|
||||||
ary->as.heap.len = 0;
|
ary->len = 0;
|
||||||
ary->as.heap.ptr = 0;
|
ary->ptr = 0;
|
||||||
ary->as.heap.aux.capa = 0;
|
ary->aux.capa = 0;
|
||||||
|
|
||||||
return (VALUE)ary;
|
return (VALUE)ary;
|
||||||
}
|
}
|
||||||
@ -182,15 +152,9 @@ ary_new(VALUE klass, long len)
|
|||||||
rb_raise(rb_eArgError, "array size too big");
|
rb_raise(rb_eArgError, "array size too big");
|
||||||
}
|
}
|
||||||
ary = ary_alloc(klass);
|
ary = ary_alloc(klass);
|
||||||
if (len <= RARRAY_EMBED_LEN_MAX) {
|
|
||||||
ARY_SET_EMBED_LEN(ary, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (len == 0) len++;
|
if (len == 0) len++;
|
||||||
ARY_SET_NOEMBED(ary);
|
RARRAY(ary)->ptr = ALLOC_N(VALUE, len);
|
||||||
RARRAY(ary)->as.heap.ptr = ALLOC_N(VALUE, len);
|
RARRAY(ary)->aux.capa = len;
|
||||||
RARRAY(ary)->as.heap.aux.capa = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
@ -225,7 +189,7 @@ rb_ary_new3(long n, ...)
|
|||||||
}
|
}
|
||||||
va_end(ar);
|
va_end(ar);
|
||||||
|
|
||||||
ARY_SET_LEN(ary, n);
|
RARRAY(ary)->len = n;
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +201,7 @@ rb_ary_new4(long n, const VALUE *elts)
|
|||||||
ary = rb_ary_new2(n);
|
ary = rb_ary_new2(n);
|
||||||
if (n > 0 && elts) {
|
if (n > 0 && elts) {
|
||||||
MEMCPY(RARRAY_PTR(ary), elts, VALUE, n);
|
MEMCPY(RARRAY_PTR(ary), elts, VALUE, n);
|
||||||
ARY_SET_LEN(ary, n);
|
RARRAY(ary)->len = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
@ -246,12 +210,12 @@ rb_ary_new4(long n, const VALUE *elts)
|
|||||||
void
|
void
|
||||||
rb_ary_free(VALUE ary)
|
rb_ary_free(VALUE ary)
|
||||||
{
|
{
|
||||||
if (!ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) {
|
if (!ARY_SHARED_P(ary)) {
|
||||||
if (ARY_LFREE_P(ary)) {
|
if (ARY_LFREE_P(ary)) {
|
||||||
xfree(RARRAY(ary)->as.heap.ptr - LFREE_SIZE(ary));
|
xfree(RARRAY(ary)->ptr - LFREE_SIZE(ary));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xfree(RARRAY(ary)->as.heap.ptr);
|
xfree(RARRAY(ary)->ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,23 +223,21 @@ rb_ary_free(VALUE ary)
|
|||||||
static VALUE
|
static VALUE
|
||||||
ary_make_shared(VALUE ary)
|
ary_make_shared(VALUE ary)
|
||||||
{
|
{
|
||||||
if (ARY_EMBED_P(ary)) abort();
|
|
||||||
if (ARY_SHARED_P(ary)) {
|
if (ARY_SHARED_P(ary)) {
|
||||||
return RARRAY(ary)->as.heap.aux.shared;
|
return RARRAY(ary)->aux.shared;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NEWOBJ(shared, struct RArray);
|
NEWOBJ(shared, struct RArray);
|
||||||
OBJSETUP(shared, 0, T_ARRAY);
|
OBJSETUP(shared, 0, T_ARRAY);
|
||||||
|
|
||||||
ARY_SET_NOEMBED(shared);
|
shared->len = RARRAY(ary)->len;
|
||||||
shared->as.heap.len = RARRAY(ary)->as.heap.len;
|
shared->ptr = RARRAY(ary)->ptr;
|
||||||
shared->as.heap.ptr = RARRAY(ary)->as.heap.ptr;
|
shared->aux.capa = RARRAY(ary)->aux.capa;
|
||||||
shared->as.heap.aux.capa = RARRAY(ary)->as.heap.aux.capa;
|
|
||||||
if (ARY_LFREE_P(ary)) {
|
if (ARY_LFREE_P(ary)) {
|
||||||
FL_SET(shared,ARY_LFREE);
|
FL_SET(shared,ARY_LFREE);
|
||||||
FL_UNSET(ary,ARY_LFREE);
|
FL_UNSET(ary,ARY_LFREE);
|
||||||
}
|
}
|
||||||
RARRAY(ary)->as.heap.aux.shared = (VALUE)shared;
|
RARRAY(ary)->aux.shared = (VALUE)shared;
|
||||||
FL_SET(ary, ELTS_SHARED);
|
FL_SET(ary, ELTS_SHARED);
|
||||||
OBJ_FREEZE(shared);
|
OBJ_FREEZE(shared);
|
||||||
return (VALUE)shared;
|
return (VALUE)shared;
|
||||||
@ -354,11 +316,10 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
|
|||||||
|
|
||||||
rb_ary_modify(ary);
|
rb_ary_modify(ary);
|
||||||
if (rb_scan_args(argc, argv, "02", &size, &val) == 0) {
|
if (rb_scan_args(argc, argv, "02", &size, &val) == 0) {
|
||||||
if (!ARY_EMBED_P(ary) && RARRAY_PTR(ary) && !ARY_SHARED_P(ary)) {
|
if (RARRAY_PTR(ary) && !ARY_SHARED_P(ary)) {
|
||||||
free(RARRAY(ary)->as.heap.ptr);
|
free(RARRAY(ary)->ptr);
|
||||||
}
|
}
|
||||||
ARY_SET_EMBED(ary);
|
RARRAY(ary)->len = 0;
|
||||||
ARY_SET_LEN(ary, 0);
|
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
rb_warning("given block not used");
|
rb_warning("given block not used");
|
||||||
}
|
}
|
||||||
@ -381,21 +342,7 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
|
|||||||
rb_raise(rb_eArgError, "array size too big");
|
rb_raise(rb_eArgError, "array size too big");
|
||||||
}
|
}
|
||||||
rb_ary_modify(ary);
|
rb_ary_modify(ary);
|
||||||
if (len <= RARRAY_EMBED_LEN_MAX) {
|
|
||||||
if (!ARY_EMBED_P(ary)) {
|
|
||||||
xfree(RARRAY(ary)->as.heap.ptr);
|
|
||||||
ARY_SET_EMBED(ary);
|
|
||||||
}
|
|
||||||
ARY_SET_EMBED_LEN(ary, len);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (ARY_EMBED_P(ary)) {
|
|
||||||
ARY_SET_NOEMBED(ary);
|
|
||||||
RARRAY(ary)->as.heap.len = 0;
|
|
||||||
RARRAY(ary)->as.heap.ptr = 0;
|
|
||||||
}
|
|
||||||
RESIZE_CAPA(ary, len);
|
RESIZE_CAPA(ary, len);
|
||||||
}
|
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
@ -404,12 +351,12 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
|
|||||||
}
|
}
|
||||||
for (i=0; i<len; i++) {
|
for (i=0; i<len; i++) {
|
||||||
rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
|
rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
|
||||||
ARY_SET_LEN(ary, i+1);
|
RARRAY(ary)->len = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
memfill(RARRAY_PTR(ary), len, val);
|
memfill(RARRAY_PTR(ary), len, val);
|
||||||
ARY_SET_LEN(ary, len);
|
RARRAY(ary)->len = len;
|
||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
@ -431,13 +378,10 @@ rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
|
|||||||
if (argc < 0) {
|
if (argc < 0) {
|
||||||
rb_raise(rb_eArgError, "negative array size");
|
rb_raise(rb_eArgError, "negative array size");
|
||||||
}
|
}
|
||||||
if (argc > RARRAY_EMBED_LEN_MAX) {
|
RARRAY(ary)->ptr = ALLOC_N(VALUE, argc);
|
||||||
ARY_SET_NOEMBED(ary);
|
RARRAY(ary)->aux.capa = argc;
|
||||||
RARRAY(ary)->as.heap.ptr = ALLOC_N(VALUE, argc);
|
|
||||||
RARRAY(ary)->as.heap.aux.capa = argc;
|
|
||||||
}
|
|
||||||
MEMCPY(RARRAY_PTR(ary), argv, VALUE, argc);
|
MEMCPY(RARRAY_PTR(ary), argv, VALUE, argc);
|
||||||
ARY_SET_LEN(ary, argc);
|
RARRAY(ary)->len = argc;
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
@ -475,7 +419,7 @@ rb_ary_store(VALUE ary, long idx, VALUE val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (idx >= RARRAY_LEN(ary)) {
|
if (idx >= RARRAY_LEN(ary)) {
|
||||||
ARY_SET_LEN(ary, idx + 1);
|
RARRAY(ary)->len = idx + 1;
|
||||||
}
|
}
|
||||||
RARRAY_PTR(ary)[idx] = val;
|
RARRAY_PTR(ary)[idx] = val;
|
||||||
}
|
}
|
||||||
@ -486,10 +430,9 @@ ary_shared_array(VALUE klass, VALUE ary)
|
|||||||
VALUE val = ary_alloc(klass);
|
VALUE val = ary_alloc(klass);
|
||||||
|
|
||||||
ary_make_shared(ary);
|
ary_make_shared(ary);
|
||||||
ARY_SET_NOEMBED(val);
|
RARRAY(val)->ptr = RARRAY(ary)->ptr;
|
||||||
RARRAY(val)->as.heap.ptr = RARRAY(ary)->as.heap.ptr;
|
RARRAY(val)->len = RARRAY(ary)->len;
|
||||||
RARRAY(val)->as.heap.len = RARRAY(ary)->as.heap.len;
|
RARRAY(val)->aux.shared = RARRAY(ary)->aux.shared;
|
||||||
RARRAY(val)->as.heap.aux.shared = RARRAY(ary)->as.heap.aux.shared;
|
|
||||||
FL_SET(val, ELTS_SHARED);
|
FL_SET(val, ELTS_SHARED);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -512,14 +455,10 @@ ary_shared_first(int argc, VALUE *argv, VALUE ary, int last)
|
|||||||
if (last) {
|
if (last) {
|
||||||
offset = RARRAY_LEN(ary) - n;
|
offset = RARRAY_LEN(ary) - n;
|
||||||
}
|
}
|
||||||
if (ARY_EMBED_P(ary) || n <= RARRAY_EMBED_LEN_MAX) {
|
|
||||||
return rb_ary_new4(n, RARRAY_PTR(ary)+offset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
result = ary_shared_array(rb_cArray, ary);
|
result = ary_shared_array(rb_cArray, ary);
|
||||||
RARRAY(result)->as.heap.ptr += offset;
|
RARRAY(result)->ptr += offset;
|
||||||
RARRAY(result)->as.heap.len = n;
|
RARRAY(result)->len = n;
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,7 +517,7 @@ rb_ary_pop(VALUE ary)
|
|||||||
RESIZE_CAPA(ary, RARRAY_LEN(ary) * 2);
|
RESIZE_CAPA(ary, RARRAY_LEN(ary) * 2);
|
||||||
}
|
}
|
||||||
n = RARRAY_LEN(ary)-1;
|
n = RARRAY_LEN(ary)-1;
|
||||||
ARY_SET_LEN(ary, n);
|
RARRAY(ary)->len = n;
|
||||||
return RARRAY_PTR(ary)[n];
|
return RARRAY_PTR(ary)[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,7 +545,7 @@ rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
|
|||||||
|
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
result = ary_shared_first(argc, argv, ary, Qtrue);
|
result = ary_shared_first(argc, argv, ary, Qtrue);
|
||||||
ARY_SET_LEN(ary, RARRAY_LEN(ary) - RARRAY_LEN(result));
|
RARRAY(ary)->len -= RARRAY_LEN(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,23 +557,18 @@ rb_ary_shift(VALUE ary)
|
|||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
if (RARRAY_LEN(ary) == 0) return Qnil;
|
if (RARRAY_LEN(ary) == 0) return Qnil;
|
||||||
top = RARRAY_PTR(ary)[0];
|
top = RARRAY_PTR(ary)[0];
|
||||||
if (ARY_EMBED_P(ary)) {
|
|
||||||
MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+1, VALUE, RARRAY_LEN(ary)-1);
|
|
||||||
ARY_SET_EMBED_LEN(ary, RARRAY_LEN(ary)-1);
|
|
||||||
return top;
|
|
||||||
}
|
|
||||||
if (!ARY_SHARED_P(ary)) {
|
if (!ARY_SHARED_P(ary)) {
|
||||||
if (ARY_LFREE_P(ary)) {
|
if (ARY_LFREE_P(ary)) {
|
||||||
RARRAY(ary)->as.heap.ptr[0] = LFREE_SIZE(ary)+1;
|
RARRAY(ary)->ptr[0] = LFREE_SIZE(ary)+1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FL_SET(ary, ARY_LFREE);
|
FL_SET(ary, ARY_LFREE);
|
||||||
RARRAY(ary)->as.heap.ptr[0] = 1;
|
RARRAY(ary)->ptr[0] = 1;
|
||||||
}
|
}
|
||||||
RARRAY(ary)->as.heap.aux.capa--;
|
RARRAY(ary)->aux.capa--;
|
||||||
}
|
}
|
||||||
RARRAY(ary)->as.heap.ptr++; /* shift ptr */
|
RARRAY(ary)->ptr++; /* shift ptr */
|
||||||
RARRAY(ary)->as.heap.len--;
|
RARRAY(ary)->len--;
|
||||||
|
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
@ -670,12 +604,12 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
|
|||||||
result = ary_shared_first(argc, argv, ary, Qfalse);
|
result = ary_shared_first(argc, argv, ary, Qfalse);
|
||||||
n = RARRAY_LEN(result);
|
n = RARRAY_LEN(result);
|
||||||
if (ARY_SHARED_P(ary)) {
|
if (ARY_SHARED_P(ary)) {
|
||||||
RARRAY(ary)->as.heap.ptr += n;
|
RARRAY(ary)->ptr += n;
|
||||||
RARRAY(ary)->as.heap.len -= n;
|
RARRAY(ary)->len -= n;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+n, VALUE, RARRAY_LEN(ary)-n);
|
MEMMOVE(RARRAY_PTR(ary), RARRAY_PTR(ary)+n, VALUE, RARRAY_LEN(ary)-n);
|
||||||
ARY_SET_LEN(ary, RARRAY_LEN(ary)-n);
|
RARRAY(ary)->len -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -708,12 +642,12 @@ rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
|
|||||||
long free = shared ? RARRAY_LEN(ary) : ARY_CAPA(ary);
|
long free = shared ? RARRAY_LEN(ary) : ARY_CAPA(ary);
|
||||||
VALUE *ptr;
|
VALUE *ptr;
|
||||||
|
|
||||||
if (!ARY_EMBED_P(ary) && free > len + argc) {
|
if (free > len + argc) {
|
||||||
free += lfree;
|
free += lfree;
|
||||||
free2 = (free - len - argc) / 2 + argc;
|
free2 = (free - len - argc) / 2 + argc;
|
||||||
ptr = RARRAY(ary)->as.heap.ptr-lfree+free2;
|
ptr = RARRAY(ary)->ptr-lfree+free2;
|
||||||
MEMMOVE(ptr, RARRAY(ary)->as.heap.ptr, VALUE,
|
MEMMOVE(ptr, RARRAY(ary)->ptr, VALUE,
|
||||||
RARRAY(ary)->as.heap.len);
|
RARRAY(ary)->len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free = (len+argc) * 1.5;
|
free = (len+argc) * 1.5;
|
||||||
@ -726,23 +660,20 @@ rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
|
|||||||
if (shared) {
|
if (shared) {
|
||||||
FL_UNSET(ary, ELTS_SHARED);
|
FL_UNSET(ary, ELTS_SHARED);
|
||||||
}
|
}
|
||||||
else if (ARY_EMBED_P(ary)) {
|
|
||||||
ARY_SET_NOEMBED(ary);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
xfree(RARRAY(ary)->as.heap.ptr-lfree);
|
xfree(RARRAY(ary)->ptr-lfree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RARRAY(ary)->as.heap.ptr = ptr;
|
RARRAY(ary)->ptr = ptr;
|
||||||
RARRAY(ary)->as.heap.len = len;
|
RARRAY(ary)->len = len;
|
||||||
RARRAY(ary)->as.heap.aux.capa = free-free2;
|
RARRAY(ary)->aux.capa = free-free2;
|
||||||
}
|
}
|
||||||
RARRAY(ary)->as.heap.ptr -= argc;
|
RARRAY(ary)->ptr -= argc;
|
||||||
RARRAY(ary)->as.heap.len += argc;
|
RARRAY(ary)->len += argc;
|
||||||
RARRAY(ary)->as.heap.aux.capa += argc;
|
RARRAY(ary)->aux.capa += argc;
|
||||||
free2 -= argc;
|
free2 -= argc;
|
||||||
if (free2 > 0) {
|
if (free2 > 0) {
|
||||||
RARRAY(ary)->as.heap.ptr[-1] = free2;
|
RARRAY(ary)->ptr[-1] = free2;
|
||||||
FL_SET(ary, ARY_LFREE);
|
FL_SET(ary, ARY_LFREE);
|
||||||
} else {
|
} else {
|
||||||
FL_UNSET(ary, ARY_LFREE);
|
FL_UNSET(ary, ARY_LFREE);
|
||||||
@ -795,20 +726,15 @@ rb_ary_subseq(VALUE ary, long beg, long len)
|
|||||||
klass = rb_obj_class(ary);
|
klass = rb_obj_class(ary);
|
||||||
if (len == 0) return ary_new(klass, 0);
|
if (len == 0) return ary_new(klass, 0);
|
||||||
|
|
||||||
if (ARY_EMBED_P(ary) && len <= RARRAY_EMBED_LEN_MAX) {
|
|
||||||
return rb_ary_new4(len, RARRAY_PTR(ary)+beg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
shared = ary_make_shared(ary);
|
shared = ary_make_shared(ary);
|
||||||
ptr = RARRAY_PTR(ary);
|
ptr = RARRAY_PTR(ary);
|
||||||
ary2 = ary_alloc(klass);
|
ary2 = ary_alloc(klass);
|
||||||
ARY_SET_NOEMBED(ary2);
|
RARRAY(ary2)->ptr = ptr + beg;
|
||||||
RARRAY(ary2)->as.heap.ptr = ptr + beg;
|
RARRAY(ary2)->len = len;
|
||||||
RARRAY(ary2)->as.heap.len = len;
|
RARRAY(ary2)->aux.shared = shared;
|
||||||
RARRAY(ary2)->as.heap.aux.shared = shared;
|
|
||||||
FL_SET(ary2, ELTS_SHARED);
|
FL_SET(ary2, ELTS_SHARED);
|
||||||
|
|
||||||
return ary2;
|
return ary2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1124,7 +1050,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
|
|||||||
if (rlen > 0) {
|
if (rlen > 0) {
|
||||||
MEMCPY(RARRAY_PTR(ary) + beg, RARRAY_PTR(rpl), VALUE, rlen);
|
MEMCPY(RARRAY_PTR(ary) + beg, RARRAY_PTR(rpl), VALUE, rlen);
|
||||||
}
|
}
|
||||||
ARY_SET_LEN(ary, len);
|
RARRAY(ary)->len = len;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
long alen;
|
long alen;
|
||||||
@ -1141,7 +1067,7 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl)
|
|||||||
if (len != rlen) {
|
if (len != rlen) {
|
||||||
MEMMOVE(RARRAY_PTR(ary) + beg + rlen, RARRAY_PTR(ary) + beg + len,
|
MEMMOVE(RARRAY_PTR(ary) + beg + rlen, RARRAY_PTR(ary) + beg + len,
|
||||||
VALUE, RARRAY_LEN(ary) - (beg + len));
|
VALUE, RARRAY_LEN(ary) - (beg + len));
|
||||||
ARY_SET_LEN(ary, alen);
|
RARRAY(ary)->len = alen;
|
||||||
}
|
}
|
||||||
if (rlen > 0) {
|
if (rlen > 0) {
|
||||||
MEMMOVE(RARRAY_PTR(ary) + beg, RARRAY_PTR(rpl), VALUE, rlen);
|
MEMMOVE(RARRAY_PTR(ary) + beg, RARRAY_PTR(rpl), VALUE, rlen);
|
||||||
@ -1360,7 +1286,7 @@ rb_ary_dup(VALUE ary)
|
|||||||
VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
|
VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
|
||||||
|
|
||||||
MEMCPY(RARRAY_PTR(dup), RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
|
MEMCPY(RARRAY_PTR(dup), RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
|
||||||
ARY_SET_LEN(dup, RARRAY_LEN(ary));
|
RARRAY(dup)->len = RARRAY_LEN(ary);
|
||||||
OBJ_INFECT(dup, ary);
|
OBJ_INFECT(dup, ary);
|
||||||
|
|
||||||
return dup;
|
return dup;
|
||||||
@ -1864,7 +1790,7 @@ rb_ary_delete(VALUE ary, VALUE item)
|
|||||||
|
|
||||||
rb_ary_modify(ary);
|
rb_ary_modify(ary);
|
||||||
if (RARRAY_LEN(ary) > i2) {
|
if (RARRAY_LEN(ary) > i2) {
|
||||||
ARY_SET_LEN(ary, i2);
|
RARRAY(ary)->len = i2;
|
||||||
if (i2 * 2 < ARY_CAPA(ary) &&
|
if (i2 * 2 < ARY_CAPA(ary) &&
|
||||||
ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
|
ARY_CAPA(ary) > ARY_DEFAULT_SIZE) {
|
||||||
RESIZE_CAPA(ary, i2*2);
|
RESIZE_CAPA(ary, i2*2);
|
||||||
@ -1890,7 +1816,7 @@ rb_ary_delete_at(VALUE ary, long pos)
|
|||||||
del = RARRAY_PTR(ary)[pos];
|
del = RARRAY_PTR(ary)[pos];
|
||||||
MEMMOVE(RARRAY_PTR(ary)+pos, RARRAY_PTR(ary)+pos+1, VALUE,
|
MEMMOVE(RARRAY_PTR(ary)+pos, RARRAY_PTR(ary)+pos+1, VALUE,
|
||||||
RARRAY_LEN(ary)-pos-1);
|
RARRAY_LEN(ary)-pos-1);
|
||||||
ARY_SET_LEN(ary, RARRAY_LEN(ary)-1);
|
RARRAY(ary)->len--;
|
||||||
|
|
||||||
return del;
|
return del;
|
||||||
}
|
}
|
||||||
@ -1992,7 +1918,7 @@ rb_ary_reject_bang(VALUE ary)
|
|||||||
}
|
}
|
||||||
if (RARRAY_LEN(ary) == i2) return Qnil;
|
if (RARRAY_LEN(ary) == i2) return Qnil;
|
||||||
if (i2 < RARRAY_LEN(ary))
|
if (i2 < RARRAY_LEN(ary))
|
||||||
ARY_SET_LEN(ary, i2);
|
RARRAY(ary)->len = i2;
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
@ -2145,29 +2071,20 @@ static VALUE
|
|||||||
rb_ary_replace(VALUE copy, VALUE orig)
|
rb_ary_replace(VALUE copy, VALUE orig)
|
||||||
{
|
{
|
||||||
VALUE shared;
|
VALUE shared;
|
||||||
|
VALUE *ptr;
|
||||||
|
|
||||||
rb_ary_modify(copy);
|
rb_ary_modify(copy);
|
||||||
orig = to_ary(orig);
|
orig = to_ary(orig);
|
||||||
if (copy == orig) return copy;
|
if (copy == orig) return copy;
|
||||||
if (ARY_EMBED_P(orig)) {
|
|
||||||
MEMCPY(RARRAY_PTR(copy), RARRAY_PTR(orig), VALUE, RARRAY_LEN(orig));
|
|
||||||
ARY_SET_LEN(copy, RARRAY_LEN(orig));
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
shared = ary_make_shared(orig);
|
shared = ary_make_shared(orig);
|
||||||
if (ARY_EMBED_P(copy)) {
|
ptr = RARRAY(copy)->ptr;
|
||||||
ARY_SET_NOEMBED(copy);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VALUE *ptr = RARRAY(copy)->as.heap.ptr;
|
|
||||||
if (ARY_LFREE_P(copy)) {
|
if (ARY_LFREE_P(copy)) {
|
||||||
ptr -= LFREE_SIZE(copy);
|
ptr -= LFREE_SIZE(copy);
|
||||||
}
|
}
|
||||||
xfree(ptr);
|
xfree(ptr);
|
||||||
}
|
RARRAY(copy)->ptr = RARRAY(shared)->ptr;
|
||||||
RARRAY(copy)->as.heap.ptr = RARRAY(shared)->as.heap.ptr;
|
RARRAY(copy)->len = RARRAY(shared)->len;
|
||||||
RARRAY(copy)->as.heap.len = RARRAY(shared)->as.heap.len;
|
RARRAY(copy)->aux.shared = shared;
|
||||||
RARRAY(copy)->as.heap.aux.shared = shared;
|
|
||||||
FL_SET(copy, ELTS_SHARED);
|
FL_SET(copy, ELTS_SHARED);
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
@ -2187,7 +2104,7 @@ VALUE
|
|||||||
rb_ary_clear(VALUE ary)
|
rb_ary_clear(VALUE ary)
|
||||||
{
|
{
|
||||||
rb_ary_modify(ary);
|
rb_ary_modify(ary);
|
||||||
ARY_SET_LEN(ary, 0);
|
RARRAY(ary)->len = 0;
|
||||||
if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
|
if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
|
||||||
RESIZE_CAPA(ary, ARY_DEFAULT_SIZE * 2);
|
RESIZE_CAPA(ary, ARY_DEFAULT_SIZE * 2);
|
||||||
}
|
}
|
||||||
@ -2260,7 +2177,7 @@ rb_ary_fill(int argc, VALUE *argv, VALUE ary)
|
|||||||
RESIZE_CAPA(ary, end);
|
RESIZE_CAPA(ary, end);
|
||||||
}
|
}
|
||||||
rb_mem_clear(RARRAY_PTR(ary) + RARRAY_LEN(ary), end - RARRAY_LEN(ary));
|
rb_mem_clear(RARRAY_PTR(ary) + RARRAY_LEN(ary), end - RARRAY_LEN(ary));
|
||||||
ARY_SET_LEN(ary, end);
|
RARRAY(ary)->len = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block_p) {
|
if (block_p) {
|
||||||
@ -2304,7 +2221,7 @@ rb_ary_plus(VALUE x, VALUE y)
|
|||||||
z = rb_ary_new2(len);
|
z = rb_ary_new2(len);
|
||||||
MEMCPY(RARRAY_PTR(z), RARRAY_PTR(x), VALUE, RARRAY_LEN(x));
|
MEMCPY(RARRAY_PTR(z), RARRAY_PTR(x), VALUE, RARRAY_LEN(x));
|
||||||
MEMCPY(RARRAY_PTR(z) + RARRAY_LEN(x), RARRAY_PTR(y), VALUE, RARRAY_LEN(y));
|
MEMCPY(RARRAY_PTR(z) + RARRAY_LEN(x), RARRAY_PTR(y), VALUE, RARRAY_LEN(y));
|
||||||
ARY_SET_LEN(z, len);
|
RARRAY(z)->len = len;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2366,7 +2283,7 @@ rb_ary_times(VALUE ary, VALUE times)
|
|||||||
len *= RARRAY_LEN(ary);
|
len *= RARRAY_LEN(ary);
|
||||||
|
|
||||||
ary2 = ary_new(rb_obj_class(ary), len);
|
ary2 = ary_new(rb_obj_class(ary), len);
|
||||||
ARY_SET_LEN(ary2, len);
|
RARRAY(ary2)->len = len;
|
||||||
|
|
||||||
for (i=0; i<len; i+=RARRAY_LEN(ary)) {
|
for (i=0; i<len; i+=RARRAY_LEN(ary)) {
|
||||||
MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
|
MEMCPY(RARRAY_PTR(ary2)+i, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
|
||||||
@ -2746,7 +2663,7 @@ rb_ary_uniq_bang(VALUE ary)
|
|||||||
rb_ary_store(ary, j++, v);
|
rb_ary_store(ary, j++, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ARY_SET_LEN(ary, j);
|
RARRAY(ary)->len = j;
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
@ -2799,7 +2716,7 @@ rb_ary_compact_bang(VALUE ary)
|
|||||||
}
|
}
|
||||||
n = p - RARRAY_PTR(ary);
|
n = p - RARRAY_PTR(ary);
|
||||||
RESIZE_CAPA(ary, n);
|
RESIZE_CAPA(ary, n);
|
||||||
ARY_SET_LEN(ary, n);
|
RARRAY(ary)->len = n;
|
||||||
|
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
2
gc.c
2
gc.c
@ -926,7 +926,7 @@ gc_mark_children(VALUE ptr, int lev)
|
|||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
if (FL_TEST(obj, ELTS_SHARED)) {
|
if (FL_TEST(obj, ELTS_SHARED)) {
|
||||||
ptr = obj->as.array.as.heap.aux.shared;
|
ptr = obj->as.array.aux.shared;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
20
ruby.h
20
ruby.h
@ -391,33 +391,17 @@ struct RString {
|
|||||||
RSTRING(str)->as.ary : \
|
RSTRING(str)->as.ary : \
|
||||||
RSTRING(str)->as.heap.ptr)
|
RSTRING(str)->as.heap.ptr)
|
||||||
|
|
||||||
#define RARRAY_EMBED_LEN_MAX 3
|
|
||||||
struct RArray {
|
struct RArray {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
long len;
|
long len;
|
||||||
union {
|
union {
|
||||||
long capa;
|
long capa;
|
||||||
VALUE shared;
|
VALUE shared;
|
||||||
} aux;
|
} aux;
|
||||||
VALUE *ptr;
|
VALUE *ptr;
|
||||||
} heap;
|
|
||||||
VALUE ary[RARRAY_EMBED_LEN_MAX];
|
|
||||||
} as;
|
|
||||||
};
|
};
|
||||||
#define RARRAY_NOEMBED FL_USER3
|
#define RARRAY_LEN(a) RARRAY(a)->len
|
||||||
#define RARRAY_EMBED_LEN_MASK (FL_USER4|FL_USER5)
|
#define RARRAY_PTR(a) RARRAY(a)->ptr
|
||||||
#define RARRAY_EMBED_LEN_SHIFT (FL_USHIFT+4)
|
|
||||||
#define RARRAY_LEN(a) \
|
|
||||||
(!(RBASIC(a)->flags & RARRAY_NOEMBED) ? \
|
|
||||||
(long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
|
|
||||||
(RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT)) : \
|
|
||||||
RARRAY(a)->as.heap.len)
|
|
||||||
#define RARRAY_PTR(a) \
|
|
||||||
(!(RBASIC(a)->flags & RARRAY_NOEMBED) ? \
|
|
||||||
RARRAY(a)->as.ary : \
|
|
||||||
RARRAY(a)->as.heap.ptr)
|
|
||||||
|
|
||||||
struct RRegexp {
|
struct RRegexp {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user