... |
... |
@@ -32,6 +32,25 @@ |
32
|
32
|
*/
|
33
|
33
|
#define EQ_BASED_HASH_VALUE 0x80000000
|
34
|
34
|
|
|
35
|
+/*
|
|
36
|
+ * If the header value for a vector has this bit set, then it is a
|
|
37
|
+ * static vector.
|
|
38
|
+ */
|
|
39
|
+#define STATIC_VECTOR_HEADER_BIT 0x1
|
|
40
|
+
|
|
41
|
+/*
|
|
42
|
+ * Mark bit for static vectors. If set in the header, the static
|
|
43
|
+ * vector is in use.
|
|
44
|
+ */
|
|
45
|
+#define STATIC_VECTOR_MARK_BIT 0x80000000
|
|
46
|
+
|
|
47
|
+/*
|
|
48
|
+ * Visited bit for static vectors. When scanning weak pointers for
|
|
49
|
+ * static vectors, this bit indicates that we've visited this static
|
|
50
|
+ * vector already.
|
|
51
|
+ */
|
|
52
|
+#define STATIC_VECTOR_VISITED_BIT 0x08000000
|
|
53
|
+
|
35
|
54
|
#define gc_abort() lose("GC invariant lost! File \"%s\", line %d\n", \
|
36
|
55
|
__FILE__, __LINE__)
|
37
|
56
|
|
... |
... |
@@ -241,7 +260,7 @@ unsigned counters_verbose = 0; |
241
|
260
|
* If true, then some debugging information is printed when scavenging
|
242
|
261
|
* static (malloc'ed) arrays.
|
243
|
262
|
*/
|
244
|
|
-boolean debug_static_array_p = 0;
|
|
263
|
+boolean debug_static_array_p = 1;
|
245
|
264
|
|
246
|
265
|
/*
|
247
|
266
|
* To enable the use of page protection to help avoid the scavenging
|
... |
... |
@@ -2718,13 +2737,14 @@ scav_static_vector(lispobj object) |
2718
|
2737
|
ptr, (unsigned long) header);
|
2719
|
2738
|
}
|
2720
|
2739
|
|
2721
|
|
- static_p = (HeaderValue(header) & 1) == 1;
|
|
2740
|
+ static_p = (HeaderValue(header) & STATIC_VECTOR_HEADER_BIT) == 1;
|
2722
|
2741
|
if (static_p) {
|
2723
|
2742
|
/*
|
2724
|
|
- * We have a static vector. Mark it as
|
2725
|
|
- * reachable by setting the MSB of the header.
|
|
2743
|
+ * We have a static vector. Mark it as reachable by
|
|
2744
|
+ * setting the MSB of the header. And clear out any
|
|
2745
|
+ * possible visited bit.
|
2726
|
2746
|
*/
|
2727
|
|
- *ptr = header | 0x80000000;
|
|
2747
|
+ *ptr = (header | STATIC_VECTOR_MARK_BIT) & ~STATIC_VECTOR_VISITED_BIT;
|
2728
|
2748
|
if (debug_static_array_p) {
|
2729
|
2749
|
fprintf(stderr, "Scavenged static vector @%p, header = 0x%lx\n",
|
2730
|
2750
|
ptr, (unsigned long) header);
|
... |
... |
@@ -5402,10 +5422,9 @@ scan_static_vectors(void) |
5402
|
5422
|
{
|
5403
|
5423
|
struct weak_pointer *wp;
|
5404
|
5424
|
struct weak_pointer *static_vector_list = NULL;
|
5405
|
|
- const int scan_mark_flag = 0x8000;
|
5406
|
5425
|
|
5407
|
5426
|
if (debug_static_array_p) {
|
5408
|
|
- printf("Phase 1: find static vectors\n");
|
|
5427
|
+ printf("Phase 1: Find static vectors\n");
|
5409
|
5428
|
}
|
5410
|
5429
|
|
5411
|
5430
|
/*
|
... |
... |
@@ -5428,15 +5447,16 @@ scan_static_vectors(void) |
5428
|
5447
|
if (maybe_static_array_p(*header)) {
|
5429
|
5448
|
|
5430
|
5449
|
if (debug_static_array_p) {
|
5431
|
|
- printf("Adding %p header = 0x%08lx, next = %p\n",
|
5432
|
|
- wp, *header, wp->next);
|
|
5450
|
+ printf(" Add: wp %p value %p header 0x%08lx, next = %p\n",
|
|
5451
|
+ wp, (lispobj *) wp->value, *header, wp->next);
|
5433
|
5452
|
}
|
5434
|
5453
|
|
5435
|
5454
|
wp->next = static_vector_list;
|
5436
|
5455
|
static_vector_list = wp;
|
5437
|
5456
|
} else {
|
5438
|
5457
|
if (debug_static_array_p) {
|
5439
|
|
- printf("Skipping %p header = 0x%08lx\n", wp, *header);
|
|
5458
|
+ printf(" Skip: wp %p value %p header 0x%08lx\n",
|
|
5459
|
+ wp, (lispobj *) wp->value, *header);
|
5440
|
5460
|
}
|
5441
|
5461
|
}
|
5442
|
5462
|
}
|
... |
... |
@@ -5444,7 +5464,7 @@ scan_static_vectors(void) |
5444
|
5464
|
}
|
5445
|
5465
|
|
5446
|
5466
|
if (debug_static_array_p) {
|
5447
|
|
- printf("Phase 2\n");
|
|
5467
|
+ printf("Phase 2: Visit unused static vectors\n");
|
5448
|
5468
|
}
|
5449
|
5469
|
|
5450
|
5470
|
/*
|
... |
... |
@@ -5458,25 +5478,26 @@ scan_static_vectors(void) |
5458
|
5478
|
lispobj *header = (lispobj *) PTR(wp->value);
|
5459
|
5479
|
|
5460
|
5480
|
if (debug_static_array_p) {
|
5461
|
|
- printf("wp %p value 0x%08lx header 0x%08lx\n",
|
5462
|
|
- wp, wp->value, *header);
|
|
5481
|
+ printf(" wp %p value %p header 0x%08lx\n",
|
|
5482
|
+ wp, (lispobj *) wp->value, *header);
|
5463
|
5483
|
}
|
5464
|
5484
|
|
5465
|
5485
|
/*
|
5466
|
5486
|
* If the static vector is unused (mark bit clear) and if we
|
5467
|
|
- * haven't seen this vector before, set the scan flag.
|
|
5487
|
+ * haven't seen this vector before, set the visited flag. If
|
|
5488
|
+ * we have visited this vector before, break the weak pointer.
|
5468
|
5489
|
*/
|
5469
|
|
- if ((*header & 0x80000000) == 0) {
|
|
5490
|
+ if ((*header & STATIC_VECTOR_MARK_BIT) == 0) {
|
5470
|
5491
|
/* Unused static vector */
|
5471
|
|
- if ((*header & scan_mark_flag) == 0) {
|
|
5492
|
+ if ((*header & STATIC_VECTOR_VISITED_BIT) == 0) {
|
5472
|
5493
|
if (debug_static_array_p) {
|
5473
|
|
- printf(" Mark vector\n");
|
|
5494
|
+ printf(" Mark vector\n");
|
5474
|
5495
|
}
|
5475
|
5496
|
|
5476
|
|
- *header |= scan_mark_flag;
|
|
5497
|
+ *header |= STATIC_VECTOR_VISITED_BIT;
|
5477
|
5498
|
} else {
|
5478
|
5499
|
if (debug_static_array_p) {
|
5479
|
|
- printf(" Break weak pointer %p\n", wp);
|
|
5500
|
+ printf(" Break weak pointer %p\n", wp);
|
5480
|
5501
|
}
|
5481
|
5502
|
|
5482
|
5503
|
wp->value = NIL;
|
... |
... |
@@ -5499,16 +5520,19 @@ scan_static_vectors(void) |
5499
|
5520
|
for (wp = static_vector_list; wp; wp = wp->next) {
|
5500
|
5521
|
lispobj *header = (lispobj *) PTR(wp->value);
|
5501
|
5522
|
|
5502
|
|
- printf("wp = %p, header = 0x%08lx\n", wp, *header);
|
|
5523
|
+ if (debug_static_array_p) {
|
|
5524
|
+ printf(" wp %p value %p header 0x%08lx\n",
|
|
5525
|
+ wp, (lispobj*) wp->value, *header);
|
|
5526
|
+ }
|
5503
|
5527
|
|
5504
|
5528
|
/*
|
5505
|
5529
|
* Only free the arrays where the mark bit is clear.
|
5506
|
5530
|
*/
|
5507
|
5531
|
if (wp->broken == NIL) {
|
5508
|
|
- if ((*header & 0x80000000) == 0) {
|
|
5532
|
+ if ((*header & STATIC_VECTOR_MARK_BIT) == 0) {
|
5509
|
5533
|
lispobj *static_array = (lispobj *) PTR(wp->value);
|
5510
|
5534
|
if (debug_static_array_p) {
|
5511
|
|
- printf("free wp %p: %p\n", wp, static_array);
|
|
5535
|
+ printf(" Free wp\n");
|
5512
|
5536
|
}
|
5513
|
5537
|
|
5514
|
5538
|
wp->value = NIL;
|
... |
... |
@@ -5518,6 +5542,27 @@ scan_static_vectors(void) |
5518
|
5542
|
}
|
5519
|
5543
|
}
|
5520
|
5544
|
}
|
|
5545
|
+
|
|
5546
|
+ if (debug_static_array_p) {
|
|
5547
|
+ printf("Phase 4: unmark static vectors\n");
|
|
5548
|
+ }
|
|
5549
|
+
|
|
5550
|
+ for (wp = static_vector_list; wp; wp = wp->next) {
|
|
5551
|
+ lispobj *header = (lispobj *) PTR(wp->value);
|
|
5552
|
+
|
|
5553
|
+ if (debug_static_array_p) {
|
|
5554
|
+ printf(" wp %p value %p broken %d header 0x%08lx\n",
|
|
5555
|
+ wp, (lispobj*) wp->value, wp->broken == T, *header);
|
|
5556
|
+ }
|
|
5557
|
+
|
|
5558
|
+ if ((*header & STATIC_VECTOR_MARK_BIT) != 0) {
|
|
5559
|
+ if (debug_static_array_p) {
|
|
5560
|
+ printf(" Clearing mark bit\n");
|
|
5561
|
+ }
|
|
5562
|
+
|
|
5563
|
+ *header &= ~STATIC_VECTOR_MARK_BIT;
|
|
5564
|
+ }
|
|
5565
|
+ }
|
5521
|
5566
|
}
|
5522
|
5567
|
|
5523
|
5568
|
void
|