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

Commits:

1 changed file:

Changes:

  • src/lisp/gencgc.c
    ... ... @@ -5401,19 +5401,20 @@ static void
    5401 5401
     scan_static_vectors(void)
    
    5402 5402
     {
    
    5403 5403
         struct weak_pointer *wp;
    
    5404
    -    struct weak_pointer *clearable_list = NULL;
    
    5404
    +    struct weak_pointer *static_vector_list = NULL;
    
    5405
    +    const int scan_mark_flag = 0x8000;
    
    5405 5406
     
    
    5406 5407
         if (debug_static_array_p) {
    
    5407
    -        printf("Phase 1: build clearable list\n");
    
    5408
    +        printf("Phase 1: find static vectors\n");
    
    5408 5409
         }
    
    5409 5410
     
    
    5410 5411
         /*
    
    5411
    -     * Find weak pointers to unmarked static arrays, using a linked
    
    5412
    -     * list.  We reuse the next slot ofthe weak pointer to chain these
    
    5413
    -     * weak pointers together.
    
    5412
    +     * Find weak pointers to static arrays, using a linked list.  We
    
    5413
    +     * reuse the next slot of the weak pointer to chain these weak
    
    5414
    +     * pointers together.
    
    5414 5415
          *
    
    5415
    -     * Invariant: clearable_list only has weak pointers to unmarked
    
    5416
    -     * static vectors.
    
    5416
    +     * Invariant: static_vector_list only has weak pointers to static
    
    5417
    +     * vectors.
    
    5417 5418
          */
    
    5418 5419
         wp = weak_pointers;
    
    5419 5420
         while (wp) {
    
    ... ... @@ -5424,16 +5425,15 @@ scan_static_vectors(void)
    5424 5425
                 /* The value may be a static vector */
    
    5425 5426
                 lispobj *header = (lispobj *) PTR(value);
    
    5426 5427
     
    
    5427
    -            if (maybe_static_array_p(*header)
    
    5428
    -                && (HeaderValue(*header) == 1)) {
    
    5428
    +            if (maybe_static_array_p(*header)) {
    
    5429 5429
     
    
    5430 5430
                     if (debug_static_array_p) {
    
    5431 5431
                         printf("Adding %p header = 0x%08lx, next = %p\n",
    
    5432 5432
                                wp, *header, wp->next);
    
    5433 5433
                     }
    
    5434 5434
     
    
    5435
    -                wp->next = clearable_list;
    
    5436
    -                clearable_list = wp;
    
    5435
    +                wp->next = static_vector_list;
    
    5436
    +                static_vector_list = wp;
    
    5437 5437
                 } else {
    
    5438 5438
                     if (debug_static_array_p) {
    
    5439 5439
                         printf("Skipping %p header = 0x%08lx\n", wp, *header);
    
    ... ... @@ -5448,14 +5448,13 @@ scan_static_vectors(void)
    5448 5448
         }
    
    5449 5449
         
    
    5450 5450
         /*
    
    5451
    -     * clearable_list now points to all weak pointers to unmarked
    
    5452
    -     * static vectors.  Go through the list.  If it's not marked, mark
    
    5453
    -     * it.  If it's marked, break the weak pointer.
    
    5451
    +     * static_vector_list now points to all weak pointers to static
    
    5452
    +     * vectors.  For unmarked (unused) static vectors, set another bit
    
    5453
    +     * in the header to say we've visited it.  If we've already
    
    5454
    +     * visited the static vector, break the weak pointer.
    
    5454 5455
          *
    
    5455
    -     * Invariant: clearable_list contains only weak pointers that have
    
    5456
    -     * been broken or that point to a unique dead static vector.
    
    5457 5456
          */
    
    5458
    -    for (wp = clearable_list; wp; wp = wp->next) {
    
    5457
    +    for (wp = static_vector_list; wp; wp = wp->next) {
    
    5459 5458
             lispobj *header = (lispobj *) PTR(wp->value);
    
    5460 5459
     
    
    5461 5460
             if (debug_static_array_p) {
    
    ... ... @@ -5463,42 +5462,60 @@ scan_static_vectors(void)
    5463 5462
                        wp, wp->value, *header);
    
    5464 5463
             }
    
    5465 5464
     
    
    5466
    -        if (HeaderValue(*header) == 1) {
    
    5467
    -            if (debug_static_array_p) {
    
    5468
    -                printf("  Mark vector\n");
    
    5469
    -            }
    
    5465
    +        /*
    
    5466
    +         * If the static vector is unused (mark bit clear) and if we
    
    5467
    +         * haven't seen this vector before, set the scan flag.
    
    5468
    +         */
    
    5469
    +        if ((*header & 0x80000000) == 0) {
    
    5470
    +            /* Unused static vector */
    
    5471
    +            if ((*header & scan_mark_flag) == 0) {
    
    5472
    +                if (debug_static_array_p) {
    
    5473
    +                    printf("  Mark vector\n");
    
    5474
    +                }
    
    5470 5475
     
    
    5471
    -            *header |= 0x80000000;
    
    5472
    -        } else {
    
    5473
    -            if (debug_static_array_p) {
    
    5474
    -                printf("  Break weak pointer %p\n", wp);
    
    5475
    -            }
    
    5476
    +                *header |= scan_mark_flag;
    
    5477
    +            } else {
    
    5478
    +                if (debug_static_array_p) {
    
    5479
    +                    printf("  Break weak pointer %p\n", wp);
    
    5480
    +                }
    
    5476 5481
     
    
    5477
    -            wp->value = NIL;
    
    5478
    -            wp->broken = T;
    
    5482
    +                wp->value = NIL;
    
    5483
    +                wp->broken = T;
    
    5484
    +            }
    
    5479 5485
             }
    
    5480 5486
         }
    
    5487
    +    
    
    5481 5488
     
    
    5482 5489
         if (debug_static_array_p) {
    
    5483 5490
             printf("Phase 3: Free static vectors\n");
    
    5484 5491
         }
    
    5485 5492
     
    
    5486 5493
         /*
    
    5487
    -     * Free up space.  Go through clearable_list and for each weak
    
    5488
    -     * pointer that has not been broken, we can free the space.  Then
    
    5489
    -     * break the weak pointer too, since the space has been freed.
    
    5494
    +     * Free up space.  Go through static_vector_list and for each weak
    
    5495
    +     * pointer that hasn't been broken and is an unused static array,
    
    5496
    +     * free the static vector.  Also break the weak pointer too, since
    
    5497
    +     * the space has been freed.
    
    5490 5498
          */
    
    5491
    -    for (wp = clearable_list; wp; wp = wp->next) {
    
    5499
    +    for (wp = static_vector_list; wp; wp = wp->next) {
    
    5500
    +        lispobj *header = (lispobj *) PTR(wp->value);
    
    5501
    +
    
    5502
    +        printf("wp = %p, header = 0x%08lx\n", wp, *header);
    
    5503
    +
    
    5504
    +        /*
    
    5505
    +         * Only free the arrays where the mark bit is clear.
    
    5506
    +         */
    
    5492 5507
             if (wp->broken == NIL) {
    
    5493
    -            lispobj *static_array = (lispobj *) PTR(wp->value);
    
    5494
    -            if (debug_static_array_p) {
    
    5495
    -                printf("free wp %p: %p\n", wp, static_array);
    
    5496
    -            }
    
    5508
    +            if ((*header & 0x80000000) == 0)  {
    
    5509
    +                lispobj *static_array = (lispobj *) PTR(wp->value);
    
    5510
    +                if (debug_static_array_p) {
    
    5511
    +                    printf("free wp %p: %p\n", wp, static_array);
    
    5512
    +                }
    
    5497 5513
     
    
    5498
    -            wp->value = NIL;
    
    5499
    -            wp->broken = T;
    
    5514
    +                wp->value = NIL;
    
    5515
    +                wp->broken = T;
    
    5500 5516
     
    
    5501
    -            free(static_array);
    
    5517
    +                free(static_array);
    
    5518
    +            }
    
    5502 5519
             }
    
    5503 5520
         }
    
    5504 5521
     }