diff options
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/src/alloc.c b/src/alloc.c index 07775391bfb..93146526118 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -349,14 +349,23 @@ static void | |||
| 349 | mark_interval_tree (tree) | 349 | mark_interval_tree (tree) |
| 350 | register INTERVAL tree; | 350 | register INTERVAL tree; |
| 351 | { | 351 | { |
| 352 | if (XMARKBIT (tree->plist)) | 352 | /* No need to test if this tree has been marked already; this |
| 353 | return; | 353 | function is always called through the MARK_INTERVAL_TREE macro, |
| 354 | which takes care of that. */ | ||
| 355 | |||
| 356 | /* XMARK expands to an assignment; the LHS of an assignment can't be | ||
| 357 | a cast. */ | ||
| 358 | XMARK (* (Lisp_Object *) &tree->parent); | ||
| 354 | 359 | ||
| 355 | traverse_intervals (tree, 1, 0, mark_interval, Qnil); | 360 | traverse_intervals (tree, 1, 0, mark_interval, Qnil); |
| 356 | } | 361 | } |
| 357 | 362 | ||
| 358 | #define MARK_INTERVAL_TREE(i) \ | 363 | #define MARK_INTERVAL_TREE(i) \ |
| 359 | { if (!NULL_INTERVAL_P (i)) mark_interval_tree (i); } | 364 | do { \ |
| 365 | if (!NULL_INTERVAL_P (i) \ | ||
| 366 | && ! XMARKBIT ((Lisp_Object) i->parent)) \ | ||
| 367 | mark_interval_tree (i); \ | ||
| 368 | } while (0) | ||
| 360 | 369 | ||
| 361 | /* The oddity in the call to XUNMARK is necessary because XUNMARK | 370 | /* The oddity in the call to XUNMARK is necessary because XUNMARK |
| 362 | expands to an assignment to its argument, and most C compilers don't | 371 | expands to an assignment to its argument, and most C compilers don't |
| @@ -1957,25 +1966,30 @@ gc_sweep () | |||
| 1957 | /* Free all "large strings" not marked with ARRAY_MARK_FLAG. */ | 1966 | /* Free all "large strings" not marked with ARRAY_MARK_FLAG. */ |
| 1958 | { | 1967 | { |
| 1959 | register struct string_block *sb = large_string_blocks, *prev = 0, *next; | 1968 | register struct string_block *sb = large_string_blocks, *prev = 0, *next; |
| 1969 | struct Lisp_String *s; | ||
| 1960 | 1970 | ||
| 1961 | while (sb) | 1971 | while (sb) |
| 1962 | if (!(((struct Lisp_String *)(&sb->chars[0]))->size & ARRAY_MARK_FLAG)) | 1972 | { |
| 1963 | { | 1973 | s = (struct Lisp_String *) &sb->chars[0]; |
| 1964 | if (prev) | 1974 | if (s->size & ARRAY_MARK_FLAG) |
| 1965 | prev->next = sb->next; | 1975 | { |
| 1966 | else | 1976 | ((struct Lisp_String *)(&sb->chars[0]))->size |
| 1967 | large_string_blocks = sb->next; | 1977 | &= ~ARRAY_MARK_FLAG & ~MARKBIT; |
| 1968 | next = sb->next; | 1978 | UNMARK_BALANCE_INTERVALS (s->intervals); |
| 1969 | xfree (sb); | 1979 | total_string_size += ((struct Lisp_String *)(&sb->chars[0]))->size; |
| 1970 | sb = next; | 1980 | prev = sb, sb = sb->next; |
| 1971 | } | 1981 | } |
| 1972 | else | 1982 | else |
| 1973 | { | 1983 | { |
| 1974 | ((struct Lisp_String *)(&sb->chars[0]))->size | 1984 | if (prev) |
| 1975 | &= ~ARRAY_MARK_FLAG & ~MARKBIT; | 1985 | prev->next = sb->next; |
| 1976 | total_string_size += ((struct Lisp_String *)(&sb->chars[0]))->size; | 1986 | else |
| 1977 | prev = sb, sb = sb->next; | 1987 | large_string_blocks = sb->next; |
| 1978 | } | 1988 | next = sb->next; |
| 1989 | xfree (sb); | ||
| 1990 | sb = next; | ||
| 1991 | } | ||
| 1992 | } | ||
| 1979 | } | 1993 | } |
| 1980 | } | 1994 | } |
| 1981 | 1995 | ||
| @@ -2067,6 +2081,16 @@ compact_strings () | |||
| 2067 | } | 2081 | } |
| 2068 | /* Store the actual size in the size field. */ | 2082 | /* Store the actual size in the size field. */ |
| 2069 | newaddr->size = size; | 2083 | newaddr->size = size; |
| 2084 | |||
| 2085 | /* Now that the string has been relocated, rebalance its | ||
| 2086 | interval tree, and update the tree's parent pointer. */ | ||
| 2087 | if (! NULL_INTERVAL_P (newaddr->intervals)) | ||
| 2088 | { | ||
| 2089 | UNMARK_BALANCE_INTERVALS (newaddr->intervals); | ||
| 2090 | XSET (* (Lisp_Object *) &newaddr->intervals->parent, | ||
| 2091 | Lisp_String, | ||
| 2092 | newaddr); | ||
| 2093 | } | ||
| 2070 | } | 2094 | } |
| 2071 | pos += STRING_FULLSIZE (size); | 2095 | pos += STRING_FULLSIZE (size); |
| 2072 | } | 2096 | } |