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,19 @@ rb_imemo_mark_and_move(VALUE obj, bool reference_updating)
420486
421487 break ;
422488 }
489+ case imemo_class_fields : {
490+ if (rb_shape_obj_too_complex_p (obj )) {
491+ rb_mark_tbl_no_pin (rb_imemo_class_fields_complex_tbl (obj ));
492+ }
493+ else {
494+ VALUE * fields = rb_imemo_class_fields_ptr (obj );
495+ uint32_t len = RSHAPE (rb_obj_shape_id (obj ))-> next_field_index ;
496+ for (uint32_t i = 0 ; i < len ; i ++ ) {
497+ rb_gc_mark_and_move (& fields [i ]);
498+ }
499+ }
500+ break ;
501+ }
423502 default :
424503 rb_bug ("unreachable" );
425504 }
@@ -513,6 +592,17 @@ rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass)
513592 rb_id_table_free (cc_tbl );
514593}
515594
595+ static inline void
596+ imemo_class_fields_free (struct rb_class_fields * fields )
597+ {
598+ if (FL_TEST_RAW ((VALUE )fields , OBJ_FIELD_COMPLEX )) {
599+ st_free_table (fields -> as .complex .table );
600+ }
601+ else if (FL_TEST_RAW ((VALUE )fields , OBJ_FIELD_EXTERNAL )) {
602+ xfree (fields -> as .external .ptr );
603+ }
604+ }
605+
516606void
517607rb_imemo_free (VALUE obj )
518608{
@@ -576,6 +666,7 @@ rb_imemo_free(VALUE obj)
576666 break ;
577667 case imemo_svar :
578668 RB_DEBUG_COUNTER_INC (obj_imemo_svar );
669+
579670 break ;
580671 case imemo_throw_data :
581672 RB_DEBUG_COUNTER_INC (obj_imemo_throw_data );
@@ -585,6 +676,10 @@ rb_imemo_free(VALUE obj)
585676 xfree (((rb_imemo_tmpbuf_t * )obj )-> ptr );
586677 RB_DEBUG_COUNTER_INC (obj_imemo_tmpbuf );
587678
679+ break ;
680+ case imemo_class_fields :
681+ imemo_class_fields_free (IMEMO_OBJ_FIELDS (obj ));
682+ RB_DEBUG_COUNTER_INC (obj_imemo_class_fields );
588683 break ;
589684 default :
590685 rb_bug ("unreachable" );
0 commit comments