Skip to content

Commit 9057474

Browse files
authored
flambda-backend: Root scanning fixes for Flambda 2 (#87)
1 parent 08e02a3 commit 9057474

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

runtime/roots_nat.c

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,32 @@ void caml_register_dyn_global(void *v) {
238238
caml_dyn_globals = cons((void*) v,caml_dyn_globals);
239239
}
240240

241+
/* Logic to determine at which index within a global root to start
242+
scanning. [*glob_block] and [*start] may be updated by this function. */
243+
static void compute_index_for_global_root_scan (value* glob_block, int* start)
244+
{
245+
*start = 0;
246+
247+
CAMLassert (Is_block (*glob_block));
248+
249+
if (Tag_val (*glob_block) < No_scan_tag) {
250+
/* Note: if a [Closure_tag] block is registered as a global root
251+
(possibly containing one or more [Infix_tag] blocks), then only one
252+
out of the combined set of the [Closure_tag] and [Infix_tag] blocks
253+
may be registered as a global root. Multiple registrations can cause
254+
the compactor to traverse the same fields of a block twice, which can
255+
cause a failure. */
256+
if (Tag_val (*glob_block) == Infix_tag)
257+
*glob_block -= Infix_offset_val (*glob_block);
258+
if (Tag_val (*glob_block) == Closure_tag)
259+
*start = Start_env_closinfo (Closinfo_val (*glob_block));
260+
}
261+
else {
262+
/* Set the index such that none of the block's fields will be scanned. */
263+
*start = Wosize_val (*glob_block);
264+
}
265+
}
266+
241267
/* Call [caml_oldify_one] on (at least) all the roots that point to the minor
242268
heap. */
243269
void caml_oldify_local_roots (void)
@@ -252,6 +278,8 @@ void caml_oldify_local_roots (void)
252278
unsigned short * p;
253279
value * glob;
254280
value * root;
281+
value glob_block;
282+
int start;
255283
struct caml__roots_block *lr;
256284
link *lnk;
257285

@@ -260,18 +288,21 @@ void caml_oldify_local_roots (void)
260288
i <= caml_globals_inited && caml_globals[i] != 0;
261289
i++) {
262290
for(glob = caml_globals[i]; *glob != 0; glob++) {
263-
for (j = 0; j < Wosize_val(*glob); j++){
264-
Oldify (&Field (*glob, j));
265-
}
291+
glob_block = *glob;
292+
compute_index_for_global_root_scan (&glob_block, &start);
293+
for (j = start; j < Wosize_val (glob_block); j++)
294+
Oldify (&Field (glob_block, j));
266295
}
267296
}
268297
caml_globals_scanned = caml_globals_inited;
269298

270299
/* Dynamic global roots */
271300
iter_list(caml_dyn_globals, lnk) {
272301
for(glob = (value *) lnk->data; *glob != 0; glob++) {
273-
for (j = 0; j < Wosize_val(*glob); j++){
274-
Oldify (&Field (*glob, j));
302+
glob_block = *glob;
303+
compute_index_for_global_root_scan (&glob_block, &start);
304+
for (j = start; j < Wosize_val (glob_block); j++) {
305+
Oldify (&Field (glob_block, j));
275306
}
276307
}
277308
}
@@ -360,6 +391,8 @@ intnat caml_darken_all_roots_slice (intnat work)
360391
static int i, j;
361392
static value *glob;
362393
static int do_resume = 0;
394+
static value glob_block;
395+
static int start;
363396
static mlsize_t roots_count = 0;
364397
intnat remaining_work = work;
365398
CAML_EV_BEGIN(EV_MAJOR_MARK_GLOBAL_ROOTS_SLICE);
@@ -371,8 +404,10 @@ intnat caml_darken_all_roots_slice (intnat work)
371404
suspend itself when [work] reaches 0. */
372405
for (i = 0; caml_globals[i] != 0; i++) {
373406
for(glob = caml_globals[i]; *glob != 0; glob++) {
374-
for (j = 0; j < Wosize_val(*glob); j++){
375-
caml_darken (Field (*glob, j), &Field (*glob, j));
407+
glob_block = *glob;
408+
compute_index_for_global_root_scan (&glob_block, &start);
409+
for (j = start; j < Wosize_val (glob_block); j++) {
410+
caml_darken (Field (glob_block, j), &Field (glob_block, j));
376411
-- remaining_work;
377412
if (remaining_work == 0){
378413
roots_count += work;
@@ -401,22 +436,28 @@ void caml_do_roots (scanning_action f, int do_globals)
401436
int i, j;
402437
value * glob;
403438
link *lnk;
439+
value glob_block;
440+
int start;
404441

405442
CAML_EV_BEGIN(EV_MAJOR_ROOTS_DYNAMIC_GLOBAL);
406443
if (do_globals){
407444
/* The global roots */
408445
for (i = 0; caml_globals[i] != 0; i++) {
409446
for(glob = caml_globals[i]; *glob != 0; glob++) {
410-
for (j = 0; j < Wosize_val(*glob); j++)
411-
f (Field (*glob, j), &Field (*glob, j));
447+
glob_block = *glob;
448+
compute_index_for_global_root_scan (&glob_block, &start);
449+
for (j = start; j < Wosize_val (glob_block); j++)
450+
f (Field (glob_block, j), &Field (glob_block, j));
412451
}
413452
}
414453
}
415454
/* Dynamic global roots */
416455
iter_list(caml_dyn_globals, lnk) {
417456
for(glob = (value *) lnk->data; *glob != 0; glob++) {
418-
for (j = 0; j < Wosize_val(*glob); j++){
419-
f (Field (*glob, j), &Field (*glob, j));
457+
glob_block = *glob;
458+
compute_index_for_global_root_scan (&glob_block, &start);
459+
for (j = start; j < Wosize_val (glob_block); j++) {
460+
f (Field (glob_block, j), &Field (glob_block, j));
420461
}
421462
}
422463
}

0 commit comments

Comments
 (0)