33#include "id_table.h"
44#include "internal.h"
55#include "internal/imemo.h"
6+ #include "internal/st.h"
67#include "vm_callinfo.h"
78
89size_t rb_iseq_memsize (const rb_iseq_t * iseq );
@@ -29,10 +30,10 @@ rb_imemo_name(enum imemo_type type)
2930 IMEMO_NAME (svar );
3031 IMEMO_NAME (throw_data );
3132 IMEMO_NAME (tmpbuf );
33+ IMEMO_NAME (class_fields );
3234#undef IMEMO_NAME
33- default :
34- rb_bug ("unreachable" );
3535 }
36+ rb_bug ("unreachable" );
3637}
3738
3839/* =========================================================================
@@ -109,6 +110,63 @@ rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt)
109110 return tmpbuf ;
110111}
111112
113+ static VALUE
114+ imemo_class_fields_new (VALUE klass , size_t capa )
115+ {
116+ size_t embedded_size = sizeof (struct rb_class_fields ) + ((capa - 1 ) * sizeof (VALUE ));
117+ if (rb_gc_size_allocatable_p (embedded_size )) {
118+ VALUE fields = rb_imemo_new (imemo_class_fields , klass , embedded_size );
119+ RUBY_ASSERT (IMEMO_TYPE_P (fields , imemo_class_fields ));
120+ return fields ;
121+ }
122+ else {
123+ VALUE fields = rb_imemo_new (imemo_class_fields , klass , sizeof (VALUE * ));
124+ FL_SET_RAW (fields , OBJ_FIELD_EXTERNAL );
125+ IMEMO_OBJ_FIELDS (fields )-> as .external .ptr = ALLOC_N (VALUE , capa );
126+ return fields ;
127+ }
128+ }
129+
130+ VALUE
131+ rb_imemo_class_fields_new (VALUE klass , size_t capa )
132+ {
133+ return imemo_class_fields_new (rb_singleton_class (klass ), capa );
134+ }
135+
136+ static VALUE
137+ imemo_class_fields_new_complex (VALUE klass , size_t capa )
138+ {
139+ VALUE fields = imemo_class_fields_new (klass , sizeof (struct rb_class_fields ));
140+ FL_SET_RAW (fields , OBJ_FIELD_COMPLEX );
141+ IMEMO_OBJ_FIELDS (fields )-> as .complex .table = st_init_numtable_with_size (capa );
142+ return fields ;
143+ }
144+
145+ VALUE
146+ rb_imemo_class_fields_new_complex (VALUE klass , size_t capa )
147+ {
148+ return imemo_class_fields_new_complex (rb_singleton_class (klass ), capa );
149+ }
150+
151+ VALUE
152+ rb_imemo_class_fields_clone (VALUE fields_obj )
153+ {
154+ rb_shape_t * shape = rb_obj_shape (fields_obj );
155+ VALUE clone ;
156+
157+ if (rb_shape_too_complex_p (shape )) {
158+ clone = rb_imemo_class_fields_new_complex (CLASS_OF (fields_obj ), 0 );
159+ st_table * src_table = rb_imemo_class_fields_complex_tbl (fields_obj );
160+ st_replace (rb_imemo_class_fields_complex_tbl (clone ), src_table );
161+ }
162+ else {
163+ clone = imemo_class_fields_new (CLASS_OF (fields_obj ), shape -> capacity );
164+ MEMCPY (rb_imemo_class_fields_ptr (clone ), rb_imemo_class_fields_ptr (fields_obj ), VALUE , shape -> next_field_index );
165+ }
166+
167+ return clone ;
168+ }
169+
112170/* =========================================================================
113171 * memsize
114172 * ========================================================================= */
@@ -155,6 +213,14 @@ rb_imemo_memsize(VALUE obj)
155213 case imemo_tmpbuf :
156214 size += ((rb_imemo_tmpbuf_t * )obj )-> cnt * sizeof (VALUE );
157215
216+ break ;
217+ case imemo_class_fields :
218+ if (FL_TEST_RAW (obj , OBJ_FIELD_COMPLEX )) {
219+ size += st_memsize (IMEMO_OBJ_FIELDS (obj )-> as .complex .table );
220+ }
221+ else if (FL_TEST_RAW (obj , OBJ_FIELD_EXTERNAL )) {
222+ size += 0 ; // TODO: Get record the size
223+ }
158224 break ;
159225 default :
160226 rb_bug ("unreachable" );
@@ -420,6 +486,22 @@ rb_imemo_mark_and_move(VALUE obj, bool reference_updating)
420486
421487 break ;
422488 }
489+ case imemo_class_fields : {
490+ struct rb_class_fields * cf = (struct rb_class_fields * )obj ;
491+ rb_gc_mark_and_move (& cf -> klass );
492+
493+ if (rb_shape_obj_too_complex_p (obj )) {
494+ rb_mark_tbl_no_pin (rb_imemo_class_fields_complex_tbl (obj ));
495+ }
496+ else {
497+ VALUE * fields = rb_imemo_class_fields_ptr (obj );
498+ uint32_t len = RSHAPE (rb_obj_shape_id (obj ))-> next_field_index ;
499+ for (uint32_t i = 0 ; i < len ; i ++ ) {
500+ rb_gc_mark_and_move (& fields [i ]);
501+ }
502+ }
503+ break ;
504+ }
423505 default :
424506 rb_bug ("unreachable" );
425507 }
@@ -513,6 +595,17 @@ rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass)
513595 rb_id_table_free (cc_tbl );
514596}
515597
598+ static inline void
599+ imemo_class_fields_free (struct rb_class_fields * fields )
600+ {
601+ if (FL_TEST_RAW ((VALUE )fields , OBJ_FIELD_COMPLEX )) {
602+ st_free_table (fields -> as .complex .table );
603+ }
604+ else if (FL_TEST_RAW ((VALUE )fields , OBJ_FIELD_EXTERNAL )) {
605+ xfree (fields -> as .external .ptr );
606+ }
607+ }
608+
516609void
517610rb_imemo_free (VALUE obj )
518611{
@@ -576,6 +669,7 @@ rb_imemo_free(VALUE obj)
576669 break ;
577670 case imemo_svar :
578671 RB_DEBUG_COUNTER_INC (obj_imemo_svar );
672+
579673 break ;
580674 case imemo_throw_data :
581675 RB_DEBUG_COUNTER_INC (obj_imemo_throw_data );
@@ -585,6 +679,10 @@ rb_imemo_free(VALUE obj)
585679 xfree (((rb_imemo_tmpbuf_t * )obj )-> ptr );
586680 RB_DEBUG_COUNTER_INC (obj_imemo_tmpbuf );
587681
682+ break ;
683+ case imemo_class_fields :
684+ imemo_class_fields_free (IMEMO_OBJ_FIELDS (obj ));
685+ RB_DEBUG_COUNTER_INC (obj_imemo_class_fields );
588686 break ;
589687 default :
590688 rb_bug ("unreachable" );
0 commit comments