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

Commits:

1 changed file:

Changes:

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