Skip to content

Commit 13a06cb

Browse files
wip - sync the finalizer table and the flag with a mutex
1 parent 04795c5 commit 13a06cb

2 files changed

Lines changed: 61 additions & 8 deletions

File tree

gc/default/default.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1607,7 +1607,7 @@ enum object_hash_state {
16071607
static enum object_hash_state
16081608
object_hash_state(VALUE obj)
16091609
{
1610-
short hash_state = (RBASIC(obj)->flags & (RUBY_FL_OBJ_HASH_SEEN | RUBY_FL_OBJ_MOVED)) >> RUBY_FL_OBJ_HASH_SHIFT;
1610+
short hash_state = (RBASIC(obj)->flags & (RUBY_FL_OBJ_HASH_SEEN | RUBY_FL_OBJ_MOVED)) >> RUBY_FL_OBJ_HASH_SHIFT;
16111611

16121612
int seen = (RBASIC(obj)->flags & RUBY_FL_OBJ_HASH_SEEN) != 0;
16131613
int moved = (RBASIC(obj)->flags & RUBY_FL_OBJ_MOVED) != 0;

gc/mmtk/mmtk.c

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -281,19 +281,30 @@ rb_mmtk_vm_live_bytes(void)
281281

282282
static void set_object_has_finalizer(VALUE obj, bool has_finalizer);
283283
bool rb_gc_impl_has_finalizer(VALUE obj);
284+
bool rb_gc_impl_object_id_seen_p(VALUE obj);
285+
284286
static void
285287
make_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

11111136
void
11121137
rb_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

11211155
bool
@@ -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

Comments
 (0)