| ... | 
... | 
@@ -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
 | 
 
  |