Skip to content

Commit c558ad4

Browse files
committed
flexible object size
This change introduces struct RValueStorage, so that objects can be any compile-time defined width. Note however, that some objects embeds others by nature, and so they need length info packed into their flags. Most are OK but Strings have no space left in their flags to introduce wider buffers (because they also embed encoding index in it). In order to cover that we needed to use upper-half of the flag bits. If there is no such thing like upper halfs on your machine, Strings cannot use full amount of spaces that they are promised to have.
1 parent 72385b0 commit c558ad4

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

gc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ typedef struct RVALUE {
328328
VALUE flags; /* always 0 for freed obj */
329329
struct RVALUE *next;
330330
} free;
331+
struct RValueStorage storage;
331332
struct RBasic basic;
332333
struct RObject object;
333334
struct RClass klass;

include/ruby/ruby.h

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);
744744
#define RGENGC_WB_PROTECTED_NODE_CREF 1
745745
#endif
746746

747+
#define SIZEOF_RBasic (2 * SIZEOF_VALUE)
747748
struct RBasic {
748749
VALUE flags;
749750
const VALUE klass;
@@ -758,7 +759,14 @@ VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change kl
758759

759760
#define RBASIC_CLASS(obj) (RBASIC(obj)->klass)
760761

761-
#define ROBJECT_EMBED_LEN_MAX 3
762+
#define SIZEOF_RValueStorage (5 * SIZEOF_VALUE)
763+
#define RValueStorage_EMBED_LEN_MAX(ELEM_SIZE) ((SIZEOF_RValueStorage - SIZEOF_RBasic) / ELEM_SIZE)
764+
struct RValueStorage {
765+
/* This is much like struct sockaddr_storage */
766+
char storage[SIZEOF_RValueStorage];
767+
};
768+
769+
#define ROBJECT_EMBED_LEN_MAX RValueStorage_EMBED_LEN_MAX(SIZEOF_VALUE)
762770
struct RObject {
763771
struct RBasic basic;
764772
union {
@@ -816,7 +824,12 @@ VALUE rb_float_new_in_heap(double);
816824

817825
#define ELTS_SHARED FL_USER2
818826

819-
#define RSTRING_EMBED_LEN_MAX ((int)((sizeof(VALUE)*3)/sizeof(char)-1))
827+
#if SIZEOF_VALUE >= 5
828+
#define RSTRING_EMBED_LEN_MAX (RValueStorage_EMBED_LEN_MAX(1) - 1) /* sizeof(char) is always 1 */
829+
#else
830+
/* as.basic.flags has no bits left to hold length of 46 chars this case >< */
831+
#define RSTRING_EMBED_LEN_MAX (31)
832+
#endif
820833
struct RString {
821834
struct RBasic basic;
822835
union {
@@ -833,8 +846,15 @@ struct RString {
833846
};
834847
#define RSTRING_NOEMBED FL_USER1
835848
#define RSTRING_FSTR FL_USER17
849+
#if RSTRING_EMBED_LEN_MAX < 32
836850
#define RSTRING_EMBED_LEN_MASK (FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6)
837851
#define RSTRING_EMBED_LEN_SHIFT (FL_USHIFT+2)
852+
#elif RSTRING_EMBED_LEN_MAX < 256
853+
#define RSTRING_EMBED_LEN_MASK (0xFF00000000ULL)
854+
#define RSTRING_EMBED_LEN_SHIFT (32)
855+
#else
856+
#error to be defined.
857+
#endif
838858
#define RSTRING_EMBED_LEN(str) \
839859
(long)((RBASIC(str)->flags >> RSTRING_EMBED_LEN_SHIFT) & \
840860
(RSTRING_EMBED_LEN_MASK >> RSTRING_EMBED_LEN_SHIFT))
@@ -856,7 +876,7 @@ struct RString {
856876
((ptrvar) = RSTRING(str)->as.ary, (lenvar) = RSTRING_EMBED_LEN(str)) : \
857877
((ptrvar) = RSTRING(str)->as.heap.ptr, (lenvar) = RSTRING(str)->as.heap.len))
858878

859-
#define RARRAY_EMBED_LEN_MAX 3
879+
#define RARRAY_EMBED_LEN_MAX RValueStorage_EMBED_LEN_MAX(SIZEOF_VALUE)
860880
struct RArray {
861881
struct RBasic basic;
862882
union {
@@ -873,8 +893,8 @@ struct RArray {
873893
};
874894
#define RARRAY_EMBED_FLAG FL_USER1
875895
/* FL_USER2 is for ELTS_SHARED */
876-
#define RARRAY_EMBED_LEN_MASK (FL_USER4|FL_USER3)
877-
#define RARRAY_EMBED_LEN_SHIFT (FL_USHIFT+3)
896+
#define RARRAY_EMBED_LEN_MASK (FL_USER6|FL_USER7|FL_USER8)
897+
#define RARRAY_EMBED_LEN_SHIFT (FL_USHIFT+6)
878898
#define RARRAY_LEN(a) \
879899
((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ? \
880900
(long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \
@@ -1044,7 +1064,7 @@ void *rb_check_typeddata(VALUE, const rb_data_type_t *);
10441064
(sval) = (type*)rb_check_typeddata((obj), (data_type)); \
10451065
} while (0)
10461066

1047-
#define RSTRUCT_EMBED_LEN_MAX 3
1067+
#define RSTRUCT_EMBED_LEN_MAX RValueStorage_EMBED_LEN_MAX(SIZEOF_VALUE)
10481068
struct RStruct {
10491069
struct RBasic basic;
10501070
union {
@@ -1055,7 +1075,7 @@ struct RStruct {
10551075
const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
10561076
} as;
10571077
};
1058-
#define RSTRUCT_EMBED_LEN_MASK (FL_USER2|FL_USER1)
1078+
#define RSTRUCT_EMBED_LEN_MASK (FL_USER3|FL_USER2|FL_USER1)
10591079
#define RSTRUCT_EMBED_LEN_SHIFT (FL_USHIFT+1)
10601080
#define RSTRUCT_LEN(st) \
10611081
((RBASIC(st)->flags & RSTRUCT_EMBED_LEN_MASK) ? \
@@ -1072,10 +1092,10 @@ struct RStruct {
10721092
#define RSTRUCT_SET(st, idx, v) RB_OBJ_WRITE(st, &RSTRUCT_CONST_PTR(st)[idx], (v))
10731093
#define RSTRUCT_GET(st, idx) (RSTRUCT_CONST_PTR(st)[idx])
10741094

1075-
#define RBIGNUM_EMBED_LEN_NUMBITS 3
1095+
#define RBIGNUM_EMBED_LEN_NUMBITS 4
10761096
#ifndef RBIGNUM_EMBED_LEN_MAX
1077-
# if (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT) < (1 << RBIGNUM_EMBED_LEN_NUMBITS)-1
1078-
# define RBIGNUM_EMBED_LEN_MAX (SIZEOF_VALUE*3/SIZEOF_ACTUAL_BDIGIT)
1097+
# if RValueStorage_EMBED_LEN_MAX(SIZEOF_ACTUAL_BDIGIT) < (1 << RBIGNUM_EMBED_LEN_NUMBITS)-1
1098+
# define RBIGNUM_EMBED_LEN_MAX RValueStorage_EMBED_LEN_MAX(SIZEOF_ACTUAL_BDIGIT)
10791099
# else
10801100
# define RBIGNUM_EMBED_LEN_MAX ((1 << RBIGNUM_EMBED_LEN_NUMBITS)-1)
10811101
# endif
@@ -1100,8 +1120,8 @@ struct RBignum {
11001120
#define RBIGNUM_NEGATIVE_P(b) (!RBIGNUM_SIGN(b))
11011121

11021122
#define RBIGNUM_EMBED_FLAG FL_USER2
1103-
#define RBIGNUM_EMBED_LEN_MASK (FL_USER5|FL_USER4|FL_USER3)
1104-
#define RBIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+RBIGNUM_EMBED_LEN_NUMBITS)
1123+
#define RBIGNUM_EMBED_LEN_MASK (FL_USER6|FL_USER5|FL_USER4|FL_USER3)
1124+
#define RBIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+3)
11051125
#define RBIGNUM_LEN(b) \
11061126
((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
11071127
(long)((RBASIC(b)->flags >> RBIGNUM_EMBED_LEN_SHIFT) & \

0 commit comments

Comments
 (0)