... |
... |
@@ -5397,94 +5397,107 @@ size_weak_pointer(lispobj * where) |
5397
|
5397
|
}
|
5398
|
5398
|
|
5399
|
5399
|
|
5400
|
|
-#if 0
|
5401
|
5400
|
static void
|
5402
|
|
-update_static_vector_list(lispobj value, lispobj* vectors_to_free, int* num_static_vectors)
|
|
5401
|
+scan_static_vectors(void)
|
5403
|
5402
|
{
|
|
5403
|
+ struct weak_pointer *wp;
|
|
5404
|
+ struct weak_pointer *clearable_list = NULL;
|
|
5405
|
+
|
|
5406
|
+ printf("Phase 1: build clearable list\n");
|
|
5407
|
+
|
5404
|
5408
|
/*
|
5405
|
|
- * We have a static array with the mark cleared which means it's
|
5406
|
|
- * not used.
|
|
5409
|
+ * Find weak pointers to unmarked static arrays, using a linked
|
|
5410
|
+ * list. We reuse the next slot ofthe weak pointer to chain these
|
|
5411
|
+ * weak pointers together.
|
5407
|
5412
|
*
|
5408
|
|
- * Only add it if we don't already have it. We don't want
|
5409
|
|
- * duplicates because we'll end up trying to free things multiple
|
5410
|
|
- * times.
|
|
5413
|
+ * Invariant: clearable_list only has weak pointers to unmarked
|
|
5414
|
+ * static vectors.
|
5411
|
5415
|
*/
|
5412
|
|
- int m;
|
5413
|
|
- int found = 0;
|
5414
|
|
-
|
5415
|
|
- for (m = 0; m < *num_static_vectors; ++m) {
|
5416
|
|
- if (value == vectors_to_free[m]) {
|
5417
|
|
- printf("Found %p at %d\n", (lispobj *) value, m);
|
5418
|
|
- found = 1;
|
5419
|
|
- break;
|
|
5416
|
+ wp = weak_pointers;
|
|
5417
|
+ while (wp) {
|
|
5418
|
+ lispobj value = wp->value;
|
|
5419
|
+ struct weak_pointer *next = wp->next;
|
|
5420
|
+
|
|
5421
|
+ if (Pointerp(value)) {
|
|
5422
|
+ /* The value may be a static vector */
|
|
5423
|
+ lispobj *header = (lispobj *) PTR(value);
|
|
5424
|
+
|
|
5425
|
+ if (maybe_static_array_p(*header)
|
|
5426
|
+ && (HeaderValue(*header) == 1)) {
|
|
5427
|
+ printf("Adding %p header = 0x%08lx, next = %p\n",
|
|
5428
|
+ wp, *header, wp->next);
|
|
5429
|
+ wp->next = clearable_list;
|
|
5430
|
+ clearable_list = wp;
|
|
5431
|
+ } else {
|
|
5432
|
+ printf("Skipping %p header = 0x%08lx\n", wp, *header);
|
|
5433
|
+ }
|
5420
|
5434
|
}
|
|
5435
|
+ wp = next;
|
5421
|
5436
|
}
|
5422
|
|
- if (!found) {
|
5423
|
|
- printf("Adding %p at %d\n", (lispobj *) value, *num_static_vectors);
|
5424
|
|
- vectors_to_free[*num_static_vectors] = value;
|
5425
|
|
- ++*num_static_vectors;
|
5426
|
|
- }
|
5427
|
|
-}
|
5428
|
|
-#endif
|
5429
|
|
-
|
5430
|
|
-void
|
5431
|
|
-scan_weak_pointers(void)
|
5432
|
|
-{
|
5433
|
|
- struct weak_pointer *wp;
|
5434
|
5437
|
|
|
5438
|
+ printf("Phase 2\n");
|
|
5439
|
+
|
5435
|
5440
|
/*
|
5436
|
|
- * Array of weak pointers to unmarked static vectors that can be
|
5437
|
|
- * freed.
|
|
5441
|
+ * clearable_list now points to all weak pointers to unmarked
|
|
5442
|
+ * static vectors. Go through the list. If it's not marked, mark
|
|
5443
|
+ * it. If it's marked, break the weak pointer.
|
|
5444
|
+ *
|
|
5445
|
+ * Invariant: clearable_list contains only weak pointers that have
|
|
5446
|
+ * been broken or that point to a unique dead static vector.
|
5438
|
5447
|
*/
|
5439
|
|
- struct weak_pointer **clearable_list;
|
|
5448
|
+ for (wp = clearable_list; wp; wp = wp->next) {
|
|
5449
|
+ lispobj *header = (lispobj *) PTR(wp->value);
|
5440
|
5450
|
|
5441
|
|
- /* Total number of weak pointers */
|
5442
|
|
- int num_weak_pointers = 0;
|
|
5451
|
+ printf("wp %p value 0x%08lx header 0x%08lx\n",
|
|
5452
|
+ wp, wp->value, *header);
|
|
5453
|
+ if (HeaderValue(*header) == 1) {
|
|
5454
|
+ printf(" Mark vector\n");
|
|
5455
|
+ *header |= 0x80000000;
|
|
5456
|
+ } else {
|
|
5457
|
+ printf(" Break weak pointer %p\n", wp);
|
|
5458
|
+ wp->value = NIL;
|
|
5459
|
+ wp->broken = T;
|
|
5460
|
+ }
|
|
5461
|
+ }
|
|
5462
|
+
|
|
5463
|
+ printf("Phase 3: Free static vectors\n");
|
5443
|
5464
|
|
5444
|
|
- /* Number of static vectors that we can free */
|
5445
|
|
- int num_static_vectors = 0;
|
5446
|
|
- int n;
|
5447
|
|
-
|
5448
|
5465
|
/*
|
5449
|
|
- * Count the number of weak pointers so we can allocate enough
|
5450
|
|
- * space for clearable_list.
|
|
5466
|
+ * Free up space. Go through clearable_list and for each weak
|
|
5467
|
+ * pointer that has not been broken, we can free the space. Then
|
|
5468
|
+ * break the weak pointer too, since the space has been freed.
|
5451
|
5469
|
*/
|
|
5470
|
+ for (wp = clearable_list; wp; wp = wp->next) {
|
|
5471
|
+ if (wp->broken == NIL) {
|
|
5472
|
+ lispobj *static_array = (lispobj *) PTR(wp->value);
|
|
5473
|
+ printf("free wp %p: %p\n", wp, static_array);
|
5452
|
5474
|
|
5453
|
|
- if (debug_static_array_p) {
|
5454
|
|
- printf("Phase 0\n");
|
5455
|
|
- }
|
5456
|
|
-
|
5457
|
|
- for (wp = weak_pointers; wp; wp = wp->next) {
|
5458
|
|
- num_weak_pointers++;
|
5459
|
|
- }
|
|
5475
|
+ wp->value = NIL;
|
|
5476
|
+ wp->broken = T;
|
5460
|
5477
|
|
5461
|
|
- if (debug_static_array_p) {
|
5462
|
|
- printf("weak pointer count = %d\n", num_weak_pointers);
|
|
5478
|
+ free(static_array);
|
|
5479
|
+ }
|
5463
|
5480
|
}
|
|
5481
|
+}
|
5464
|
5482
|
|
5465
|
|
- /* Nothing to do if there are no weak pointers */
|
5466
|
|
- if (num_weak_pointers == 0) {
|
5467
|
|
- return;
|
5468
|
|
- }
|
5469
|
|
-
|
5470
|
|
- /*
|
5471
|
|
- * Allocate enough space to hold all weak pointers in case they
|
5472
|
|
- * all point to static vectors.
|
5473
|
|
- */
|
5474
|
|
- clearable_list = (struct weak_pointer **) malloc(num_weak_pointers * sizeof(struct weak_pointer *));
|
5475
|
|
- gc_assert(clearable_list);
|
|
5483
|
+void
|
|
5484
|
+scan_weak_pointers(void)
|
|
5485
|
+{
|
|
5486
|
+ struct weak_pointer *wp;
|
5476
|
5487
|
|
5477
|
5488
|
/*
|
5478
|
5489
|
* Now process the weak pointers.
|
5479
|
5490
|
*/
|
5480
|
|
- if (debug_static_array_p) {
|
5481
|
|
- printf("Phase 1\n");
|
5482
|
|
- }
|
5483
|
5491
|
|
|
5492
|
+ printf("scan_weak_pointers...\n");
|
|
5493
|
+
|
5484
|
5494
|
for (wp = weak_pointers; wp; wp = wp->next) {
|
5485
|
5495
|
lispobj value = wp->value;
|
5486
|
5496
|
lispobj *first_pointer = (lispobj *) PTR(value);
|
5487
|
5497
|
|
|
5498
|
+ printf("scan_weak: wp = %p value %p header 0x%08lx\n",
|
|
5499
|
+ wp, (lispobj*) value, *first_pointer);
|
|
5500
|
+
|
5488
|
5501
|
wp->mark_bit = NIL;
|
5489
|
5502
|
if (Pointerp(value)) {
|
5490
|
5503
|
if (from_space_p(value)) {
|
... |
... |
@@ -5494,111 +5507,12 @@ scan_weak_pointers(void) |
5494
|
5507
|
wp->value = NIL;
|
5495
|
5508
|
wp->broken = T;
|
5496
|
5509
|
}
|
5497
|
|
- } else {
|
5498
|
|
- /* The value may be a static vector */
|
5499
|
|
- lispobj *header = (lispobj *) PTR(value);
|
5500
|
|
-
|
5501
|
|
- if (debug_static_array_p) {
|
5502
|
|
- printf("wp %p: value %p, header = 0x%08lx\n",
|
5503
|
|
- wp, (lispobj*) value, *header);
|
5504
|
|
- }
|
5505
|
|
-
|
5506
|
|
- if (maybe_static_array_p(*header)) {
|
5507
|
|
- /*
|
5508
|
|
- * A header value of 1 means we have a static
|
5509
|
|
- * vector with the in-use bit cleared, so we can
|
5510
|
|
- * add this weak pointer to the clearable list.
|
5511
|
|
- */
|
5512
|
|
- if (HeaderValue(*header) == 1) {
|
5513
|
|
- if (debug_static_array_p) {
|
5514
|
|
- printf(" clearable_list[%d] = %p\n", num_static_vectors, wp);
|
5515
|
|
- }
|
5516
|
|
-
|
5517
|
|
- clearable_list[num_static_vectors] = wp;
|
5518
|
|
- ++num_static_vectors;
|
5519
|
|
- }
|
5520
|
|
- }
|
5521
|
|
- }
|
5522
|
|
- }
|
5523
|
|
- }
|
5524
|
|
-
|
5525
|
|
- /*
|
5526
|
|
- * At this point, clearable_list contains all the weak pointers to
|
5527
|
|
- * unmarked (unused) static vecotors.
|
5528
|
|
- *
|
5529
|
|
- * Traverse the clearable list. If the weak pointer points to an
|
5530
|
|
- * unmarked static vector, mark it. If it points to a marked
|
5531
|
|
- * static vector, then we know it shares a referent with another
|
5532
|
|
- * weak pointer. Break this weak pointer and remove it from the
|
5533
|
|
- * clearable list by setting it to NIL.
|
5534
|
|
- */
|
5535
|
|
- if (debug_static_array_p) {
|
5536
|
|
- printf("Phase 2: %d pointers\n", num_static_vectors);
|
5537
|
|
- }
|
5538
|
|
-
|
5539
|
|
- for (n = 0; n < num_static_vectors; ++n) {
|
5540
|
|
- struct weak_pointer *wp = clearable_list[n];
|
5541
|
|
- lispobj *header = (lispobj *) PTR(wp->value);
|
5542
|
|
-
|
5543
|
|
- if (debug_static_array_p) {
|
5544
|
|
- printf("%2d: wp = %p, header = 0x%08lx\n", n, wp, *header);
|
5545
|
|
- }
|
5546
|
|
-
|
5547
|
|
- if (HeaderValue(*header) == 1) {
|
5548
|
|
- /*
|
5549
|
|
- * If the header value is 1, we have an unmarked static
|
5550
|
|
- * vector. Mark it now.
|
5551
|
|
- */
|
5552
|
|
- if (debug_static_array_p) {
|
5553
|
|
- printf(" Mark vector\n");
|
5554
|
|
- }
|
5555
|
|
-
|
5556
|
|
- *header |= 0x80000000;
|
5557
|
|
- } else {
|
5558
|
|
- /*
|
5559
|
|
- * We have a marked static vector. Break this weak
|
5560
|
|
- * pointer and remove it from the list by setting it to
|
5561
|
|
- * NIL.
|
5562
|
|
- */
|
5563
|
|
- if (debug_static_array_p) {
|
5564
|
|
- printf(" Break weak pointer %p\n", wp);
|
5565
|
|
- }
|
5566
|
|
-
|
5567
|
|
- wp->value = NIL;
|
5568
|
|
- wp->broken = T;
|
5569
|
|
- clearable_list[n] = NULL;
|
5570
|
|
- }
|
5571
|
|
- }
|
5572
|
|
-
|
5573
|
|
- /*
|
5574
|
|
- * At this point, the clearable list is either NIL or a weak
|
5575
|
|
- * pointer that references a unique dead static vector.
|
5576
|
|
- *
|
5577
|
|
- * Traverse the clearable list skipping over any NIL entries. For
|
5578
|
|
- * all other entries, free the static vector and break the weak
|
5579
|
|
- * pointer.
|
5580
|
|
- */
|
5581
|
|
-
|
5582
|
|
- if (debug_static_array_p) {
|
5583
|
|
- printf("Phase 3: Free static vectors\n");
|
5584
|
|
- }
|
5585
|
|
-
|
5586
|
|
- for (n = 0; n < num_static_vectors; ++n) {
|
5587
|
|
- struct weak_pointer *wp = clearable_list[n];
|
5588
|
|
- if (wp != NULL) {
|
5589
|
|
- lispobj *static_array = (lispobj *) PTR(wp->value);
|
5590
|
|
-
|
5591
|
|
- if (debug_static_array_p) {
|
5592
|
|
- printf("%2d: free wp %p: %p\n", n, (void*) wp, static_array);
|
5593
|
5510
|
}
|
5594
|
|
-
|
5595
|
|
- free(static_array);
|
5596
|
|
- wp->value = NIL;
|
5597
|
|
- wp->broken = T;
|
5598
|
5511
|
}
|
5599
|
5512
|
}
|
|
5513
|
+ printf("scan_weak_pointers done\n");
|
5600
|
5514
|
|
5601
|
|
- free(clearable_list);
|
|
5515
|
+ scan_static_vectors();
|
5602
|
5516
|
}
|
5603
|
5517
|
|
5604
|
5518
|
|