Raymond Toy pushed to branch issue-243-weak-pointer-to-static-array at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/array.lisp
    ... ... @@ -406,6 +406,7 @@
    406 406
     	  (delete-if-not #'weak-pointer-value *static-vectors*))))
    
    407 407
     
    
    408 408
     ;; Clear the mark bit of all of static vectors before GC
    
    409
    +#+nil
    
    409 410
     (pushnew 'clear-static-vector-mark *before-gc-hooks*)
    
    410 411
     ;; Clean up any unreferenced static vectors after GC has run.
    
    411 412
     (pushnew 'finalize-static-vectors *after-gc-hooks*)
    

  • src/lisp/gencgc.c
    ... ... @@ -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