Skip to content

Commit 227bb0b

Browse files
committed
Move ROBJECT_HEAP into shape
1 parent f7985af commit 227bb0b

21 files changed

Lines changed: 308 additions & 159 deletions

File tree

debug.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ const union {
5252
enum ruby_econv_flag_type econv_flag_types;
5353
rb_econv_result_t econv_result;
5454
enum ruby_preserved_encindex encoding_index;
55-
enum ruby_robject_flags robject_flags;
5655
enum ruby_rmodule_flags rmodule_flags;
5756
enum ruby_rstring_flags rstring_flags;
5857
enum ruby_rarray_flags rarray_flags;

ext/objspace/objspace_dump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ dump_object(VALUE obj, struct dump_config *dc)
592592
break;
593593

594594
case T_OBJECT:
595-
if (!FL_TEST_RAW(obj, ROBJECT_HEAP)) {
595+
if (!rb_obj_shape_heap_p(obj)) {
596596
dump_append(dc, ", \"embedded\":true");
597597
}
598598

gc.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,7 @@ rb_gc_imemo_needs_cleanup_p(VALUE obj)
13561356
return ((rb_imemo_tmpbuf_t *)obj)->ptr != NULL;
13571357

13581358
case imemo_fields:
1359-
return FL_TEST_RAW(obj, OBJ_FIELD_HEAP) || (id2ref_tbl && rb_obj_shape_has_id(obj));
1359+
return rb_obj_shape_heap_p(obj) || (id2ref_tbl && rb_obj_shape_has_id(obj));
13601360
}
13611361
UNREACHABLE_RETURN(true);
13621362
}
@@ -1412,7 +1412,7 @@ rb_gc_obj_needs_cleanup_p(VALUE obj)
14121412

14131413
switch (flags & RUBY_T_MASK) {
14141414
case T_OBJECT:
1415-
if (flags & ROBJECT_HEAP) return true;
1415+
if (rb_obj_shape_heap_p(obj)) return true;
14161416
return false;
14171417

14181418
case T_DATA:
@@ -1557,7 +1557,7 @@ rb_gc_obj_free(void *objspace, VALUE obj)
15571557

15581558
switch (BUILTIN_TYPE(obj)) {
15591559
case T_OBJECT:
1560-
if (FL_TEST_RAW(obj, ROBJECT_HEAP)) {
1560+
if (rb_obj_shape_heap_p(obj)) {
15611561
if (rb_obj_shape_complex_p(obj)) {
15621562
RB_DEBUG_COUNTER_INC(obj_obj_complex);
15631563
st_free_table(ROBJECT_FIELDS_HASH(obj));
@@ -2198,7 +2198,7 @@ object_id0(VALUE obj)
21982198
id = generate_next_object_id();
21992199
rb_obj_field_set(obj, object_id_shape_id, 0, id);
22002200

2201-
RUBY_ASSERT(RBASIC_SHAPE_ID(obj) == object_id_shape_id);
2201+
RUBY_ASSERT(RBASIC_SHAPE_ID(obj) == object_id_shape_id || RBASIC_SHAPE_ID(obj) == rb_shape_transition_heap(object_id_shape_id));
22022202
RUBY_ASSERT(rb_obj_shape_has_id(obj));
22032203

22042204
if (RB_UNLIKELY(id2ref_tbl)) {
@@ -2604,7 +2604,7 @@ rb_obj_memsize_of(VALUE obj)
26042604

26052605
switch (BUILTIN_TYPE(obj)) {
26062606
case T_OBJECT:
2607-
if (FL_TEST_RAW(obj, ROBJECT_HEAP)) {
2607+
if (rb_obj_shape_heap_p(obj)) {
26082608
if (rb_obj_shape_complex_p(obj)) {
26092609
size += rb_st_memsize(ROBJECT_FIELDS_HASH(obj));
26102610
}
@@ -3882,7 +3882,7 @@ gc_ref_update_object(void *objspace, VALUE v)
38823882
{
38833883
VALUE *ptr = ROBJECT_FIELDS(v);
38843884

3885-
if (FL_TEST_RAW(v, ROBJECT_HEAP)) {
3885+
if (rb_obj_shape_heap_p(v)) {
38863886
if (rb_obj_shape_complex_p(v)) {
38873887
gc_ref_update_table_values_only(ROBJECT_FIELDS_HASH(v));
38883888
return;
@@ -3894,7 +3894,7 @@ gc_ref_update_object(void *objspace, VALUE v)
38943894
// Object can be re-embedded
38953895
memcpy(ROBJECT(v)->as.ary, ptr, sizeof(VALUE) * ROBJECT_FIELDS_COUNT(v));
38963896
SIZED_FREE_N(ptr, ROBJECT_FIELDS_CAPACITY(v));
3897-
FL_UNSET_RAW(v, ROBJECT_HEAP);
3897+
RBASIC_SET_SHAPE_ID(v, rb_obj_shape_transition_embedded(v));
38983898
ptr = ROBJECT(v)->as.ary;
38993899
}
39003900
}
@@ -5087,7 +5087,7 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU
50875087
}
50885088
case T_OBJECT:
50895089
{
5090-
if (FL_TEST_RAW(obj, ROBJECT_HEAP)) {
5090+
if (rb_obj_shape_heap_p(obj)) {
50915091
if (rb_obj_shape_complex_p(obj)) {
50925092
size_t hash_len = rb_st_table_size(ROBJECT_FIELDS_HASH(obj));
50935093
APPEND_F("(complex) len:%zu", hash_len);

imemo.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ rb_imemo_fields_new(VALUE owner, shape_id_t shape_id, bool shareable)
141141
// layout in the shape describes the layout of the thing on which it is set.
142142
// Imemo fields have the same layout as robject, therefore the layout
143143
// should reflect that fact.
144-
RBASIC_SET_SHAPE_ID(fields, rb_shape_id_with_robject_layout(shape_id));
144+
RBASIC_SET_SHAPE_ID(fields, rb_shape_id_with_robject_layout(rb_shape_transition_embedded(shape_id)));
145145
RUBY_ASSERT(IMEMO_TYPE_P(fields, imemo_fields));
146146
return fields;
147147
}
@@ -151,12 +151,11 @@ rb_imemo_fields_new_complex(VALUE owner, shape_id_t shape_id, size_t capa, bool
151151
{
152152
VALUE fields = rb_imemo_new(imemo_fields, owner, sizeof(struct rb_fields), shareable);
153153
IMEMO_OBJ_FIELDS(fields)->as.complex.table = st_init_numtable_with_size(capa);
154-
FL_SET_RAW(fields, OBJ_FIELD_HEAP);
155154
// imemo fields objects should always have "RObject" layout. The
156155
// layout in the shape describes the layout of the thing on which it is set.
157156
// Imemo fields have the same layout as robject, therefore the layout
158157
// should reflect that fact.
159-
RBASIC_SET_SHAPE_ID(fields, rb_shape_id_with_robject_layout(shape_id));
158+
RBASIC_SET_SHAPE_ID(fields, rb_shape_id_with_robject_layout(rb_shape_transition_heap(shape_id)));
160159
return fields;
161160
}
162161

@@ -180,12 +179,11 @@ rb_imemo_fields_new_complex_tbl(VALUE owner, shape_id_t shape_id, st_table *tbl,
180179
{
181180
VALUE fields = rb_imemo_new(imemo_fields, owner, sizeof(struct rb_fields), shareable);
182181
IMEMO_OBJ_FIELDS(fields)->as.complex.table = tbl;
183-
FL_SET_RAW(fields, OBJ_FIELD_HEAP);
184182
// imemo fields objects should always have "RObject" layout. The
185183
// layout in the shape describes the layout of the thing on which it is set.
186184
// Imemo fields have the same layout as robject, therefore the layout
187185
// should reflect that fact.
188-
RBASIC_SET_SHAPE_ID(fields, rb_shape_id_with_robject_layout(shape_id));
186+
RBASIC_SET_SHAPE_ID(fields, rb_shape_id_with_robject_layout(rb_shape_transition_heap(shape_id)));
189187
st_foreach(tbl, imemo_fields_trigger_wb_i, (st_data_t)fields);
190188
return fields;
191189
}
@@ -628,7 +626,7 @@ rb_free_const_table(struct rb_id_table *tbl)
628626
static inline void
629627
imemo_fields_free(struct rb_fields *fields)
630628
{
631-
if (FL_TEST_RAW((VALUE)fields, OBJ_FIELD_HEAP)) {
629+
if (rb_obj_shape_heap_p((VALUE)fields)) {
632630
RUBY_ASSERT(rb_shape_complex_p(RBASIC_SHAPE_ID((VALUE)fields)));
633631
st_free_table(fields->as.complex.table);
634632
}

include/ruby/internal/core/robject.h

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,28 @@
5353
*
5454
* Bits that you can set to ::RBasic::flags.
5555
*/
56-
enum ruby_robject_flags {
57-
/**
58-
* This flag marks that the object's instance variables are stored in an
59-
* external heap buffer.
60-
* Normally, instance variable references are stored inside the object slot,
61-
* but if it overflow, Ruby may have to allocate a separate buffer and spills
62-
* the instance variables there.
63-
* This flag denotes that situation.
64-
*
65-
* @warning This bit has to be considered read-only. Setting/clearing
66-
* this bit without corresponding fix up must cause immediate
67-
* SEGV. Also, internal structures of an object change
68-
* dynamically and transparently throughout of its lifetime.
69-
* Don't assume it being persistent.
70-
*
71-
* @internal
72-
*
73-
* 3rd parties must not be aware that there even is more than one way to
74-
* store instance variables. Might better be hidden.
75-
*/
76-
ROBJECT_HEAP = RUBY_FL_USER4
77-
};
56+
// enum ruby_robject_flags {
57+
// /**
58+
// * This flag marks that the object's instance variables are stored in an
59+
// * external heap buffer.
60+
// * Normally, instance variable references are stored inside the object slot,
61+
// * but if it overflow, Ruby may have to allocate a separate buffer and spills
62+
// * the instance variables there.
63+
// * This flag denotes that situation.
64+
// *
65+
// * @warning This bit has to be considered read-only. Setting/clearing
66+
// * this bit without corresponding fix up must cause immediate
67+
// * SEGV. Also, internal structures of an object change
68+
// * dynamically and transparently throughout of its lifetime.
69+
// * Don't assume it being persistent.
70+
// *
71+
// * @internal
72+
// *
73+
// * 3rd parties must not be aware that there even is more than one way to
74+
// * store instance variables. Might better be hidden.
75+
// */
76+
// ROBJECT_HEAP = RUBY_FL_USER4
77+
// };
7878

7979
struct st_table;
8080

internal/class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "id.h"
1212
#include "id_table.h" /* for struct rb_id_table */
1313
#include "internal/box.h"
14+
#include "internal/gc.h"
1415
#include "internal/serial.h" /* for rb_serial_t */
1516
#include "internal/static_assert.h"
1617
#include "internal/variable.h" /* for rb_class_ivar_set */

internal/imemo.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111
#include "ruby/internal/config.h"
1212
#include <stddef.h> /* for size_t */
13+
#include "shape.h"
1314
#include "id_table.h"
1415
#include "internal/array.h" /* for rb_ary_hidden_new_fill */
1516
#include "ruby/internal/stdbool.h" /* for bool */
@@ -171,7 +172,7 @@ imemo_type(VALUE imemo)
171172
static inline int
172173
imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
173174
{
174-
if (LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
175+
if (RB_LIKELY(!RB_SPECIAL_CONST_P(imemo))) {
175176
/* fixed at compile time if imemo_type is given. */
176177
const VALUE mask = (IMEMO_MASK << FL_USHIFT) | RUBY_T_MASK;
177178
const VALUE expected_type = (imemo_type << FL_USHIFT) | T_IMEMO;
@@ -258,7 +259,6 @@ struct rb_fields {
258259
// IMEMO/fields and T_OBJECT have exactly the same layout.
259260
// This is useful for JIT and common codepaths.
260261
#define OBJ_FIELD_HEAP ROBJECT_HEAP
261-
STATIC_ASSERT(imemo_fields_flags, OBJ_FIELD_HEAP == IMEMO_FL_USER0);
262262
STATIC_ASSERT(imemo_fields_embed_offset, offsetof(struct RObject, as.ary) == offsetof(struct rb_fields, as.embed.fields));
263263
STATIC_ASSERT(imemo_fields_external_offset, offsetof(struct RObject, as.heap.fields) == offsetof(struct rb_fields, as.external.ptr));
264264
STATIC_ASSERT(imemo_fields_complex_offset, offsetof(struct RObject, as.heap.fields) == offsetof(struct rb_fields, as.complex.table));
@@ -308,7 +308,7 @@ rb_imemo_fields_ptr(VALUE fields_obj)
308308

309309
RUBY_ASSERT(IMEMO_TYPE_P(fields_obj, imemo_fields) || RB_TYPE_P(fields_obj, T_OBJECT));
310310

311-
if (UNLIKELY(FL_TEST_RAW(fields_obj, OBJ_FIELD_HEAP))) {
311+
if (RB_UNLIKELY(rb_obj_shape_heap_p(fields_obj))) {
312312
return IMEMO_OBJ_FIELDS(fields_obj)->as.external.ptr;
313313
}
314314
else {
@@ -324,7 +324,7 @@ rb_imemo_fields_complex_tbl(VALUE fields_obj)
324324
}
325325

326326
RUBY_ASSERT(IMEMO_TYPE_P(fields_obj, imemo_fields) || RB_TYPE_P(fields_obj, T_OBJECT));
327-
RUBY_ASSERT(FL_TEST_RAW(fields_obj, OBJ_FIELD_HEAP));
327+
RUBY_ASSERT(rb_obj_shape_heap_p(fields_obj));
328328

329329
// Some codepaths unconditionally access the fields_ptr, and assume it can be used as st_table if the
330330
// shape is complex.

internal/object.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
* @brief Internal header for Object.
1010
*/
1111
#include "ruby/ruby.h" /* for VALUE */
12+
#include "shape.h"
1213

1314
/* object.c */
1415

@@ -68,7 +69,7 @@ ROBJECT_FIELDS(VALUE obj)
6869

6970
struct RObject *const ptr = ROBJECT(obj);
7071

71-
if (RB_UNLIKELY(RB_FL_ANY_RAW(obj, ROBJECT_HEAP))) {
72+
if (RB_UNLIKELY(rb_obj_shape_heap_p(obj))) {
7273
return ptr->as.heap.fields;
7374
}
7475
else {

internal/variable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "ruby/internal/stdbool.h" /* for bool */
1515
#include "ruby/ruby.h" /* for VALUE */
1616
#include "shape.h" /* for shape_id_t */
17+
#include "box.h"
18+
#include "internal/gc.h"
1719

1820
/* variable.c */
1921
void rb_gc_mark_global_tbl(void);

object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ rb_obj_copy_ivar(VALUE dest, VALUE obj)
364364
RUBY_ASSERT(src_num_ivs <= dest_capa);
365365
if (initial_capa < dest_capa) {
366366
rb_ensure_iv_list_size(dest, 0, dest_capa);
367+
dest_shape_id = rb_shape_transition_heap(dest_shape_id);
367368
dest_buf = ROBJECT_FIELDS(dest);
368369
}
369370

0 commit comments

Comments
 (0)