@@ -281,19 +281,30 @@ rb_mmtk_vm_live_bytes(void)
281281
282282static void set_object_has_finalizer (VALUE obj , bool has_finalizer );
283283bool rb_gc_impl_has_finalizer (VALUE obj );
284+ bool rb_gc_impl_object_id_seen_p (VALUE obj );
285+
284286static void
285287make_final_job (struct objspace * objspace , VALUE obj , VALUE table )
286288{
287289 RUBY_ASSERT (rb_gc_impl_has_finalizer (obj ));
288290 RUBY_ASSERT (mmtk_is_reachable ((MMTk_ObjectReference )table ));
289291 RUBY_ASSERT (RB_BUILTIN_TYPE (table ) == T_ARRAY );
290292
293+ VALUE object_id ;
294+ st_data_t val ;
295+ if (rb_gc_impl_object_id_seen_p (obj ) &&
296+ st_lookup (objspace -> obj_to_id_tbl , (st_data_t )obj , & val )) {
297+ object_id = (VALUE )val ;
298+ } else {
299+ object_id = rb_gc_impl_object_id (objspace , obj );
300+ }
301+
291302 set_object_has_finalizer (obj , false);
292303
293304 struct MMTk_final_job * job = xmalloc (sizeof (struct MMTk_final_job ));
294305 job -> next = objspace -> finalizer_jobs ;
295306 job -> kind = MMTK_FINAL_JOB_FINALIZE ;
296- job -> as .finalize .object_id = rb_obj_id (( VALUE ) obj ) ;
307+ job -> as .finalize .object_id = object_id ;
297308 job -> as .finalize .finalizer_array = table ;
298309
299310 objspace -> finalizer_jobs = job ;
@@ -371,6 +382,7 @@ set_object_has_finalizer(VALUE obj, bool has_finalizer)
371382 else {
372383 struct object_metadata * metadata = xmalloc (sizeof (struct object_metadata ));
373384 metadata -> has_finalizer = has_finalizer ? 1 : 0 ;
385+ metadata -> seen_obj_id = 0 ; // Initialize the other fields
374386 st_insert (object_metadata_table , key , (st_data_t )metadata );
375387 }
376388}
@@ -1073,8 +1085,12 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
10731085 struct objspace * objspace = objspace_ptr ;
10741086 VALUE table ;
10751087 st_data_t data ;
1088+ VALUE result ;
10761089
1077- set_object_has_finalizer (obj , true);
1090+ int err ;
1091+ if ((err = pthread_mutex_lock (& objspace -> mutex )) != 0 ) {
1092+ rb_bug ("ERROR: cannot lock objspace->mutex: %s" , strerror (err ));
1093+ }
10781094
10791095 int lev = rb_gc_vm_lock ();
10801096
@@ -1090,7 +1106,8 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
10901106 VALUE recv = RARRAY_AREF (table , i );
10911107 if (rb_equal (recv , block )) {
10921108 rb_gc_vm_unlock (lev );
1093- return recv ;
1109+ result = recv ;
1110+ goto done ;
10941111 }
10951112 }
10961113 }
@@ -1105,17 +1122,34 @@ rb_gc_impl_define_finalizer(void *objspace_ptr, VALUE obj, VALUE block)
11051122
11061123 rb_gc_vm_unlock (lev );
11071124
1108- return block ;
1125+ set_object_has_finalizer (obj , true);
1126+ result = block ;
1127+
1128+ done :
1129+ if ((err = pthread_mutex_unlock (& objspace -> mutex )) != 0 ) {
1130+ rb_bug ("ERROR: cannot release objspace->mutex: %s" , strerror (err ));
1131+ }
1132+
1133+ return result ;
11091134}
11101135
11111136void
11121137rb_gc_impl_undefine_finalizer (void * objspace_ptr , VALUE obj )
11131138{
11141139 struct objspace * objspace = objspace_ptr ;
1115-
11161140 st_data_t data = obj ;
1141+
1142+ int err ;
1143+ if ((err = pthread_mutex_lock (& objspace -> mutex )) != 0 ) {
1144+ rb_bug ("ERROR: cannot lock objspace->mutex: %s" , strerror (err ));
1145+ }
1146+
11171147 st_delete (objspace -> finalizer_table , & data , 0 );
11181148 set_object_has_finalizer (obj , false);
1149+
1150+ if ((err = pthread_mutex_unlock (& objspace -> mutex )) != 0 ) {
1151+ rb_bug ("ERROR: cannot release objspace->mutex: %s" , strerror (err ));
1152+ }
11191153}
11201154
11211155bool
@@ -1138,16 +1172,35 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj)
11381172 struct objspace * objspace = objspace_ptr ;
11391173 VALUE table ;
11401174 st_data_t data ;
1175+
1176+ int err ;
1177+ if ((err = pthread_mutex_lock (& objspace -> mutex )) != 0 ) {
1178+ rb_bug ("ERROR: cannot lock objspace->mutex: %s" , strerror (err ));
1179+ }
11411180
1142- if (!rb_gc_impl_has_finalizer (obj )) return ;
1181+ bool has_finalizer = rb_gc_impl_has_finalizer (obj );
1182+ if (!has_finalizer ) {
1183+ if ((err = pthread_mutex_unlock (& objspace -> mutex )) != 0 ) {
1184+ rb_bug ("ERROR: cannot release objspace->mutex: %s" , strerror (err ));
1185+ }
1186+ return ;
1187+ }
11431188
11441189 if (RB_LIKELY (st_lookup (objspace -> finalizer_table , obj , & data ))) {
11451190 table = (VALUE )data ;
11461191 st_insert (objspace -> finalizer_table , dest , table );
11471192 set_object_has_finalizer (dest , true);
11481193 }
11491194 else {
1150- rb_bug ("rb_gc_copy_finalizer: FL_FINALIZE set but not found in finalizer_table: %s" , rb_obj_info (obj ));
1195+ set_object_has_finalizer (obj , false);
1196+ if ((err = pthread_mutex_unlock (& objspace -> mutex )) != 0 ) {
1197+ rb_bug ("ERROR: cannot release objspace->mutex: %s" , strerror (err ));
1198+ }
1199+ return ;
1200+ }
1201+
1202+ if ((err = pthread_mutex_unlock (& objspace -> mutex )) != 0 ) {
1203+ rb_bug ("ERROR: cannot release objspace->mutex: %s" , strerror (err ));
11511204 }
11521205}
11531206
0 commit comments