... |
... |
@@ -5439,85 +5439,84 @@ push(struct weak_pointer* wp, struct weak_pointer **list) |
5439
|
5439
|
*list = wp;
|
5440
|
5440
|
}
|
5441
|
5441
|
|
|
5442
|
+/*
|
|
5443
|
+ * Phase 2: Find the weak pointers to static vectors that are in use
|
|
5444
|
+ * and not in use. The vectors that are in use are added to
|
|
5445
|
+ * inuse_list. Those that are not in use are added to freeable_list.
|
|
5446
|
+ * Only unique vectors are added to freeable list; a duplicate has its
|
|
5447
|
+ * weak pointer to it broken.
|
|
5448
|
+ */
|
5442
|
5449
|
static void
|
5443
|
|
-scan_static_vectors(struct weak_pointer *static_vector_list)
|
|
5450
|
+scan_static_vectors_2(struct weak_pointer *static_vector_list,
|
|
5451
|
+ struct weak_pointer **freeable_list,
|
|
5452
|
+ struct weak_pointer **inuse_list)
|
5444
|
5453
|
{
|
5445
|
|
- /* List of weak pointers to static vectors that can be freed. */
|
5446
|
|
- struct weak_pointer *freeable_list = NULL;
|
5447
|
|
-
|
5448
|
|
- /* List of weak pointers to static vectors that are in in use. */
|
5449
|
|
- struct weak_pointer *inuse_list = NULL;
|
5450
|
|
- struct weak_pointer *wp;
|
5451
|
|
-
|
5452
|
5454
|
DPRINTF(debug_static_array_p,
|
5453
|
5455
|
(stdout, "Phase 2: Find unused and unused static vectors\n"));
|
5454
|
5456
|
|
5455
|
|
- /*
|
5456
|
|
- * static_vector_list points to all weak pointers to static
|
5457
|
|
- * vectors. If the static vector is in use, add it to the in-use
|
5458
|
|
- * list. If the static vector is not in use, and has not been
|
5459
|
|
- * visited, mark it as visited and add it to the freeable list.
|
5460
|
|
- * If it has been visited, just break the weak pointer.
|
5461
|
|
- */
|
5462
|
5457
|
while (static_vector_list) {
|
5463
|
|
- struct weak_pointer *this_wp;
|
|
5458
|
+ struct weak_pointer *wp;
|
5464
|
5459
|
lispobj *header;
|
5465
|
5460
|
|
5466
|
5461
|
/* Pop weak pointer from the list */
|
5467
|
|
- this_wp = pop(&static_vector_list);
|
5468
|
|
- header = (lispobj *) PTR(this_wp->value);
|
|
5462
|
+ wp = pop(&static_vector_list);
|
|
5463
|
+ header = (lispobj *) PTR(wp->value);
|
5469
|
5464
|
|
5470
|
5465
|
DPRINTF(debug_static_array_p,
|
5471
|
5466
|
(stdout, " wp %p value %p header 0x%08lx\n",
|
5472
|
|
- this_wp, (lispobj *) this_wp->value, *header));
|
|
5467
|
+ wp, (lispobj *) wp->value, *header));
|
5473
|
5468
|
|
5474
|
|
- /*
|
5475
|
|
- * If the static vector is unused (mark bit clear) and if we
|
5476
|
|
- * haven't seen this vector before, set the visited flag. If
|
5477
|
|
- * we have visited this vector before, break the weak pointer.
|
5478
|
|
- */
|
5479
|
5469
|
if ((*header & STATIC_VECTOR_MARK_BIT) != 0) {
|
5480
|
5470
|
/*
|
5481
|
5471
|
* Static vector is in use. Add this to the in-use list.
|
5482
|
5472
|
*/
|
5483
|
|
- printf(" In-use vector; add to in-use list\n");
|
5484
|
|
- push(this_wp, &inuse_list);
|
|
5473
|
+ DPRINTF(debug_static_array_p,
|
|
5474
|
+ (stdout, " In-use vector; add to in-use list\n"));
|
|
5475
|
+
|
|
5476
|
+ push(wp, inuse_list);
|
5485
|
5477
|
} else {
|
5486
|
|
- /* Unused static vector */
|
|
5478
|
+ /*
|
|
5479
|
+ * Static vector not in use. If we haven't seen this
|
|
5480
|
+ * vector before, set the visited flag and add it to
|
|
5481
|
+ * freeable_list. If we have visited this vector before,
|
|
5482
|
+ * break the weak pointer.
|
|
5483
|
+ */
|
5487
|
5484
|
if ((*header & STATIC_VECTOR_VISITED_BIT) == 0) {
|
5488
|
5485
|
DPRINTF(debug_static_array_p,
|
5489
|
5486
|
(stdout, " Visit unused vector, add to freeable list\n"));
|
5490
|
5487
|
|
5491
|
5488
|
*header |= STATIC_VECTOR_VISITED_BIT;
|
5492
|
|
-
|
5493
|
|
- /*
|
5494
|
|
- * Add this to the freeable list because it's a static
|
5495
|
|
- * vector that we can free.
|
5496
|
|
- */
|
5497
|
|
- push(this_wp, &freeable_list);
|
|
5489
|
+ push(wp, freeable_list);
|
5498
|
5490
|
} else {
|
5499
|
5491
|
DPRINTF(debug_static_array_p,
|
5500
|
5492
|
(stdout, " Already visited unused vector; break weak pointer\n"));
|
5501
|
5493
|
|
5502
|
|
- this_wp->value = NIL;
|
5503
|
|
- this_wp->broken = T;
|
|
5494
|
+ wp->value = NIL;
|
|
5495
|
+ wp->broken = T;
|
5504
|
5496
|
}
|
5505
|
5497
|
}
|
5506
|
5498
|
}
|
|
5499
|
+}
|
|
5500
|
+
|
|
5501
|
+/*
|
|
5502
|
+ * Free all the unused static vectors in freeable_list.
|
|
5503
|
+ */
|
|
5504
|
+static void
|
|
5505
|
+scan_static_vectors_3(struct weak_pointer *freeable_list)
|
|
5506
|
+{
|
|
5507
|
+ struct weak_pointer *wp;
|
5507
|
5508
|
|
5508
|
5509
|
DPRINTF(debug_static_array_p,
|
5509
|
5510
|
(stdout, "Phase 3: Free static vectors\n"));
|
5510
|
5511
|
|
5511
|
|
- /*
|
5512
|
|
- * freeable_list now contains weak pointers to unique static
|
5513
|
|
- * vectors that are not in use. Break the weak pointer and free
|
5514
|
|
- * the static vector.
|
5515
|
|
- */
|
5516
|
5512
|
for (wp = freeable_list; wp; wp = wp->next) {
|
5517
|
|
- /* Invariant: weak pointer must not be broken */
|
5518
|
|
- gc_assert(wp->broken == NIL);
|
5519
|
|
-
|
5520
|
5513
|
lispobj *header = (lispobj *) PTR(wp->value);
|
|
5514
|
+ lispobj *static_array = (lispobj *) PTR(wp->value);
|
|
5515
|
+
|
|
5516
|
+ /*
|
|
5517
|
+ * Invariant: weak pointer must not be broken
|
|
5518
|
+ */
|
|
5519
|
+ gc_assert(wp->broken == NIL);
|
5521
|
5520
|
|
5522
|
5521
|
DPRINTF(debug_static_array_p,
|
5523
|
5522
|
(stdout, " wp %p value %p header 0x%08lx\n",
|
... |
... |
@@ -5527,8 +5526,7 @@ scan_static_vectors(struct weak_pointer *static_vector_list) |
5527
|
5526
|
* Invariant: Mark bit must be clear
|
5528
|
5527
|
*/
|
5529
|
5528
|
gc_assert(((*header & STATIC_VECTOR_MARK_BIT) == 0));
|
5530
|
|
-
|
5531
|
|
- lispobj *static_array = (lispobj *) PTR(wp->value);
|
|
5529
|
+
|
5532
|
5530
|
DPRINTF(debug_static_array_p,
|
5533
|
5531
|
(stdout, " Free static vector\n"));
|
5534
|
5532
|
|
... |
... |
@@ -5537,14 +5535,19 @@ scan_static_vectors(struct weak_pointer *static_vector_list) |
5537
|
5535
|
|
5538
|
5536
|
free(static_array);
|
5539
|
5537
|
}
|
|
5538
|
+}
|
|
5539
|
+
|
|
5540
|
+/*
|
|
5541
|
+ * Unmark all the vectors in inuse_list
|
|
5542
|
+ */
|
|
5543
|
+static void
|
|
5544
|
+scan_static_vectors_4(struct weak_pointer *inuse_list)
|
|
5545
|
+{
|
|
5546
|
+ struct weak_pointer *wp;
|
5540
|
5547
|
|
5541
|
5548
|
DPRINTF(debug_static_array_p,
|
5542
|
5549
|
(stdout, "Phase 4: unmark static vectors\n"));
|
5543
|
5550
|
|
5544
|
|
- /*
|
5545
|
|
- * At this point, inuse_list is a list of weak pointers to static
|
5546
|
|
- * vectors that are still in use. Clear the mark bit.
|
5547
|
|
- */
|
5548
|
5551
|
for (wp = inuse_list; wp; wp = wp->next) {
|
5549
|
5552
|
lispobj *header = (lispobj *) PTR(wp->value);
|
5550
|
5553
|
/*
|
... |
... |
@@ -5560,6 +5563,7 @@ scan_static_vectors(struct weak_pointer *static_vector_list) |
5560
|
5563
|
(stdout, " wp %p value %p broken %d header 0x%08lx\n",
|
5561
|
5564
|
wp, (lispobj*) wp->value, wp->broken == T, *header));
|
5562
|
5565
|
|
|
5566
|
+ /* Only clear if we haven't already */
|
5563
|
5567
|
if ((*header & STATIC_VECTOR_MARK_BIT) != 0) {
|
5564
|
5568
|
DPRINTF(debug_static_array_p,
|
5565
|
5569
|
(stdout, " Clearing mark bit\n"));
|
... |
... |
@@ -5569,6 +5573,28 @@ scan_static_vectors(struct weak_pointer *static_vector_list) |
5569
|
5573
|
}
|
5570
|
5574
|
}
|
5571
|
5575
|
|
|
5576
|
+static void
|
|
5577
|
+scan_static_vectors(struct weak_pointer *static_vector_list)
|
|
5578
|
+{
|
|
5579
|
+ /* List of weak pointers to static vectors that can be freed. */
|
|
5580
|
+ struct weak_pointer *freeable_list = NULL;
|
|
5581
|
+
|
|
5582
|
+ /* List of weak pointers to static vectors that are in in use. */
|
|
5583
|
+ struct weak_pointer *inuse_list = NULL;
|
|
5584
|
+
|
|
5585
|
+ /*
|
|
5586
|
+ * For each weak pointer, add it either the inuse list or the
|
|
5587
|
+ * freeable list.
|
|
5588
|
+ */
|
|
5589
|
+ scan_static_vectors_2(static_vector_list, &freeable_list, &inuse_list);
|
|
5590
|
+
|
|
5591
|
+ /* Free the unused unique static vectors. */
|
|
5592
|
+ scan_static_vectors_3(freeable_list);
|
|
5593
|
+
|
|
5594
|
+ /* Unmark all the static vectors that are still alive. */
|
|
5595
|
+ scan_static_vectors_4(inuse_list);
|
|
5596
|
+}
|
|
5597
|
+
|
5572
|
5598
|
void
|
5573
|
5599
|
scan_weak_pointers(void)
|
5574
|
5600
|
{
|