@@ -84,14 +84,6 @@ static void rb_class_remove_from_super_subclasses(VALUE klass);
8484static void rb_class_remove_from_module_subclasses (VALUE klass );
8585static void rb_class_classext_free_subclasses (rb_classext_t * ext );
8686
87- static enum rb_id_table_iterator_result
88- cvar_table_free_i (VALUE value , void * ctx )
89- {
90- struct rb_cvar_class_tbl_entry * entry = (struct rb_cvar_class_tbl_entry * )value ;
91- SIZED_FREE (entry );
92- return ID_TABLE_CONTINUE ;
93- }
94-
9587rb_classext_t *
9688rb_class_unlink_classext (VALUE klass , const rb_box_t * box )
9789{
@@ -114,11 +106,6 @@ rb_class_classext_free(VALUE klass, rb_classext_t *ext, bool is_prime)
114106 rb_free_const_table (tbl );
115107 }
116108
117- if ((tbl = RCLASSEXT_CVC_TBL (ext )) != NULL ) {
118- rb_id_table_foreach_values (tbl , cvar_table_free_i , NULL );
119- rb_id_table_free (tbl );
120- }
121-
122109 if (is_prime ) {
123110 rb_class_remove_from_super_subclasses (klass );
124111 rb_class_classext_free_subclasses (ext );
@@ -254,33 +241,6 @@ duplicate_classext_m_tbl(struct rb_id_table *orig, VALUE klass, bool init_missin
254241 return tbl ;
255242}
256243
257- static enum rb_id_table_iterator_result
258- duplicate_classext_cvc_tbl_i (ID key , VALUE value , void * data )
259- {
260- struct rb_id_table * tbl = (struct rb_id_table * )data ;
261- struct rb_cvar_class_tbl_entry * cvc_entry = (struct rb_cvar_class_tbl_entry * )value ;
262- struct rb_cvar_class_tbl_entry * copy = ALLOC (struct rb_cvar_class_tbl_entry );
263- MEMCPY (copy , cvc_entry , struct rb_cvar_class_tbl_entry , 1 );
264- rb_id_table_insert (tbl , key , (VALUE )copy );
265- return ID_TABLE_CONTINUE ;
266- }
267-
268- static struct rb_id_table *
269- duplicate_classext_cvc_tbl (struct rb_id_table * orig , bool init_missing )
270- {
271- struct rb_id_table * tbl ;
272-
273- if (!orig ) {
274- if (init_missing )
275- return rb_id_table_create (0 );
276- else
277- return NULL ;
278- }
279- tbl = rb_id_table_create (rb_id_table_size (orig ));
280- rb_id_table_foreach (orig , duplicate_classext_cvc_tbl_i , tbl );
281- return tbl ;
282- }
283-
284244static rb_const_entry_t *
285245duplicate_classext_const_entry (rb_const_entry_t * src , VALUE klass )
286246{
@@ -414,7 +374,14 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_box_t *bo
414374 * RCLASSEXT_CC_TBL(copy) = NULL
415375 */
416376
417- RCLASSEXT_CVC_TBL (ext ) = duplicate_classext_cvc_tbl (RCLASSEXT_CVC_TBL (orig ), dup_iclass );
377+ VALUE cvc_table = RCLASSEXT_CVC_TBL (orig );
378+ if (cvc_table ) {
379+ cvc_table = rb_marked_id_table_dup (cvc_table );
380+ }
381+ else if (dup_iclass ) {
382+ cvc_table = rb_marked_id_table_new (2 );
383+ }
384+ RB_OBJ_WRITE (klass , & RCLASSEXT_CVC_TBL (ext ), cvc_table );
418385
419386 // Subclasses/back-pointers are only in the prime classext.
420387
@@ -981,9 +948,15 @@ class_init_copy_check(VALUE clone, VALUE orig)
981948
982949struct cvc_table_copy_ctx {
983950 VALUE clone ;
984- struct rb_id_table * new_table ;
951+ VALUE new_table ;
985952};
986953
954+ static struct rb_cvar_class_tbl_entry *
955+ cvc_table_entry_alloc (void )
956+ {
957+ return (struct rb_cvar_class_tbl_entry * )SHAREABLE_IMEMO_NEW (struct rb_cvar_class_tbl_entry , imemo_cvar_entry , 0 );
958+ }
959+
987960static enum rb_id_table_iterator_result
988961cvc_table_copy (ID id , VALUE val , void * data )
989962{
@@ -993,13 +966,11 @@ cvc_table_copy(ID id, VALUE val, void *data)
993966
994967 struct rb_cvar_class_tbl_entry * ent ;
995968
996- ent = ALLOC ( struct rb_cvar_class_tbl_entry );
997- ent -> class_value = ctx -> clone ;
998- ent -> cref = orig_entry -> cref ;
969+ ent = cvc_table_entry_alloc ( );
970+ RB_OBJ_WRITE (( VALUE ) ent , & ent -> class_value , ctx -> clone ) ;
971+ RB_OBJ_WRITE ( ctx -> clone , & ent -> cref , orig_entry -> cref ) ;
999972 ent -> global_cvar_state = orig_entry -> global_cvar_state ;
1000- rb_id_table_insert (ctx -> new_table , id , (VALUE )ent );
1001-
1002- RB_OBJ_WRITTEN (ctx -> clone , Qundef , ent -> cref );
973+ rb_marked_id_table_insert (ctx -> new_table , id , (VALUE )ent );
1003974
1004975 return ID_TABLE_CONTINUE ;
1005976}
@@ -1012,13 +983,13 @@ copy_tables(VALUE clone, VALUE orig)
1012983 RCLASS_WRITE_CONST_TBL (clone , 0 , false);
1013984 }
1014985 if (RCLASS_CVC_TBL (orig )) {
1015- struct rb_id_table * rb_cvc_tbl = RCLASS_CVC_TBL (orig );
1016- struct rb_id_table * rb_cvc_tbl_dup = rb_id_table_create ( rb_id_table_size (rb_cvc_tbl ));
986+ VALUE rb_cvc_tbl = RCLASS_CVC_TBL (orig );
987+ VALUE rb_cvc_tbl_dup = rb_marked_id_table_new ( rb_marked_id_table_size (rb_cvc_tbl ));
1017988
1018989 struct cvc_table_copy_ctx ctx ;
1019990 ctx .clone = clone ;
1020991 ctx .new_table = rb_cvc_tbl_dup ;
1021- rb_id_table_foreach (rb_cvc_tbl , cvc_table_copy , & ctx );
992+ rb_marked_id_table_foreach (rb_cvc_tbl , cvc_table_copy , & ctx );
1022993 RCLASS_WRITE_CVC_TBL (clone , rb_cvc_tbl_dup );
1023994 }
1024995 rb_id_table_free (RCLASS_M_TBL (clone ));
0 commit comments