@@ -93,7 +93,11 @@ class irc : public shape::data<irc,shape::ptr> {
93
93
}
94
94
95
95
void walk_box2 () {
96
- shape::data<irc,shape::ptr>::walk_box_contents1 ();
96
+ // the box ptr can be NULL for env ptrs in closures and data
97
+ // not fully initialized
98
+ rust_opaque_box *box = *(rust_opaque_box**)dp;
99
+ if (box)
100
+ shape::data<irc,shape::ptr>::walk_box_contents1 ();
97
101
}
98
102
99
103
void walk_uniq2 () {
@@ -103,8 +107,6 @@ class irc : public shape::data<irc,shape::ptr> {
103
107
void walk_fn2 (char code) {
104
108
switch (code) {
105
109
case shape::SHAPE_BOX_FN: {
106
- // Record an irc for the environment box, but don't descend
107
- // into it since it will be walked via the box's allocation
108
110
shape::bump_dp<void *>(dp); // skip over the code ptr
109
111
walk_box2 (); // walk over the environment ptr
110
112
break ;
@@ -137,19 +139,19 @@ class irc : public shape::data<irc,shape::ptr> {
137
139
138
140
void walk_uniq_contents2 (irc &sub) { sub.walk (); }
139
141
140
- void walk_box_contents2 (irc &sub, shape::ptr &box_dp ) {
141
- maybe_record_irc (box_dp );
142
+ void walk_box_contents2 (irc &sub) {
143
+ maybe_record_irc ();
142
144
143
145
// Do not traverse the contents of this box; it's in the allocation
144
146
// somewhere, so we're guaranteed to come back to it (if we haven't
145
147
// traversed it already).
146
148
}
147
149
148
- void maybe_record_irc (shape::ptr &box_dp) {
149
- if (!box_dp)
150
- return ;
150
+ void maybe_record_irc () {
151
+ rust_opaque_box *box_ptr = *(rust_opaque_box **) dp;
151
152
152
- rust_opaque_box *box_ptr = (rust_opaque_box *) box_dp;
153
+ if (!box_ptr)
154
+ return ;
153
155
154
156
// Bump the internal reference count of the box.
155
157
if (ircs.find (box_ptr) == ircs.end ()) {
@@ -326,7 +328,11 @@ class mark : public shape::data<mark,shape::ptr> {
326
328
}
327
329
328
330
void walk_box2 () {
329
- shape::data<mark,shape::ptr>::walk_box_contents1 ();
331
+ // the box ptr can be NULL for env ptrs in closures and data
332
+ // not fully initialized
333
+ rust_opaque_box *box = *(rust_opaque_box**)dp;
334
+ if (box)
335
+ shape::data<mark,shape::ptr>::walk_box_contents1 ();
330
336
}
331
337
332
338
void walk_uniq2 () {
@@ -336,8 +342,6 @@ class mark : public shape::data<mark,shape::ptr> {
336
342
void walk_fn2 (char code) {
337
343
switch (code) {
338
344
case shape::SHAPE_BOX_FN: {
339
- // Record an irc for the environment box, but don't descend
340
- // into it since it will be walked via the box's allocation
341
345
shape::data<mark,shape::ptr>::walk_fn_contents1 ();
342
346
break ;
343
347
}
@@ -369,11 +373,11 @@ class mark : public shape::data<mark,shape::ptr> {
369
373
370
374
void walk_uniq_contents2 (mark &sub) { sub.walk (); }
371
375
372
- void walk_box_contents2 (mark &sub, shape::ptr &box_dp) {
373
- if (!box_dp)
374
- return ;
376
+ void walk_box_contents2 (mark &sub) {
377
+ rust_opaque_box *box_ptr = *(rust_opaque_box **) dp;
375
378
376
- rust_opaque_box *box_ptr = (rust_opaque_box *) box_dp;
379
+ if (!box_ptr)
380
+ return ;
377
381
378
382
if (marked.find (box_ptr) != marked.end ())
379
383
return ; // Skip to avoid chasing cycles.
@@ -516,22 +520,26 @@ class sweep : public shape::data<sweep,shape::ptr> {
516
520
}
517
521
518
522
void walk_box2 () {
519
- shape::data<sweep,shape::ptr>::walk_box_contents1 ();
523
+ // In sweep phase, do not walk the box contents. There is an
524
+ // outer loop walking all remaining boxes, and this box may well
525
+ // have been freed already!
520
526
}
521
527
522
528
void walk_fn2 (char code) {
523
529
switch (code) {
524
530
case shape::SHAPE_UNIQ_FN: {
525
531
fn_env_pair pair = *(fn_env_pair*)dp;
526
532
527
- // free closed over data:
528
- shape::data<sweep,shape::ptr>::walk_fn_contents1 ();
529
-
530
- // now free the embedded type descr:
531
- upcall_s_free_shared_type_desc ((type_desc*)pair.env ->td );
532
-
533
- // now free the ptr:
534
- task->kernel ->free (pair.env );
533
+ if (pair.env ) {
534
+ // free closed over data:
535
+ shape::data<sweep,shape::ptr>::walk_fn_contents1 ();
536
+
537
+ // now free the embedded type descr:
538
+ upcall_s_free_shared_type_desc ((type_desc*)pair.env ->td );
539
+
540
+ // now free the ptr:
541
+ task->kernel ->free (pair.env );
542
+ }
535
543
break ;
536
544
}
537
545
case shape::SHAPE_BOX_FN: {
@@ -579,10 +587,6 @@ class sweep : public shape::data<sweep,shape::ptr> {
579
587
580
588
void walk_uniq_contents2 (sweep &sub) { sub.walk (); }
581
589
582
- void walk_box_contents2 (sweep &sub, shape::ptr &box_dp) {
583
- return ;
584
- }
585
-
586
590
void walk_struct2 (const uint8_t *end_sp) {
587
591
while (this ->sp != end_sp) {
588
592
this ->walk ();
0 commit comments