@@ -238,6 +238,32 @@ void caml_register_dyn_global(void *v) {
238
238
caml_dyn_globals = cons ((void * ) v ,caml_dyn_globals );
239
239
}
240
240
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
+
241
267
/* Call [caml_oldify_one] on (at least) all the roots that point to the minor
242
268
heap. */
243
269
void caml_oldify_local_roots (void )
@@ -252,6 +278,8 @@ void caml_oldify_local_roots (void)
252
278
unsigned short * p ;
253
279
value * glob ;
254
280
value * root ;
281
+ value glob_block ;
282
+ int start ;
255
283
struct caml__roots_block * lr ;
256
284
link * lnk ;
257
285
@@ -260,18 +288,21 @@ void caml_oldify_local_roots (void)
260
288
i <= caml_globals_inited && caml_globals [i ] != 0 ;
261
289
i ++ ) {
262
290
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 ));
266
295
}
267
296
}
268
297
caml_globals_scanned = caml_globals_inited ;
269
298
270
299
/* Dynamic global roots */
271
300
iter_list (caml_dyn_globals , lnk ) {
272
301
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 ));
275
306
}
276
307
}
277
308
}
@@ -360,6 +391,8 @@ intnat caml_darken_all_roots_slice (intnat work)
360
391
static int i , j ;
361
392
static value * glob ;
362
393
static int do_resume = 0 ;
394
+ static value glob_block ;
395
+ static int start ;
363
396
static mlsize_t roots_count = 0 ;
364
397
intnat remaining_work = work ;
365
398
CAML_EV_BEGIN (EV_MAJOR_MARK_GLOBAL_ROOTS_SLICE );
@@ -371,8 +404,10 @@ intnat caml_darken_all_roots_slice (intnat work)
371
404
suspend itself when [work] reaches 0. */
372
405
for (i = 0 ; caml_globals [i ] != 0 ; i ++ ) {
373
406
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 ));
376
411
-- remaining_work ;
377
412
if (remaining_work == 0 ){
378
413
roots_count += work ;
@@ -401,22 +436,28 @@ void caml_do_roots (scanning_action f, int do_globals)
401
436
int i , j ;
402
437
value * glob ;
403
438
link * lnk ;
439
+ value glob_block ;
440
+ int start ;
404
441
405
442
CAML_EV_BEGIN (EV_MAJOR_ROOTS_DYNAMIC_GLOBAL );
406
443
if (do_globals ){
407
444
/* The global roots */
408
445
for (i = 0 ; caml_globals [i ] != 0 ; i ++ ) {
409
446
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 ));
412
451
}
413
452
}
414
453
}
415
454
/* Dynamic global roots */
416
455
iter_list (caml_dyn_globals , lnk ) {
417
456
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 ));
420
461
}
421
462
}
422
463
}
0 commit comments