356 |
|
|
357 |
/* Node color. */ |
/* Node color. */ |
358 |
enum {MEM_BLACK, MEM_RED} color; |
enum {MEM_BLACK, MEM_RED} color; |
359 |
|
|
360 |
/* Memory type. */ |
/* Memory type. */ |
361 |
enum mem_type type; |
enum mem_type type; |
362 |
}; |
}; |
596 |
#ifdef GC_MALLOC_CHECK |
#ifdef GC_MALLOC_CHECK |
597 |
allocated_mem_type = type; |
allocated_mem_type = type; |
598 |
#endif |
#endif |
599 |
|
|
600 |
val = (void *) malloc (nbytes); |
val = (void *) malloc (nbytes); |
601 |
|
|
602 |
#if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
#if GC_MARK_STACK && !defined GC_MALLOC_CHECK |
603 |
if (val && type != MEM_TYPE_NON_LISP) |
if (val && type != MEM_TYPE_NON_LISP) |
604 |
mem_insert (val, (char *) val + nbytes, type); |
mem_insert (val, (char *) val + nbytes, type); |
605 |
#endif |
#endif |
606 |
|
|
607 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
608 |
if (!val && nbytes) |
if (!val && nbytes) |
609 |
memory_full (); |
memory_full (); |
617 |
struct buffer * |
struct buffer * |
618 |
allocate_buffer () |
allocate_buffer () |
619 |
{ |
{ |
620 |
struct buffer *b |
struct buffer *b |
621 |
= (struct buffer *) lisp_malloc (sizeof (struct buffer), |
= (struct buffer *) lisp_malloc (sizeof (struct buffer), |
622 |
MEM_TYPE_BUFFER); |
MEM_TYPE_BUFFER); |
623 |
VALIDATE_LISP_STORAGE (b, sizeof *b); |
VALIDATE_LISP_STORAGE (b, sizeof *b); |
674 |
if (ptr) |
if (ptr) |
675 |
{ |
{ |
676 |
struct mem_node *m; |
struct mem_node *m; |
677 |
|
|
678 |
m = mem_find (ptr); |
m = mem_find (ptr); |
679 |
if (m == MEM_NIL || m->start != ptr) |
if (m == MEM_NIL || m->start != ptr) |
680 |
{ |
{ |
689 |
} |
} |
690 |
} |
} |
691 |
#endif /* GC_MALLOC_CHECK */ |
#endif /* GC_MALLOC_CHECK */ |
692 |
|
|
693 |
__free_hook = old_free_hook; |
__free_hook = old_free_hook; |
694 |
free (ptr); |
free (ptr); |
695 |
|
|
696 |
/* If we released our reserve (due to running out of memory), |
/* If we released our reserve (due to running out of memory), |
697 |
and we have a fair amount free once again, |
and we have a fair amount free once again, |
698 |
try to set aside another reserve in case we run out once more. */ |
try to set aside another reserve in case we run out once more. */ |
762 |
} |
} |
763 |
} |
} |
764 |
#endif /* GC_MALLOC_CHECK */ |
#endif /* GC_MALLOC_CHECK */ |
765 |
|
|
766 |
__malloc_hook = emacs_blocked_malloc; |
__malloc_hook = emacs_blocked_malloc; |
767 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
768 |
|
|
797 |
|
|
798 |
mem_delete (m); |
mem_delete (m); |
799 |
} |
} |
800 |
|
|
801 |
/* fprintf (stderr, "%p -> realloc\n", ptr); */ |
/* fprintf (stderr, "%p -> realloc\n", ptr); */ |
802 |
|
|
803 |
/* Prevent malloc from registering blocks. */ |
/* Prevent malloc from registering blocks. */ |
804 |
dont_register_blocks = 1; |
dont_register_blocks = 1; |
805 |
#endif /* GC_MALLOC_CHECK */ |
#endif /* GC_MALLOC_CHECK */ |
820 |
/* Can't handle zero size regions in the red-black tree. */ |
/* Can't handle zero size regions in the red-black tree. */ |
821 |
mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP); |
mem_insert (value, (char *) value + max (size, 1), MEM_TYPE_NON_LISP); |
822 |
} |
} |
823 |
|
|
824 |
/* fprintf (stderr, "%p <- realloc\n", value); */ |
/* fprintf (stderr, "%p <- realloc\n", value); */ |
825 |
#endif /* GC_MALLOC_CHECK */ |
#endif /* GC_MALLOC_CHECK */ |
826 |
|
|
827 |
__realloc_hook = emacs_blocked_realloc; |
__realloc_hook = emacs_blocked_realloc; |
828 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
829 |
|
|
1069 |
struct Lisp_String *string; |
struct Lisp_String *string; |
1070 |
|
|
1071 |
#ifdef GC_CHECK_STRING_BYTES |
#ifdef GC_CHECK_STRING_BYTES |
1072 |
|
|
1073 |
EMACS_INT nbytes; |
EMACS_INT nbytes; |
1074 |
unsigned char data[1]; |
unsigned char data[1]; |
1075 |
|
|
1076 |
#define SDATA_NBYTES(S) (S)->nbytes |
#define SDATA_NBYTES(S) (S)->nbytes |
1077 |
#define SDATA_DATA(S) (S)->data |
#define SDATA_DATA(S) (S)->data |
1078 |
|
|
1079 |
#else /* not GC_CHECK_STRING_BYTES */ |
#else /* not GC_CHECK_STRING_BYTES */ |
1080 |
|
|
1081 |
union |
union |
1086 |
/* When STRING is null. */ |
/* When STRING is null. */ |
1087 |
EMACS_INT nbytes; |
EMACS_INT nbytes; |
1088 |
} u; |
} u; |
1089 |
|
|
1090 |
|
|
1091 |
#define SDATA_NBYTES(S) (S)->u.nbytes |
#define SDATA_NBYTES(S) (S)->u.nbytes |
1092 |
#define SDATA_DATA(S) (S)->u.data |
#define SDATA_DATA(S) (S)->u.data |
1165 |
S must be live, i.e. S->data must not be null. S->data is actually |
S must be live, i.e. S->data must not be null. S->data is actually |
1166 |
a pointer to the `u.data' member of its sdata structure; the |
a pointer to the `u.data' member of its sdata structure; the |
1167 |
structure starts at a constant offset in front of that. */ |
structure starts at a constant offset in front of that. */ |
1168 |
|
|
1169 |
#ifdef GC_CHECK_STRING_BYTES |
#ifdef GC_CHECK_STRING_BYTES |
1170 |
|
|
1171 |
#define SDATA_OF_STRING(S) \ |
#define SDATA_OF_STRING(S) \ |
1238 |
abort (); |
abort (); |
1239 |
return nbytes; |
return nbytes; |
1240 |
} |
} |
1241 |
|
|
1242 |
/* Check validity of Lisp strings' string_bytes member in B. */ |
/* Check validity of Lisp strings' string_bytes member in B. */ |
1243 |
|
|
1244 |
void |
void |
1246 |
struct sblock *b; |
struct sblock *b; |
1247 |
{ |
{ |
1248 |
struct sdata *from, *end, *from_end; |
struct sdata *from, *end, *from_end; |
1249 |
|
|
1250 |
end = b->next_free; |
end = b->next_free; |
1251 |
|
|
1252 |
for (from = &b->first_data; from < end; from = from_end) |
for (from = &b->first_data; from < end; from = from_end) |
1253 |
{ |
{ |
1254 |
/* Compute the next FROM here because copying below may |
/* Compute the next FROM here because copying below may |
1255 |
overwrite data we need to compute it. */ |
overwrite data we need to compute it. */ |
1256 |
int nbytes; |
int nbytes; |
1257 |
|
|
1258 |
/* Check that the string size recorded in the string is the |
/* Check that the string size recorded in the string is the |
1259 |
same as the one recorded in the sdata structure. */ |
same as the one recorded in the sdata structure. */ |
1260 |
if (from->string) |
if (from->string) |
1261 |
CHECK_STRING_BYTES (from->string); |
CHECK_STRING_BYTES (from->string); |
1262 |
|
|
1263 |
if (from->string) |
if (from->string) |
1264 |
nbytes = GC_STRING_BYTES (from->string); |
nbytes = GC_STRING_BYTES (from->string); |
1265 |
else |
else |
1266 |
nbytes = SDATA_NBYTES (from); |
nbytes = SDATA_NBYTES (from); |
1267 |
|
|
1268 |
nbytes = SDATA_SIZE (nbytes); |
nbytes = SDATA_SIZE (nbytes); |
1269 |
from_end = (struct sdata *) ((char *) from + nbytes); |
from_end = (struct sdata *) ((char *) from + nbytes); |
1270 |
} |
} |
1289 |
if (s) |
if (s) |
1290 |
CHECK_STRING_BYTES (s); |
CHECK_STRING_BYTES (s); |
1291 |
} |
} |
1292 |
|
|
1293 |
for (b = oldest_sblock; b; b = b->next) |
for (b = oldest_sblock; b; b = b->next) |
1294 |
check_sblock (b); |
check_sblock (b); |
1295 |
} |
} |
1395 |
#endif |
#endif |
1396 |
|
|
1397 |
b = (struct sblock *) lisp_malloc (size, MEM_TYPE_NON_LISP); |
b = (struct sblock *) lisp_malloc (size, MEM_TYPE_NON_LISP); |
1398 |
|
|
1399 |
#ifdef DOUG_LEA_MALLOC |
#ifdef DOUG_LEA_MALLOC |
1400 |
/* Back to a reasonable maximum of mmap'ed areas. */ |
/* Back to a reasonable maximum of mmap'ed areas. */ |
1401 |
mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
1402 |
#endif |
#endif |
1403 |
|
|
1404 |
b->next_free = &b->first_data; |
b->next_free = &b->first_data; |
1405 |
b->first_data.string = NULL; |
b->first_data.string = NULL; |
1406 |
b->next = large_sblocks; |
b->next = large_sblocks; |
1428 |
|
|
1429 |
old_data = s->data ? SDATA_OF_STRING (s) : NULL; |
old_data = s->data ? SDATA_OF_STRING (s) : NULL; |
1430 |
old_nbytes = GC_STRING_BYTES (s); |
old_nbytes = GC_STRING_BYTES (s); |
1431 |
|
|
1432 |
data = b->next_free; |
data = b->next_free; |
1433 |
data->string = s; |
data->string = s; |
1434 |
s->data = SDATA_DATA (data); |
s->data = SDATA_DATA (data); |
1439 |
s->size_byte = nbytes; |
s->size_byte = nbytes; |
1440 |
s->data[nbytes] = '\0'; |
s->data[nbytes] = '\0'; |
1441 |
b->next_free = (struct sdata *) ((char *) data + needed); |
b->next_free = (struct sdata *) ((char *) data + needed); |
1442 |
|
|
1443 |
/* If S had already data assigned, mark that as free by setting its |
/* If S had already data assigned, mark that as free by setting its |
1444 |
string back-pointer to null, and recording the size of the data |
string back-pointer to null, and recording the size of the data |
1445 |
in it. */ |
in it. */ |
1460 |
{ |
{ |
1461 |
struct string_block *b, *next; |
struct string_block *b, *next; |
1462 |
struct string_block *live_blocks = NULL; |
struct string_block *live_blocks = NULL; |
1463 |
|
|
1464 |
string_free_list = NULL; |
string_free_list = NULL; |
1465 |
total_strings = total_free_strings = 0; |
total_strings = total_free_strings = 0; |
1466 |
total_string_size = 0; |
total_string_size = 0; |
1484 |
{ |
{ |
1485 |
/* String is live; unmark it and its intervals. */ |
/* String is live; unmark it and its intervals. */ |
1486 |
UNMARK_STRING (s); |
UNMARK_STRING (s); |
1487 |
|
|
1488 |
if (!NULL_INTERVAL_P (s->intervals)) |
if (!NULL_INTERVAL_P (s->intervals)) |
1489 |
UNMARK_BALANCE_INTERVALS (s->intervals); |
UNMARK_BALANCE_INTERVALS (s->intervals); |
1490 |
|
|
1556 |
{ |
{ |
1557 |
struct sblock *b, *next; |
struct sblock *b, *next; |
1558 |
struct sblock *live_blocks = NULL; |
struct sblock *live_blocks = NULL; |
1559 |
|
|
1560 |
for (b = large_sblocks; b; b = next) |
for (b = large_sblocks; b; b = next) |
1561 |
{ |
{ |
1562 |
next = b->next; |
next = b->next; |
1597 |
{ |
{ |
1598 |
end = b->next_free; |
end = b->next_free; |
1599 |
xassert ((char *) end <= (char *) b + SBLOCK_SIZE); |
xassert ((char *) end <= (char *) b + SBLOCK_SIZE); |
1600 |
|
|
1601 |
for (from = &b->first_data; from < end; from = from_end) |
for (from = &b->first_data; from < end; from = from_end) |
1602 |
{ |
{ |
1603 |
/* Compute the next FROM here because copying below may |
/* Compute the next FROM here because copying below may |
1611 |
&& GC_STRING_BYTES (from->string) != SDATA_NBYTES (from)) |
&& GC_STRING_BYTES (from->string) != SDATA_NBYTES (from)) |
1612 |
abort (); |
abort (); |
1613 |
#endif /* GC_CHECK_STRING_BYTES */ |
#endif /* GC_CHECK_STRING_BYTES */ |
1614 |
|
|
1615 |
if (from->string) |
if (from->string) |
1616 |
nbytes = GC_STRING_BYTES (from->string); |
nbytes = GC_STRING_BYTES (from->string); |
1617 |
else |
else |
1618 |
nbytes = SDATA_NBYTES (from); |
nbytes = SDATA_NBYTES (from); |
1619 |
|
|
1620 |
nbytes = SDATA_SIZE (nbytes); |
nbytes = SDATA_SIZE (nbytes); |
1621 |
from_end = (struct sdata *) ((char *) from + nbytes); |
from_end = (struct sdata *) ((char *) from + nbytes); |
1622 |
|
|
1623 |
/* FROM->string non-null means it's alive. Copy its data. */ |
/* FROM->string non-null means it's alive. Copy its data. */ |
1624 |
if (from->string) |
if (from->string) |
1625 |
{ |
{ |
1633 |
to = &tb->first_data; |
to = &tb->first_data; |
1634 |
to_end = (struct sdata *) ((char *) to + nbytes); |
to_end = (struct sdata *) ((char *) to + nbytes); |
1635 |
} |
} |
1636 |
|
|
1637 |
/* Copy, and update the string's `data' pointer. */ |
/* Copy, and update the string's `data' pointer. */ |
1638 |
if (from != to) |
if (from != to) |
1639 |
{ |
{ |
1700 |
p += len; |
p += len; |
1701 |
} |
} |
1702 |
} |
} |
1703 |
|
|
1704 |
*p = 0; |
*p = 0; |
1705 |
return val; |
return val; |
1706 |
} |
} |
1728 |
slot `size' of the struct Lisp_Bool_Vector. */ |
slot `size' of the struct Lisp_Bool_Vector. */ |
1729 |
val = Fmake_vector (make_number (length_in_elts + 1), Qnil); |
val = Fmake_vector (make_number (length_in_elts + 1), Qnil); |
1730 |
p = XBOOL_VECTOR (val); |
p = XBOOL_VECTOR (val); |
1731 |
|
|
1732 |
/* Get rid of any bits that would cause confusion. */ |
/* Get rid of any bits that would cause confusion. */ |
1733 |
p->vector_size = 0; |
p->vector_size = 0; |
1734 |
XSETBOOL_VECTOR (val, p); |
XSETBOOL_VECTOR (val, p); |
1735 |
p->size = XFASTINT (length); |
p->size = XFASTINT (length); |
1736 |
|
|
1737 |
real_init = (NILP (init) ? 0 : -1); |
real_init = (NILP (init) ? 0 : -1); |
1738 |
for (i = 0; i < length_in_chars ; i++) |
for (i = 0; i < length_in_chars ; i++) |
1739 |
p->data[i] = real_init; |
p->data[i] = real_init; |
1740 |
|
|
1741 |
/* Clear the extraneous bits in the last byte. */ |
/* Clear the extraneous bits in the last byte. */ |
1742 |
if (XINT (length) != length_in_chars * BITS_PER_CHAR) |
if (XINT (length) != length_in_chars * BITS_PER_CHAR) |
1743 |
XBOOL_VECTOR (val)->data[length_in_chars - 1] |
XBOOL_VECTOR (val)->data[length_in_chars - 1] |
1982 |
} |
} |
1983 |
XSETFLOAT (val, &float_block->floats[float_block_index++]); |
XSETFLOAT (val, &float_block->floats[float_block_index++]); |
1984 |
} |
} |
1985 |
|
|
1986 |
XFLOAT_DATA (val) = float_value; |
XFLOAT_DATA (val) = float_value; |
1987 |
XSETFASTINT (XFLOAT (val)->type, 0); /* bug chasing -wsr */ |
XSETFASTINT (XFLOAT (val)->type, 0); /* bug chasing -wsr */ |
1988 |
consing_since_gc += sizeof (struct Lisp_Float); |
consing_since_gc += sizeof (struct Lisp_Float); |
2089 |
} |
} |
2090 |
XSETCONS (val, &cons_block->conses[cons_block_index++]); |
XSETCONS (val, &cons_block->conses[cons_block_index++]); |
2091 |
} |
} |
2092 |
|
|
2093 |
XSETCAR (val, car); |
XSETCAR (val, car); |
2094 |
XSETCDR (val, cdr); |
XSETCDR (val, cdr); |
2095 |
consing_since_gc += sizeof (struct Lisp_Cons); |
consing_since_gc += sizeof (struct Lisp_Cons); |
2174 |
{ |
{ |
2175 |
val = Fcons (init, val); |
val = Fcons (init, val); |
2176 |
--size; |
--size; |
2177 |
|
|
2178 |
if (size > 0) |
if (size > 0) |
2179 |
{ |
{ |
2180 |
val = Fcons (init, val); |
val = Fcons (init, val); |
2181 |
--size; |
--size; |
2182 |
|
|
2183 |
if (size > 0) |
if (size > 0) |
2184 |
{ |
{ |
2185 |
val = Fcons (init, val); |
val = Fcons (init, val); |
2186 |
--size; |
--size; |
2187 |
|
|
2188 |
if (size > 0) |
if (size > 0) |
2189 |
{ |
{ |
2190 |
val = Fcons (init, val); |
val = Fcons (init, val); |
2196 |
|
|
2197 |
QUIT; |
QUIT; |
2198 |
} |
} |
2199 |
|
|
2200 |
return val; |
return val; |
2201 |
} |
} |
2202 |
|
|
2232 |
a dumped Emacs. */ |
a dumped Emacs. */ |
2233 |
mallopt (M_MMAP_MAX, 0); |
mallopt (M_MMAP_MAX, 0); |
2234 |
#endif |
#endif |
2235 |
|
|
2236 |
nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; |
nbytes = sizeof *p + (len - 1) * sizeof p->contents[0]; |
2237 |
p = (struct Lisp_Vector *) lisp_malloc (nbytes, type); |
p = (struct Lisp_Vector *) lisp_malloc (nbytes, type); |
2238 |
|
|
2239 |
#ifdef DOUG_LEA_MALLOC |
#ifdef DOUG_LEA_MALLOC |
2240 |
/* Back to a reasonable maximum of mmap'ed areas. */ |
/* Back to a reasonable maximum of mmap'ed areas. */ |
2241 |
mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); |
2242 |
#endif |
#endif |
2243 |
|
|
2244 |
VALIDATE_LISP_STORAGE (p, 0); |
VALIDATE_LISP_STORAGE (p, 0); |
2245 |
consing_since_gc += nbytes; |
consing_since_gc += nbytes; |
2246 |
vector_cells_consed += len; |
vector_cells_consed += len; |
2272 |
EMACS_INT len = VECSIZE (struct Lisp_Hash_Table); |
EMACS_INT len = VECSIZE (struct Lisp_Hash_Table); |
2273 |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_HASH_TABLE); |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_HASH_TABLE); |
2274 |
EMACS_INT i; |
EMACS_INT i; |
2275 |
|
|
2276 |
v->size = len; |
v->size = len; |
2277 |
for (i = 0; i < len; ++i) |
for (i = 0; i < len; ++i) |
2278 |
v->contents[i] = Qnil; |
v->contents[i] = Qnil; |
2279 |
|
|
2280 |
return (struct Lisp_Hash_Table *) v; |
return (struct Lisp_Hash_Table *) v; |
2281 |
} |
} |
2282 |
|
|
2287 |
EMACS_INT len = VECSIZE (struct window); |
EMACS_INT len = VECSIZE (struct window); |
2288 |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_WINDOW); |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_WINDOW); |
2289 |
EMACS_INT i; |
EMACS_INT i; |
2290 |
|
|
2291 |
for (i = 0; i < len; ++i) |
for (i = 0; i < len; ++i) |
2292 |
v->contents[i] = Qnil; |
v->contents[i] = Qnil; |
2293 |
v->size = len; |
v->size = len; |
2294 |
|
|
2295 |
return (struct window *) v; |
return (struct window *) v; |
2296 |
} |
} |
2297 |
|
|
2302 |
EMACS_INT len = VECSIZE (struct frame); |
EMACS_INT len = VECSIZE (struct frame); |
2303 |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_FRAME); |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_FRAME); |
2304 |
EMACS_INT i; |
EMACS_INT i; |
2305 |
|
|
2306 |
for (i = 0; i < len; ++i) |
for (i = 0; i < len; ++i) |
2307 |
v->contents[i] = make_number (0); |
v->contents[i] = make_number (0); |
2308 |
v->size = len; |
v->size = len; |
2316 |
EMACS_INT len = VECSIZE (struct Lisp_Process); |
EMACS_INT len = VECSIZE (struct Lisp_Process); |
2317 |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_PROCESS); |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_PROCESS); |
2318 |
EMACS_INT i; |
EMACS_INT i; |
2319 |
|
|
2320 |
for (i = 0; i < len; ++i) |
for (i = 0; i < len; ++i) |
2321 |
v->contents[i] = Qnil; |
v->contents[i] = Qnil; |
2322 |
v->size = len; |
v->size = len; |
2323 |
|
|
2324 |
return (struct Lisp_Process *) v; |
return (struct Lisp_Process *) v; |
2325 |
} |
} |
2326 |
|
|
2331 |
{ |
{ |
2332 |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_VECTOR); |
struct Lisp_Vector *v = allocate_vectorlike (len, MEM_TYPE_VECTOR); |
2333 |
EMACS_INT i; |
EMACS_INT i; |
2334 |
|
|
2335 |
for (i = 0; i < len; ++i) |
for (i = 0; i < len; ++i) |
2336 |
v->contents[i] = Qnil; |
v->contents[i] = Qnil; |
2337 |
v->size = len; |
v->size = len; |
2338 |
|
|
2339 |
return v; |
return v; |
2340 |
} |
} |
2341 |
|
|
2547 |
} |
} |
2548 |
XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index++]); |
XSETSYMBOL (val, &symbol_block->symbols[symbol_block_index++]); |
2549 |
} |
} |
2550 |
|
|
2551 |
p = XSYMBOL (val); |
p = XSYMBOL (val); |
2552 |
p->xname = name; |
p->xname = name; |
2553 |
p->plist = Qnil; |
p->plist = Qnil; |
2628 |
} |
} |
2629 |
XSETMISC (val, &marker_block->markers[marker_block_index++]); |
XSETMISC (val, &marker_block->markers[marker_block_index++]); |
2630 |
} |
} |
2631 |
|
|
2632 |
consing_since_gc += sizeof (union Lisp_Misc); |
consing_since_gc += sizeof (union Lisp_Misc); |
2633 |
misc_objects_consed++; |
misc_objects_consed++; |
2634 |
return val; |
return val; |
2713 |
characters, so we can make a string. */ |
characters, so we can make a string. */ |
2714 |
{ |
{ |
2715 |
Lisp_Object result; |
Lisp_Object result; |
2716 |
|
|
2717 |
result = Fmake_string (make_number (nargs), make_number (0)); |
result = Fmake_string (make_number (nargs), make_number (0)); |
2718 |
for (i = 0; i < nargs; i++) |
for (i = 0; i < nargs; i++) |
2719 |
{ |
{ |
2722 |
if (XINT (args[i]) & CHAR_META) |
if (XINT (args[i]) & CHAR_META) |
2723 |
SSET (result, i, SREF (result, i) | 0x80); |
SSET (result, i, SREF (result, i) | 0x80); |
2724 |
} |
} |
2725 |
|
|
2726 |
return result; |
return result; |
2727 |
} |
} |
2728 |
} |
} |
2805 |
parent = NULL; |
parent = NULL; |
2806 |
|
|
2807 |
#if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS |
#if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS |
2808 |
|
|
2809 |
while (c != MEM_NIL) |
while (c != MEM_NIL) |
2810 |
{ |
{ |
2811 |
if (start >= c->start && start < c->end) |
if (start >= c->start && start < c->end) |
2813 |
parent = c; |
parent = c; |
2814 |
c = start < c->start ? c->left : c->right; |
c = start < c->start ? c->left : c->right; |
2815 |
} |
} |
2816 |
|
|
2817 |
#else /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ |
#else /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ |
2818 |
|
|
2819 |
while (c != MEM_NIL) |
while (c != MEM_NIL) |
2820 |
{ |
{ |
2821 |
parent = c; |
parent = c; |
2822 |
c = start < c->start ? c->left : c->right; |
c = start < c->start ? c->left : c->right; |
2823 |
} |
} |
2824 |
|
|
2825 |
#endif /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ |
#endif /* GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS */ |
2826 |
|
|
2827 |
/* Create a new node. */ |
/* Create a new node. */ |
2847 |
else |
else |
2848 |
parent->right = x; |
parent->right = x; |
2849 |
} |
} |
2850 |
else |
else |
2851 |
mem_root = x; |
mem_root = x; |
2852 |
|
|
2853 |
/* Re-establish red-black tree properties. */ |
/* Re-establish red-black tree properties. */ |
2868 |
{ |
{ |
2869 |
/* X is red and its parent is red. This is a violation of |
/* X is red and its parent is red. This is a violation of |
2870 |
red-black tree property #3. */ |
red-black tree property #3. */ |
2871 |
|
|
2872 |
if (x->parent == x->parent->parent->left) |
if (x->parent == x->parent->parent->left) |
2873 |
{ |
{ |
2874 |
/* We're on the left side of our grandparent, and Y is our |
/* We're on the left side of our grandparent, and Y is our |
2875 |
"uncle". */ |
"uncle". */ |
2876 |
struct mem_node *y = x->parent->parent->right; |
struct mem_node *y = x->parent->parent->right; |
2877 |
|
|
2878 |
if (y->color == MEM_RED) |
if (y->color == MEM_RED) |
2879 |
{ |
{ |
2880 |
/* Uncle and parent are red but should be black because |
/* Uncle and parent are red but should be black because |
2904 |
{ |
{ |
2905 |
/* This is the symmetrical case of above. */ |
/* This is the symmetrical case of above. */ |
2906 |
struct mem_node *y = x->parent->parent->left; |
struct mem_node *y = x->parent->parent->left; |
2907 |
|
|
2908 |
if (y->color == MEM_RED) |
if (y->color == MEM_RED) |
2909 |
{ |
{ |
2910 |
x->parent->color = MEM_BLACK; |
x->parent->color = MEM_BLACK; |
2919 |
x = x->parent; |
x = x->parent; |
2920 |
mem_rotate_right (x); |
mem_rotate_right (x); |
2921 |
} |
} |
2922 |
|
|
2923 |
x->parent->color = MEM_BLACK; |
x->parent->color = MEM_BLACK; |
2924 |
x->parent->parent->color = MEM_RED; |
x->parent->parent->color = MEM_RED; |
2925 |
mem_rotate_left (x->parent->parent); |
mem_rotate_left (x->parent->parent); |
2933 |
} |
} |
2934 |
|
|
2935 |
|
|
2936 |
/* (x) (y) |
/* (x) (y) |
2937 |
/ \ / \ |
/ \ / \ |
2938 |
a (y) ===> (x) c |
a (y) ===> (x) c |
2939 |
/ \ / \ |
/ \ / \ |
2940 |
b c a b */ |
b c a b */ |
2973 |
} |
} |
2974 |
|
|
2975 |
|
|
2976 |
/* (x) (Y) |
/* (x) (Y) |
2977 |
/ \ / \ |
/ \ / \ |
2978 |
(y) c ===> a (x) |
(y) c ===> a (x) |
2979 |
/ \ / \ |
/ \ / \ |
2980 |
a b b c */ |
a b b c */ |
2981 |
|
|
2982 |
static void |
static void |
2988 |
x->left = y->right; |
x->left = y->right; |
2989 |
if (y->right != MEM_NIL) |
if (y->right != MEM_NIL) |
2990 |
y->right->parent = x; |
y->right->parent = x; |
2991 |
|
|
2992 |
if (y != MEM_NIL) |
if (y != MEM_NIL) |
2993 |
y->parent = x->parent; |
y->parent = x->parent; |
2994 |
if (x->parent) |
if (x->parent) |
3000 |
} |
} |
3001 |
else |
else |
3002 |
mem_root = y; |
mem_root = y; |
3003 |
|
|
3004 |
y->right = x; |
y->right = x; |
3005 |
if (x != MEM_NIL) |
if (x != MEM_NIL) |
3006 |
x->parent = y; |
x->parent = y; |
3049 |
z->end = y->end; |
z->end = y->end; |
3050 |
z->type = y->type; |
z->type = y->type; |
3051 |
} |
} |
3052 |
|
|
3053 |
if (y->color == MEM_BLACK) |
if (y->color == MEM_BLACK) |
3054 |
mem_delete_fixup (x); |
mem_delete_fixup (x); |
3055 |
|
|
3073 |
if (x == x->parent->left) |
if (x == x->parent->left) |
3074 |
{ |
{ |
3075 |
struct mem_node *w = x->parent->right; |
struct mem_node *w = x->parent->right; |
3076 |
|
|
3077 |
if (w->color == MEM_RED) |
if (w->color == MEM_RED) |
3078 |
{ |
{ |
3079 |
w->color = MEM_BLACK; |
w->color = MEM_BLACK; |
3081 |
mem_rotate_left (x->parent); |
mem_rotate_left (x->parent); |
3082 |
w = x->parent->right; |
w = x->parent->right; |
3083 |
} |
} |
3084 |
|
|
3085 |
if (w->left->color == MEM_BLACK && w->right->color == MEM_BLACK) |
if (w->left->color == MEM_BLACK && w->right->color == MEM_BLACK) |
3086 |
{ |
{ |
3087 |
w->color = MEM_RED; |
w->color = MEM_RED; |
3106 |
else |
else |
3107 |
{ |
{ |
3108 |
struct mem_node *w = x->parent->left; |
struct mem_node *w = x->parent->left; |
3109 |
|
|
3110 |
if (w->color == MEM_RED) |
if (w->color == MEM_RED) |
3111 |
{ |
{ |
3112 |
w->color = MEM_BLACK; |
w->color = MEM_BLACK; |
3114 |
mem_rotate_right (x->parent); |
mem_rotate_right (x->parent); |
3115 |
w = x->parent->left; |
w = x->parent->left; |
3116 |
} |
} |
3117 |
|
|
3118 |
if (w->right->color == MEM_BLACK && w->left->color == MEM_BLACK) |
if (w->right->color == MEM_BLACK && w->left->color == MEM_BLACK) |
3119 |
{ |
{ |
3120 |
w->color = MEM_RED; |
w->color = MEM_RED; |
3129 |
mem_rotate_left (w); |
mem_rotate_left (w); |
3130 |
w = x->parent->left; |
w = x->parent->left; |
3131 |
} |
} |
3132 |
|
|
3133 |
w->color = x->parent->color; |
w->color = x->parent->color; |
3134 |
x->parent->color = MEM_BLACK; |
x->parent->color = MEM_BLACK; |
3135 |
w->left->color = MEM_BLACK; |
w->left->color = MEM_BLACK; |
3138 |
} |
} |
3139 |
} |
} |
3140 |
} |
} |
3141 |
|
|
3142 |
x->color = MEM_BLACK; |
x->color = MEM_BLACK; |
3143 |
} |
} |
3144 |
|
|
3206 |
{ |
{ |
3207 |
struct symbol_block *b = (struct symbol_block *) m->start; |
struct symbol_block *b = (struct symbol_block *) m->start; |
3208 |
int offset = (char *) p - (char *) &b->symbols[0]; |
int offset = (char *) p - (char *) &b->symbols[0]; |
3209 |
|
|
3210 |
/* P must point to the start of a Lisp_Symbol, not be |
/* P must point to the start of a Lisp_Symbol, not be |
3211 |
one of the unused cells in the current symbol block, |
one of the unused cells in the current symbol block, |
3212 |
and not be on the free-list. */ |
and not be on the free-list. */ |
3233 |
{ |
{ |
3234 |
struct float_block *b = (struct float_block *) m->start; |
struct float_block *b = (struct float_block *) m->start; |
3235 |
int offset = (char *) p - (char *) &b->floats[0]; |
int offset = (char *) p - (char *) &b->floats[0]; |
3236 |
|
|
3237 |
/* P must point to the start of a Lisp_Float, not be |
/* P must point to the start of a Lisp_Float, not be |
3238 |
one of the unused cells in the current float block, |
one of the unused cells in the current float block, |
3239 |
and not be on the free-list. */ |
and not be on the free-list. */ |
3260 |
{ |
{ |
3261 |
struct marker_block *b = (struct marker_block *) m->start; |
struct marker_block *b = (struct marker_block *) m->start; |
3262 |
int offset = (char *) p - (char *) &b->markers[0]; |
int offset = (char *) p - (char *) &b->markers[0]; |
3263 |
|
|
3264 |
/* P must point to the start of a Lisp_Misc, not be |
/* P must point to the start of a Lisp_Misc, not be |
3265 |
one of the unused cells in the current misc block, |
one of the unused cells in the current misc block, |
3266 |
and not be on the free-list. */ |
and not be on the free-list. */ |
3366 |
{ |
{ |
3367 |
void *po = (void *) XPNTR (obj); |
void *po = (void *) XPNTR (obj); |
3368 |
struct mem_node *m = mem_find (po); |
struct mem_node *m = mem_find (po); |
3369 |
|
|
3370 |
if (m != MEM_NIL) |
if (m != MEM_NIL) |
3371 |
{ |
{ |
3372 |
int mark_p = 0; |
int mark_p = 0; |
3412 |
case Lisp_Misc_Marker: |
case Lisp_Misc_Marker: |
3413 |
mark_p = !XMARKBIT (XMARKER (obj)->chain); |
mark_p = !XMARKBIT (XMARKER (obj)->chain); |
3414 |
break; |
break; |
3415 |
|
|
3416 |
case Lisp_Misc_Buffer_Local_Value: |
case Lisp_Misc_Buffer_Local_Value: |
3417 |
case Lisp_Misc_Some_Buffer_Local_Value: |
case Lisp_Misc_Some_Buffer_Local_Value: |
3418 |
mark_p = !XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); |
mark_p = !XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); |
3419 |
break; |
break; |
3420 |
|
|
3421 |
case Lisp_Misc_Overlay: |
case Lisp_Misc_Overlay: |
3422 |
mark_p = !XMARKBIT (XOVERLAY (obj)->plist); |
mark_p = !XMARKBIT (XOVERLAY (obj)->plist); |
3423 |
break; |
break; |
3456 |
assume that Lisp data is aligned on even addresses. */ |
assume that Lisp data is aligned on even addresses. */ |
3457 |
if ((EMACS_INT) p & 1) |
if ((EMACS_INT) p & 1) |
3458 |
return; |
return; |
3459 |
|
|
3460 |
m = mem_find (p); |
m = mem_find (p); |
3461 |
if (m != MEM_NIL) |
if (m != MEM_NIL) |
3462 |
{ |
{ |
3463 |
Lisp_Object obj = Qnil; |
Lisp_Object obj = Qnil; |
3464 |
|
|
3465 |
switch (m->type) |
switch (m->type) |
3466 |
{ |
{ |
3467 |
case MEM_TYPE_NON_LISP: |
case MEM_TYPE_NON_LISP: |
3468 |
/* Nothing to do; not a pointer to Lisp memory. */ |
/* Nothing to do; not a pointer to Lisp memory. */ |
3469 |
break; |
break; |
3470 |
|
|
3471 |
case MEM_TYPE_BUFFER: |
case MEM_TYPE_BUFFER: |
3472 |
if (live_buffer_p (m, p) |
if (live_buffer_p (m, p) |
3473 |
&& !XMARKBIT (((struct buffer *) p)->name)) |
&& !XMARKBIT (((struct buffer *) p)->name)) |
3474 |
XSETVECTOR (obj, p); |
XSETVECTOR (obj, p); |
3475 |
break; |
break; |
3476 |
|
|
3477 |
case MEM_TYPE_CONS: |
case MEM_TYPE_CONS: |
3478 |
if (live_cons_p (m, p) |
if (live_cons_p (m, p) |
3479 |
&& !XMARKBIT (((struct Lisp_Cons *) p)->car)) |
&& !XMARKBIT (((struct Lisp_Cons *) p)->car)) |
3480 |
XSETCONS (obj, p); |
XSETCONS (obj, p); |
3481 |
break; |
break; |
3482 |
|
|
3483 |
case MEM_TYPE_STRING: |
case MEM_TYPE_STRING: |
3484 |
if (live_string_p (m, p) |
if (live_string_p (m, p) |
3485 |
&& !STRING_MARKED_P ((struct Lisp_String *) p)) |
&& !STRING_MARKED_P ((struct Lisp_String *) p)) |
3491 |
{ |
{ |
3492 |
Lisp_Object tem; |
Lisp_Object tem; |
3493 |
XSETMISC (tem, p); |
XSETMISC (tem, p); |
3494 |
|
|
3495 |
switch (XMISCTYPE (tem)) |
switch (XMISCTYPE (tem)) |
3496 |
{ |
{ |
3497 |
case Lisp_Misc_Marker: |
case Lisp_Misc_Marker: |
3498 |
if (!XMARKBIT (XMARKER (tem)->chain)) |
if (!XMARKBIT (XMARKER (tem)->chain)) |
3499 |
obj = tem; |
obj = tem; |
3500 |
break; |
break; |
3501 |
|
|
3502 |
case Lisp_Misc_Buffer_Local_Value: |
case Lisp_Misc_Buffer_Local_Value: |
3503 |
case Lisp_Misc_Some_Buffer_Local_Value: |
case Lisp_Misc_Some_Buffer_Local_Value: |
3504 |
if (!XMARKBIT (XBUFFER_LOCAL_VALUE (tem)->realvalue)) |
if (!XMARKBIT (XBUFFER_LOCAL_VALUE (tem)->realvalue)) |
3505 |
obj = tem; |
obj = tem; |
3506 |
break; |
break; |
3507 |
|
|
3508 |
case Lisp_Misc_Overlay: |
case Lisp_Misc_Overlay: |
3509 |
if (!XMARKBIT (XOVERLAY (tem)->plist)) |
if (!XMARKBIT (XOVERLAY (tem)->plist)) |
3510 |
obj = tem; |
obj = tem; |
3512 |
} |
} |
3513 |
} |
} |
3514 |
break; |
break; |
3515 |
|
|
3516 |
case MEM_TYPE_SYMBOL: |
case MEM_TYPE_SYMBOL: |
3517 |
if (live_symbol_p (m, p) |
if (live_symbol_p (m, p) |
3518 |
&& !XMARKBIT (((struct Lisp_Symbol *) p)->plist)) |
&& !XMARKBIT (((struct Lisp_Symbol *) p)->plist)) |
3519 |
XSETSYMBOL (obj, p); |
XSETSYMBOL (obj, p); |
3520 |
break; |
break; |
3521 |
|
|
3522 |
case MEM_TYPE_FLOAT: |
case MEM_TYPE_FLOAT: |
3523 |
if (live_float_p (m, p) |
if (live_float_p (m, p) |
3524 |
&& !XMARKBIT (((struct Lisp_Float *) p)->type)) |
&& !XMARKBIT (((struct Lisp_Float *) p)->type)) |
3525 |
XSETFLOAT (obj, p); |
XSETFLOAT (obj, p); |
3526 |
break; |
break; |
3527 |
|
|
3528 |
case MEM_TYPE_VECTOR: |
case MEM_TYPE_VECTOR: |
3529 |
case MEM_TYPE_PROCESS: |
case MEM_TYPE_PROCESS: |
3530 |
case MEM_TYPE_HASH_TABLE: |
case MEM_TYPE_HASH_TABLE: |
3552 |
|
|
3553 |
/* Mark Lisp objects referenced from the address range START..END. */ |
/* Mark Lisp objects referenced from the address range START..END. */ |
3554 |
|
|
3555 |
static void |
static void |
3556 |
mark_memory (start, end) |
mark_memory (start, end) |
3557 |
void *start, *end; |
void *start, *end; |
3558 |
{ |
{ |
3593 |
Here, `obj' isn't really used, and the compiler optimizes it |
Here, `obj' isn't really used, and the compiler optimizes it |
3594 |
away. The only reference to the life string is through the |
away. The only reference to the life string is through the |
3595 |
pointer `s'. */ |
pointer `s'. */ |
3596 |
|
|
3597 |
for (pp = (void **) start; (void *) pp < end; ++pp) |
for (pp = (void **) start; (void *) pp < end; ++pp) |
3598 |
mark_maybe_pointer (*pp); |
mark_maybe_pointer (*pp); |
3599 |
} |
} |
3783 |
#ifdef sparc |
#ifdef sparc |
3784 |
asm ("ta 3"); |
asm ("ta 3"); |
3785 |
#endif |
#endif |
3786 |
|
|
3787 |
/* Save registers that we need to see on the stack. We need to see |
/* Save registers that we need to see on the stack. We need to see |
3788 |
registers used to hold register variables and registers used to |
registers used to hold register variables and registers used to |
3789 |
pass parameters. */ |
pass parameters. */ |
3790 |
#ifdef GC_SAVE_REGISTERS_ON_STACK |
#ifdef GC_SAVE_REGISTERS_ON_STACK |
3791 |
GC_SAVE_REGISTERS_ON_STACK (end); |
GC_SAVE_REGISTERS_ON_STACK (end); |
3792 |
#else /* not GC_SAVE_REGISTERS_ON_STACK */ |
#else /* not GC_SAVE_REGISTERS_ON_STACK */ |
3793 |
|
|
3794 |
#ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that |
#ifndef GC_SETJMP_WORKS /* If it hasn't been checked yet that |
3795 |
setjmp will definitely work, test it |
setjmp will definitely work, test it |
3796 |
and print a message with the result |
and print a message with the result |
3801 |
test_setjmp (); |
test_setjmp (); |
3802 |
} |
} |
3803 |
#endif /* GC_SETJMP_WORKS */ |
#endif /* GC_SETJMP_WORKS */ |
3804 |
|
|
3805 |
setjmp (j); |
setjmp (j); |
3806 |
end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; |
end = stack_grows_down_p ? (char *) &j + sizeof j : (char *) &j; |
3807 |
#endif /* not GC_SAVE_REGISTERS_ON_STACK */ |
#endif /* not GC_SAVE_REGISTERS_ON_STACK */ |
4146 |
Qt tends to return NULL, which effectively turns undo back on. |
Qt tends to return NULL, which effectively turns undo back on. |
4147 |
So don't call truncate_undo_list if undo_list is Qt. */ |
So don't call truncate_undo_list if undo_list is Qt. */ |
4148 |
if (! EQ (nextb->undo_list, Qt)) |
if (! EQ (nextb->undo_list, Qt)) |
4149 |
nextb->undo_list |
nextb->undo_list |
4150 |
= truncate_undo_list (nextb->undo_list, undo_limit, |
= truncate_undo_list (nextb->undo_list, undo_limit, |
4151 |
undo_strong_limit); |
undo_strong_limit); |
4152 |
|
|
4199 |
XMARK (tail->var[i]); |
XMARK (tail->var[i]); |
4200 |
} |
} |
4201 |
#endif |
#endif |
4202 |
|
|
4203 |
mark_byte_stack (); |
mark_byte_stack (); |
4204 |
for (bind = specpdl; bind != specpdl_ptr; bind++) |
for (bind = specpdl; bind != specpdl_ptr; bind++) |
4205 |
{ |
{ |
4210 |
{ |
{ |
4211 |
mark_object (&catch->tag); |
mark_object (&catch->tag); |
4212 |
mark_object (&catch->val); |
mark_object (&catch->val); |
4213 |
} |
} |
4214 |
for (handler = handlerlist; handler; handler = handler->next) |
for (handler = handlerlist; handler; handler = handler->next) |
4215 |
{ |
{ |
4216 |
mark_object (&handler->handler); |
mark_object (&handler->handler); |
4217 |
mark_object (&handler->var); |
mark_object (&handler->var); |
4218 |
} |
} |
4219 |
for (backlist = backtrace_list; backlist; backlist = backlist->next) |
for (backlist = backtrace_list; backlist; backlist = backlist->next) |
4220 |
{ |
{ |
4221 |
if (!XMARKBIT (*backlist->function)) |
if (!XMARKBIT (*backlist->function)) |
4233 |
mark_object (&backlist->args[i]); |
mark_object (&backlist->args[i]); |
4234 |
XMARK (backlist->args[i]); |
XMARK (backlist->args[i]); |
4235 |
} |
} |
4236 |
} |
} |
4237 |
mark_kboards (); |
mark_kboards (); |
4238 |
|
|
4239 |
/* Look thru every buffer's undo list |
/* Look thru every buffer's undo list |
4300 |
for (i = 0; i < tail->nvars; i++) |
for (i = 0; i < tail->nvars; i++) |
4301 |
XUNMARK (tail->var[i]); |
XUNMARK (tail->var[i]); |
4302 |
#endif |
#endif |
4303 |
|
|
4304 |
unmark_byte_stack (); |
unmark_byte_stack (); |
4305 |
for (backlist = backtrace_list; backlist; backlist = backlist->next) |
for (backlist = backtrace_list; backlist; backlist = backlist->next) |
4306 |
{ |
{ |
4311 |
i = backlist->nargs - 1; |
i = backlist->nargs - 1; |
4312 |
for (; i >= 0; i--) |
for (; i >= 0; i--) |
4313 |
XUNMARK (backlist->args[i]); |
XUNMARK (backlist->args[i]); |
4314 |
} |
} |
4315 |
XUNMARK (buffer_defaults.name); |
XUNMARK (buffer_defaults.name); |
4316 |
XUNMARK (buffer_local_symbols.name); |
XUNMARK (buffer_local_symbols.name); |
4317 |
|
|
4357 |
{ |
{ |
4358 |
/* Compute average percentage of zombies. */ |
/* Compute average percentage of zombies. */ |
4359 |
double nlive = 0; |
double nlive = 0; |
4360 |
|
|
4361 |
for (i = 0; i < 7; ++i) |
for (i = 0; i < 7; ++i) |
4362 |
if (CONSP (total[i])) |
if (CONSP (total[i])) |
4363 |
nlive += XFASTINT (XCAR (total[i])); |
nlive += XFASTINT (XCAR (total[i])); |
4408 |
{ |
{ |
4409 |
struct glyph *glyph = row->glyphs[area]; |
struct glyph *glyph = row->glyphs[area]; |
4410 |
struct glyph *end_glyph = glyph + row->used[area]; |
struct glyph *end_glyph = glyph + row->used[area]; |
4411 |
|
|
4412 |
for (; glyph < end_glyph; ++glyph) |
for (; glyph < end_glyph; ++glyph) |
4413 |
if (GC_STRINGP (glyph->object) |
if (GC_STRINGP (glyph->object) |
4414 |
&& !STRING_MARKED_P (XSTRING (glyph->object))) |
&& !STRING_MARKED_P (XSTRING (glyph->object))) |
4450 |
struct image *img; |
struct image *img; |
4451 |
{ |
{ |
4452 |
mark_object (&img->spec); |
mark_object (&img->spec); |
4453 |
|
|
4454 |
if (!NILP (img->data.lisp_val)) |
if (!NILP (img->data.lisp_val)) |
4455 |
mark_object (&img->data.lisp_val); |
mark_object (&img->data.lisp_val); |
4456 |
} |
} |
4538 |
CHECK_ALLOCATED (); \ |
CHECK_ALLOCATED (); \ |
4539 |
CHECK_LIVE (LIVEP); \ |
CHECK_LIVE (LIVEP); \ |
4540 |
} while (0) \ |
} while (0) \ |
4541 |
|
|
4542 |
#else /* not GC_CHECK_MARKED_OBJECTS */ |
#else /* not GC_CHECK_MARKED_OBJECTS */ |
4543 |
|
|
4544 |
#define CHECK_ALLOCATED() (void) 0 |
#define CHECK_ALLOCATED() (void) 0 |
4545 |
#define CHECK_LIVE(LIVEP) (void) 0 |
#define CHECK_LIVE(LIVEP) (void) 0 |
4546 |
#define CHECK_ALLOCATED_AND_LIVE(LIVEP) (void) 0 |
#define CHECK_ALLOCATED_AND_LIVE(LIVEP) (void) 0 |
4547 |
|
|
4548 |
#endif /* not GC_CHECK_MARKED_OBJECTS */ |
#endif /* not GC_CHECK_MARKED_OBJECTS */ |
4549 |
|
|
4550 |
switch (SWITCH_ENUM_CAST (XGCTYPE (obj))) |
switch (SWITCH_ENUM_CAST (XGCTYPE (obj))) |
4571 |
&& po != &buffer_local_symbols) |
&& po != &buffer_local_symbols) |
4572 |
abort (); |
abort (); |
4573 |
#endif /* GC_CHECK_MARKED_OBJECTS */ |
#endif /* GC_CHECK_MARKED_OBJECTS */ |
4574 |
|
|
4575 |
if (GC_BUFFERP (obj)) |
if (GC_BUFFERP (obj)) |
4576 |
{ |
{ |
4577 |
if (!XMARKBIT (XBUFFER (obj)->name)) |
if (!XMARKBIT (XBUFFER (obj)->name)) |
4602 |
|
|
4603 |
if (size & ARRAY_MARK_FLAG) |
if (size & ARRAY_MARK_FLAG) |
4604 |
break; /* Already marked */ |
break; /* Already marked */ |
4605 |
|
|
4606 |
CHECK_LIVE (live_vector_p); |
CHECK_LIVE (live_vector_p); |
4607 |
ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ |
4608 |
size &= PSEUDOVECTOR_SIZE_MASK; |
size &= PSEUDOVECTOR_SIZE_MASK; |
4695 |
{ |
{ |
4696 |
struct Lisp_Hash_Table *h = XHASH_TABLE (obj); |
struct Lisp_Hash_Table *h = XHASH_TABLE (obj); |
4697 |
EMACS_INT size = h->size; |
EMACS_INT size = h->size; |
4698 |
|
|
4699 |
/* Stop if already marked. */ |
/* Stop if already marked. */ |
4700 |
if (size & ARRAY_MARK_FLAG) |
if (size & ARRAY_MARK_FLAG) |
4701 |
break; |
break; |
4702 |
|
|
4703 |
/* Mark it. */ |
/* Mark it. */ |
4704 |
CHECK_LIVE (live_vector_p); |
CHECK_LIVE (live_vector_p); |
4705 |
h->size |= ARRAY_MARK_FLAG; |
h->size |= ARRAY_MARK_FLAG; |
4706 |
|
|
4707 |
/* Mark contents. */ |
/* Mark contents. */ |
4708 |
/* Do not mark next_free or next_weak. |
/* Do not mark next_free or next_weak. |
4709 |
Being in the next_weak chain |
Being in the next_weak chain |
4710 |
should not keep the hash table alive. |
should not keep the hash table alive. |
4711 |
No need to mark `count' since it is an integer. */ |
No need to mark `count' since it is an integer. */ |
4712 |
mark_object (&h->test); |
mark_object (&h->test); |
4725 |
mark_object (&h->key_and_value); |
mark_object (&h->key_and_value); |
4726 |
else |
else |
4727 |
XVECTOR (h->key_and_value)->size |= ARRAY_MARK_FLAG; |
XVECTOR (h->key_and_value)->size |= ARRAY_MARK_FLAG; |
4728 |
|
|
4729 |
} |
} |
4730 |
else |
else |
4731 |
{ |
{ |
4759 |
if (!PURE_POINTER_P (XSTRING (ptr->xname))) |
if (!PURE_POINTER_P (XSTRING (ptr->xname))) |
4760 |
MARK_STRING (XSTRING (ptr->xname)); |
MARK_STRING (XSTRING (ptr->xname)); |
4761 |
MARK_INTERVAL_TREE (STRING_INTERVALS (ptr->xname)); |
MARK_INTERVAL_TREE (STRING_INTERVALS (ptr->xname)); |
4762 |
|
|
4763 |
/* Note that we do not mark the obarray of the symbol. |
/* Note that we do not mark the obarray of the symbol. |
4764 |
It is safe not to do so because nothing accesses that |
It is safe not to do so because nothing accesses that |
4765 |
slot except to check whether it is nil. */ |
slot except to check whether it is nil. */ |
4933 |
/* If this is an indirect buffer, mark its base buffer. */ |
/* If this is an indirect buffer, mark its base buffer. */ |
4934 |
if (buffer->base_buffer && !XMARKBIT (buffer->base_buffer->name)) |
if (buffer->base_buffer && !XMARKBIT (buffer->base_buffer->name)) |
4935 |
{ |
{ |
4936 |
XSETBUFFER (base_buffer, buffer->base_buffer); |
XSETBUFFER (base_buffer, buffer->base_buffer); |
4937 |
mark_buffer (base_buffer); |
mark_buffer (base_buffer); |
4938 |
} |
} |
4939 |
} |
} |
4975 |
Lisp_Object obj; |
Lisp_Object obj; |
4976 |
{ |
{ |
4977 |
int survives_p; |
int survives_p; |
4978 |
|
|
4979 |
switch (XGCTYPE (obj)) |
switch (XGCTYPE (obj)) |
4980 |
{ |
{ |
4981 |
case Lisp_Int: |
case Lisp_Int: |
4992 |
case Lisp_Misc_Marker: |
case Lisp_Misc_Marker: |
4993 |
survives_p = XMARKBIT (obj); |
survives_p = XMARKBIT (obj); |
4994 |
break; |
break; |
4995 |
|
|
4996 |
case Lisp_Misc_Buffer_Local_Value: |
case Lisp_Misc_Buffer_Local_Value: |
4997 |
case Lisp_Misc_Some_Buffer_Local_Value: |
case Lisp_Misc_Some_Buffer_Local_Value: |
4998 |
survives_p = XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); |
survives_p = XMARKBIT (XBUFFER_LOCAL_VALUE (obj)->realvalue); |
4999 |
break; |
break; |
5000 |
|
|
5001 |
case Lisp_Misc_Intfwd: |
case Lisp_Misc_Intfwd: |
5002 |
case Lisp_Misc_Boolfwd: |
case Lisp_Misc_Boolfwd: |
5003 |
case Lisp_Misc_Objfwd: |
case Lisp_Misc_Objfwd: |
5005 |
case Lisp_Misc_Kboard_Objfwd: |
case Lisp_Misc_Kboard_Objfwd: |
5006 |
survives_p = 1; |
survives_p = 1; |
5007 |
break; |
break; |
5008 |
|
|
5009 |
case Lisp_Misc_Overlay: |
case Lisp_Misc_Overlay: |
5010 |
survives_p = XMARKBIT (XOVERLAY (obj)->plist); |
survives_p = XMARKBIT (XOVERLAY (obj)->plist); |
5011 |
break; |
break; |
5071 |
register int num_free = 0, num_used = 0; |
register int num_free = 0, num_used = 0; |
5072 |
|
|
5073 |
cons_free_list = 0; |
cons_free_list = 0; |
5074 |
|
|
5075 |
for (cblk = cons_block; cblk; cblk = *cprev) |
for (cblk = cons_block; cblk; cblk = *cprev) |
5076 |
{ |
{ |
5077 |
register int i; |
register int i; |
5121 |
register int num_free = 0, num_used = 0; |
register int num_free = 0, num_used = 0; |
5122 |
|
|
5123 |
float_free_list = 0; |
float_free_list = 0; |
5124 |
|
|
5125 |
for (fblk = float_block; fblk; fblk = *fprev) |
for (fblk = float_block; fblk; fblk = *fprev) |
5126 |
{ |
{ |
5127 |
register int i; |
register int i; |
5221 |
register int num_free = 0, num_used = 0; |
register int num_free = 0, num_used = 0; |
5222 |
|
|
5223 |
symbol_free_list = NULL; |
symbol_free_list = NULL; |
5224 |
|
|
5225 |
for (sblk = symbol_block; sblk; sblk = *sprev) |
for (sblk = symbol_block; sblk; sblk = *sprev) |
5226 |
{ |
{ |
5227 |
int this_free = 0; |
int this_free = 0; |
5234 |
it might be pointed to by pure bytecode which we don't trace, |
it might be pointed to by pure bytecode which we don't trace, |
5235 |
so we conservatively assume that it is live. */ |
so we conservatively assume that it is live. */ |
5236 |
int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); |
int pure_p = PURE_POINTER_P (XSTRING (sym->xname)); |
5237 |
|
|
5238 |
if (!XMARKBIT (sym->plist) && !pure_p) |
if (!XMARKBIT (sym->plist) && !pure_p) |
5239 |
{ |
{ |
5240 |
*(struct Lisp_Symbol **) &sym->value = symbol_free_list; |
*(struct Lisp_Symbol **) &sym->value = symbol_free_list; |
5252 |
XUNMARK (sym->plist); |
XUNMARK (sym->plist); |
5253 |
} |
} |
5254 |
} |
} |
5255 |
|
|
5256 |
lim = SYMBOL_BLOCK_SIZE; |
lim = SYMBOL_BLOCK_SIZE; |
5257 |
/* If this block contains only free symbols and we have already |
/* If this block contains only free symbols and we have already |
5258 |
seen more than two blocks worth of free symbols then deallocate |
seen more than two blocks worth of free symbols then deallocate |
5284 |
register int num_free = 0, num_used = 0; |
register int num_free = 0, num_used = 0; |
5285 |
|
|
5286 |
marker_free_list = 0; |
marker_free_list = 0; |
5287 |
|
|
5288 |
for (mblk = marker_block; mblk; mblk = *mprev) |
for (mblk = marker_block; mblk; mblk = *mprev) |
5289 |
{ |
{ |
5290 |
register int i; |
register int i; |
5414 |
prev = vector, vector = vector->next; |
prev = vector, vector = vector->next; |
5415 |
} |
} |
5416 |
} |
} |
5417 |
|
|
5418 |
#ifdef GC_CHECK_STRING_BYTES |
#ifdef GC_CHECK_STRING_BYTES |
5419 |
if (!noninteractive) |
if (!noninteractive) |
5420 |
check_string_bytes (1); |
check_string_bytes (1); |