@@ -422,18 +422,141 @@ mark::do_mark(rust_task *task, const std::vector<void *> &roots,
422
422
}
423
423
}
424
424
425
+ class sweep : public shape ::data<sweep,shape::ptr> {
426
+ friend class shape ::data<sweep,shape::ptr>;
427
+
428
+ sweep (const sweep &other, const shape::ptr &in_dp)
429
+ : shape::data<sweep,shape::ptr>(other.task, other.align,
430
+ other.sp, other.params,
431
+ other.tables, in_dp) {}
432
+
433
+ sweep (const sweep &other,
434
+ const uint8_t *in_sp,
435
+ const shape::type_param *in_params,
436
+ const rust_shape_tables *in_tables = NULL )
437
+ : shape::data<sweep,shape::ptr>(other.task,
438
+ other.align,
439
+ in_sp,
440
+ in_params,
441
+ in_tables ? in_tables : other.tables,
442
+ other.dp) {}
443
+
444
+ sweep (const sweep &other,
445
+ const uint8_t *in_sp,
446
+ const shape::type_param *in_params,
447
+ const rust_shape_tables *in_tables,
448
+ shape::ptr in_dp)
449
+ : shape::data<sweep,shape::ptr>(other.task,
450
+ other.align,
451
+ in_sp,
452
+ in_params,
453
+ in_tables,
454
+ in_dp) {}
455
+
456
+ sweep (rust_task *in_task,
457
+ bool in_align,
458
+ const uint8_t *in_sp,
459
+ const shape::type_param *in_params,
460
+ const rust_shape_tables *in_tables,
461
+ uint8_t *in_data)
462
+ : shape::data<sweep,shape::ptr>(in_task, in_align, in_sp,
463
+ in_params, in_tables, in_data) {}
464
+
465
+ void walk_vec (bool is_pod, uint16_t sp_size) {
466
+ void *vec = shape::get_dp<void *>(dp);
467
+ walk_vec (is_pod, get_vec_data_range (dp));
468
+ task->kernel ->free (vec);
469
+ }
470
+
471
+ void walk_vec (bool is_pod,
472
+ const std::pair<shape::ptr,shape::ptr> &data_range) {
473
+ sweep sub (*this , data_range.first );
474
+ shape::ptr data_end = sub.end_dp = data_range.second ;
475
+ while (sub.dp < data_end) {
476
+ sub.walk_reset ();
477
+ sub.align = true ;
478
+ }
479
+ }
480
+
481
+ void walk_tag (shape::tag_info &tinfo, uint32_t tag_variant) {
482
+ shape::data<sweep,shape::ptr>::walk_variant (tinfo, tag_variant);
483
+ }
484
+
485
+ void walk_box () {
486
+ shape::data<sweep,shape::ptr>::walk_box_contents ();
487
+ }
488
+
489
+ void walk_fn () {
490
+ return ;
491
+ }
492
+
493
+ void walk_obj () {
494
+ shape::data<sweep,shape::ptr>::walk_obj_contents (dp);
495
+ }
496
+
497
+ void walk_res (const shape::rust_fn *dtor, unsigned n_params,
498
+ const shape::type_param *params, const uint8_t *end_sp,
499
+ bool live) {
500
+ while (this ->sp != end_sp) {
501
+ this ->walk ();
502
+ align = true ;
503
+ }
504
+ }
505
+
506
+ void walk_subcontext (sweep &sub) { sub.walk (); }
507
+
508
+ void walk_box_contents (sweep &sub, shape::ptr &ref_count_dp) {
509
+ return ;
510
+ }
511
+
512
+ void walk_struct (const uint8_t *end_sp) {
513
+ while (this ->sp != end_sp) {
514
+ this ->walk ();
515
+ align = true ;
516
+ }
517
+ }
518
+
519
+ void walk_variant (shape::tag_info &tinfo, uint32_t variant_id,
520
+ const std::pair<const uint8_t *,const uint8_t *>
521
+ variant_ptr_and_end) {
522
+ sweep sub (*this , variant_ptr_and_end.first , tinfo.params );
523
+
524
+ const uint8_t *variant_end = variant_ptr_and_end.second ;
525
+ while (sub.sp < variant_end) {
526
+ sub.walk ();
527
+ align = true ;
528
+ }
529
+ }
530
+
531
+ template <typename T>
532
+ inline void walk_number () { /* no-op */ }
533
+
534
+ public:
535
+ static void do_sweep (rust_task *task, const std::set<void *> &marked);
536
+ };
425
537
426
538
void
427
- sweep (rust_task *task, const std::set<void *> &marked) {
539
+ sweep::do_sweep (rust_task *task, const std::set<void *> &marked) {
428
540
std::map<void *,const type_desc *>::iterator
429
541
begin (task->local_allocs .begin ()), end (task->local_allocs .end ());
430
542
while (begin != end) {
431
543
void *alloc = begin->first ;
544
+
432
545
if (marked.find (alloc) == marked.end ()) {
433
546
LOG (task, gc, " object is part of a cycle: %p" , alloc);
434
547
435
- // FIXME: Run the destructor, *if* it's a resource.
548
+ const type_desc *tydesc = begin->second ;
549
+ uint8_t *p = reinterpret_cast <uint8_t *>(alloc);
550
+ shape::arena arena;
551
+ shape::type_param *params =
552
+ shape::type_param::from_tydesc_and_data (tydesc, p, arena);
553
+
554
+ sweep sweep (task, true , tydesc->shape ,
555
+ params, tydesc->shape_tables ,
556
+ p + sizeof (uintptr_t ));
557
+ sweep.walk ();
436
558
559
+ // FIXME: Run the destructor, *if* it's a resource.
437
560
task->free (alloc);
438
561
}
439
562
++begin;
@@ -455,7 +578,7 @@ do_cc(rust_task *task) {
455
578
std::set<void *> marked;
456
579
mark::do_mark (task, roots, marked);
457
580
458
- sweep (task, marked);
581
+ sweep::do_sweep (task, marked);
459
582
}
460
583
461
584
void
0 commit comments