Raymond Toy pushed to branch issue-243-weak-pointer-to-static-array at cmucl / cmucl
Commits: 9c0971b2 by Raymond Toy at 2024-02-18T14:01:01-08:00 Put back tabs to match master branch
This minimizes the difference between this and the master.
- - - - - 025f7c08 by Raymond Toy at 2024-02-18T14:04:32-08:00 Add comment for phase 4 of scanning static vectors.
- - - - - b5653912 by Raymond Toy at 2024-02-18T14:18:55-08:00 Be more careful about clearing the static vector mark bit
Check that the weak pointer hasn't been broken yet before trying to clear the mark bit of the static vector.
I think this currently doesn't matter because when the weak pointer is broken, the value is set to NIL, and NIL doesn't have the MSB set. But that's not guaranteed, so let's be safe.
- - - - - 2478e670 by Raymond Toy at 2024-02-18T14:26:02-08:00 For phase 3 and 4, onl process weak pointers that are not broken
For a little extra safety, only process weak pointers that have not been broken, so add the check at the very beginning of the loop.
- - - - - 84c364a2 by Raymond Toy at 2024-02-18T14:32:20-08:00 Add some more comments
- - - - -
1 changed file:
- src/lisp/gencgc.c
Changes:
===================================== src/lisp/gencgc.c ===================================== @@ -5442,13 +5442,13 @@ scan_static_vectors(void)
if (Pointerp(value)) { /* The value may be a static vector */ - lispobj *header = (lispobj *) PTR(value); + lispobj header = *(lispobj *) PTR(value);
- if (maybe_static_array_p(*header)) { + if (maybe_static_array_p(header)) {
if (debug_static_array_p) { printf(" Add: wp %p value %p header 0x%08lx, next = %p\n", - wp, (lispobj *) wp->value, *header, wp->next); + wp, (lispobj *) wp->value, header, wp->next); }
wp->next = static_vector_list; @@ -5456,7 +5456,7 @@ scan_static_vectors(void) } else { if (debug_static_array_p) { printf(" Skip: wp %p value %p header 0x%08lx\n", - wp, (lispobj *) wp->value, *header); + wp, (lispobj *) wp->value, header); } } } @@ -5472,7 +5472,6 @@ scan_static_vectors(void) * vectors. For unmarked (unused) static vectors, set another bit * in the header to say we've visited it. If we've already * visited the static vector, break the weak pointer. - * */ for (wp = static_vector_list; wp; wp = wp->next) { lispobj *header = (lispobj *) PTR(wp->value); @@ -5512,23 +5511,27 @@ scan_static_vectors(void) }
/* + * static_vector_list now contains either broken weak pointers or + * weak pointers to static arrays (whether alive or not). + * * Free up space. Go through static_vector_list and for each weak * pointer that hasn't been broken and is an unused static array, * free the static vector. Also break the weak pointer too, since * the space has been freed. */ for (wp = static_vector_list; wp; wp = wp->next) { - lispobj *header = (lispobj *) PTR(wp->value); + /* Skip over broken weak pointers */ + if (wp->broken == NIL) { + lispobj *header = (lispobj *) PTR(wp->value);
- if (debug_static_array_p) { - printf(" wp %p value %p header 0x%08lx\n", - wp, (lispobj*) wp->value, *header); - } + if (debug_static_array_p) { + printf(" wp %p value %p header 0x%08lx\n", + wp, (lispobj*) wp->value, *header); + }
- /* - * Only free the arrays where the mark bit is clear. - */ - if (wp->broken == NIL) { + /* + * Only free the arrays where the mark bit is clear. + */ if ((*header & STATIC_VECTOR_MARK_BIT) == 0) { lispobj *static_array = (lispobj *) PTR(wp->value); if (debug_static_array_p) { @@ -5542,25 +5545,36 @@ scan_static_vectors(void) } } } +
if (debug_static_array_p) { printf("Phase 4: unmark static vectors\n"); }
+ /* + * At this point, static_vector_list contains weak pointers that + * have been broken or weak pointres to live static vectors. Go + * through all the weak pointers and if it hasn't been broken and + * if the mark bit of the static vector is set, then clear the + * mark bit . + */ for (wp = static_vector_list; wp; wp = wp->next) { - lispobj *header = (lispobj *) PTR(wp->value); - - if (debug_static_array_p) { - printf(" wp %p value %p broken %d header 0x%08lx\n", - wp, (lispobj*) wp->value, wp->broken == T, *header); - } + /* Skip over broken weak pointers */ + if (wp->broken == NIL) { + lispobj *header = (lispobj *) PTR(wp->value);
- if ((*header & STATIC_VECTOR_MARK_BIT) != 0) { if (debug_static_array_p) { - printf(" Clearing mark bit\n"); + printf(" wp %p value %p broken %d header 0x%08lx\n", + wp, (lispobj*) wp->value, wp->broken == T, *header); }
- *header &= ~STATIC_VECTOR_MARK_BIT; + if ((*header & STATIC_VECTOR_MARK_BIT) != 0) { + if (debug_static_array_p) { + printf(" Clearing mark bit\n"); + } + + *header &= ~STATIC_VECTOR_MARK_BIT; + } } } } @@ -5576,13 +5590,13 @@ scan_weak_pointers(void)
wp->mark_bit = NIL; if (Pointerp(value) && from_space_p(value)) { - if (first_pointer[0] == 0x01) - wp->value = first_pointer[1]; - else { - wp->value = NIL; - wp->broken = T; - } - } + if (first_pointer[0] == 0x01) + wp->value = first_pointer[1]; + else { + wp->value = NIL; + wp->broken = T; + } + } }
scan_static_vectors();
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/9cb44e305299b41e951c584...