* alloc.c (mark_buffer): Simplify. Remove prototype.
(mark_object): Add comment. Reorganize marking of vector-like objects. Use CHECK_LIVE for all vector-like ojects except buffers and subroutines when GC_CHECK_MARKED_OBJECTS is defined. Avoid redundant calls to mark_vectorlike for bool vectors.
This commit is contained in:
parent
6651c01506
commit
cf5c017598
2 changed files with 135 additions and 114 deletions
|
@ -1,3 +1,11 @@
|
|||
2012-07-02 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
||||
* alloc.c (mark_buffer): Simplify. Remove prototype.
|
||||
(mark_object): Add comment. Reorganize marking of vector-like
|
||||
objects. Use CHECK_LIVE for all vector-like ojects except buffers
|
||||
and subroutines when GC_CHECK_MARKED_OBJECTS is defined. Avoid
|
||||
redundant calls to mark_vectorlike for bool vectors.
|
||||
|
||||
2012-06-30 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* nsterm.m (ns_init_paths): Ignore site-lisp if --no-site-lisp.
|
||||
|
@ -58,7 +66,7 @@
|
|||
|
||||
* window.h (struct window): Change type of 'fringes_outside_margins'
|
||||
to bitfield. Fix comment. Adjust users accordingly.
|
||||
(struct window): Change type of 'window_end_bytepos' to ptrdiff_t.
|
||||
(struct window): Change type of 'window_end_bytepos' to ptrdiff_t.
|
||||
Adjust comment.
|
||||
* xdisp.c (try_window_id): Change type of 'first_vpos' and 'vpos'
|
||||
to ptrdiff_t.
|
||||
|
|
239
src/alloc.c
239
src/alloc.c
|
@ -270,7 +270,6 @@ Lisp_Object Qchar_table_extra_slots;
|
|||
|
||||
static Lisp_Object Qpost_gc_hook;
|
||||
|
||||
static void mark_buffer (Lisp_Object);
|
||||
static void mark_terminals (void);
|
||||
static void gc_sweep (void);
|
||||
static Lisp_Object make_pure_vector (ptrdiff_t);
|
||||
|
@ -5787,6 +5786,48 @@ mark_char_table (struct Lisp_Vector *ptr)
|
|||
}
|
||||
}
|
||||
|
||||
/* Mark the pointers in a buffer structure. */
|
||||
|
||||
static void
|
||||
mark_buffer (struct buffer *buffer)
|
||||
{
|
||||
register Lisp_Object *ptr, tmp;
|
||||
|
||||
eassert (!VECTOR_MARKED_P (buffer));
|
||||
VECTOR_MARK (buffer);
|
||||
|
||||
MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
|
||||
|
||||
/* For now, we just don't mark the undo_list. It's done later in
|
||||
a special way just before the sweep phase, and after stripping
|
||||
some of its elements that are not needed any more. */
|
||||
|
||||
if (buffer->overlays_before)
|
||||
{
|
||||
XSETMISC (tmp, buffer->overlays_before);
|
||||
mark_object (tmp);
|
||||
}
|
||||
if (buffer->overlays_after)
|
||||
{
|
||||
XSETMISC (tmp, buffer->overlays_after);
|
||||
mark_object (tmp);
|
||||
}
|
||||
|
||||
/* buffer-local Lisp variables start at `undo_list',
|
||||
tho only the ones from `name' on are GC'd normally. */
|
||||
for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name);
|
||||
ptr <= &PER_BUFFER_VALUE (buffer,
|
||||
PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER));
|
||||
ptr++)
|
||||
mark_object (*ptr);
|
||||
|
||||
/* If this is an indirect buffer, mark its base buffer. */
|
||||
if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer))
|
||||
mark_buffer (buffer->base_buffer);
|
||||
}
|
||||
|
||||
/* Determine type of generic Lisp_Object and mark it accordingly. */
|
||||
|
||||
void
|
||||
mark_object (Lisp_Object arg)
|
||||
{
|
||||
|
@ -5863,77 +5904,88 @@ mark_object (Lisp_Object arg)
|
|||
break;
|
||||
|
||||
case Lisp_Vectorlike:
|
||||
if (VECTOR_MARKED_P (XVECTOR (obj)))
|
||||
break;
|
||||
{
|
||||
register struct Lisp_Vector *ptr = XVECTOR (obj);
|
||||
register ptrdiff_t pvectype;
|
||||
|
||||
if (VECTOR_MARKED_P (ptr))
|
||||
break;
|
||||
|
||||
#ifdef GC_CHECK_MARKED_OBJECTS
|
||||
m = mem_find (po);
|
||||
if (m == MEM_NIL && !SUBRP (obj)
|
||||
&& po != &buffer_defaults
|
||||
&& po != &buffer_local_symbols)
|
||||
abort ();
|
||||
m = mem_find (po);
|
||||
if (m == MEM_NIL && !SUBRP (obj)
|
||||
&& po != &buffer_defaults
|
||||
&& po != &buffer_local_symbols)
|
||||
abort ();
|
||||
#endif /* GC_CHECK_MARKED_OBJECTS */
|
||||
|
||||
if (BUFFERP (obj))
|
||||
{
|
||||
#ifdef GC_CHECK_MARKED_OBJECTS
|
||||
if (po != &buffer_defaults && po != &buffer_local_symbols)
|
||||
{
|
||||
struct buffer *b;
|
||||
for (b = all_buffers; b && b != po; b = b->header.next.buffer)
|
||||
;
|
||||
if (b == NULL)
|
||||
abort ();
|
||||
}
|
||||
#endif /* GC_CHECK_MARKED_OBJECTS */
|
||||
mark_buffer (obj);
|
||||
}
|
||||
else if (SUBRP (obj))
|
||||
break;
|
||||
else if (COMPILEDP (obj))
|
||||
/* We could treat this just like a vector, but it is better to
|
||||
save the COMPILED_CONSTANTS element for last and avoid
|
||||
recursion there. */
|
||||
{
|
||||
register struct Lisp_Vector *ptr = XVECTOR (obj);
|
||||
int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
|
||||
int i;
|
||||
if (ptr->header.size & PSEUDOVECTOR_FLAG)
|
||||
pvectype = ptr->header.size & PVEC_TYPE_MASK;
|
||||
else
|
||||
pvectype = 0;
|
||||
|
||||
#ifdef GC_CHECK_MARKED_OBJECTS
|
||||
if (pvectype != PVEC_SUBR && pvectype != PVEC_BUFFER)
|
||||
CHECK_LIVE (live_vector_p);
|
||||
VECTOR_MARK (ptr); /* Else mark it */
|
||||
for (i = 0; i < size; i++) /* and then mark its elements */
|
||||
{
|
||||
#endif /* GC_CHECK_MARKED_OBJECTS */
|
||||
|
||||
if (pvectype == PVEC_BUFFER)
|
||||
{
|
||||
#ifdef GC_CHECK_MARKED_OBJECTS
|
||||
if (po != &buffer_defaults && po != &buffer_local_symbols)
|
||||
{
|
||||
struct buffer *b = all_buffers;
|
||||
for (; b && b != po; b = b->header.next.buffer)
|
||||
;
|
||||
if (b == NULL)
|
||||
abort ();
|
||||
}
|
||||
#endif /* GC_CHECK_MARKED_OBJECTS */
|
||||
mark_buffer ((struct buffer *) ptr);
|
||||
}
|
||||
|
||||
else if (pvectype == PVEC_COMPILED)
|
||||
/* We could treat this just like a vector, but it is better
|
||||
to save the COMPILED_CONSTANTS element for last and avoid
|
||||
recursion there. */
|
||||
{
|
||||
int size = ptr->header.size & PSEUDOVECTOR_SIZE_MASK;
|
||||
int i;
|
||||
|
||||
VECTOR_MARK (ptr);
|
||||
for (i = 0; i < size; i++)
|
||||
if (i != COMPILED_CONSTANTS)
|
||||
mark_object (ptr->contents[i]);
|
||||
}
|
||||
obj = ptr->contents[COMPILED_CONSTANTS];
|
||||
goto loop;
|
||||
}
|
||||
else if (FRAMEP (obj))
|
||||
obj = ptr->contents[COMPILED_CONSTANTS];
|
||||
goto loop;
|
||||
}
|
||||
|
||||
else if (pvectype == PVEC_FRAME)
|
||||
{
|
||||
mark_vectorlike (ptr);
|
||||
mark_face_cache (((struct frame *) ptr)->face_cache);
|
||||
}
|
||||
|
||||
else if (pvectype == PVEC_WINDOW)
|
||||
{
|
||||
struct window *w = (struct window *) ptr;
|
||||
|
||||
mark_vectorlike (ptr);
|
||||
/* Mark glyphs for leaf windows. Marking window
|
||||
matrices is sufficient because frame matrices
|
||||
use the same glyph memory. */
|
||||
if (NILP (w->hchild) && NILP (w->vchild) && w->current_matrix)
|
||||
{
|
||||
mark_glyph_matrix (w->current_matrix);
|
||||
mark_glyph_matrix (w->desired_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
else if (pvectype == PVEC_HASH_TABLE)
|
||||
{
|
||||
register struct frame *ptr = XFRAME (obj);
|
||||
mark_vectorlike (XVECTOR (obj));
|
||||
mark_face_cache (ptr->face_cache);
|
||||
}
|
||||
else if (WINDOWP (obj))
|
||||
{
|
||||
register struct Lisp_Vector *ptr = XVECTOR (obj);
|
||||
struct window *w = XWINDOW (obj);
|
||||
struct Lisp_Hash_Table *h = (struct Lisp_Hash_Table *) ptr;
|
||||
|
||||
mark_vectorlike (ptr);
|
||||
/* Mark glyphs for leaf windows. Marking window matrices is
|
||||
sufficient because frame matrices use the same glyph
|
||||
memory. */
|
||||
if (NILP (w->hchild)
|
||||
&& NILP (w->vchild)
|
||||
&& w->current_matrix)
|
||||
{
|
||||
mark_glyph_matrix (w->current_matrix);
|
||||
mark_glyph_matrix (w->desired_matrix);
|
||||
}
|
||||
}
|
||||
else if (HASH_TABLE_P (obj))
|
||||
{
|
||||
struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
|
||||
mark_vectorlike ((struct Lisp_Vector *)h);
|
||||
/* If hash table is not weak, mark all keys and values.
|
||||
For weak tables, mark only the vector. */
|
||||
if (NILP (h->weak))
|
||||
|
@ -5941,10 +5993,17 @@ mark_object (Lisp_Object arg)
|
|||
else
|
||||
VECTOR_MARK (XVECTOR (h->key_and_value));
|
||||
}
|
||||
else if (CHAR_TABLE_P (obj))
|
||||
mark_char_table (XVECTOR (obj));
|
||||
else
|
||||
mark_vectorlike (XVECTOR (obj));
|
||||
|
||||
else if (pvectype == PVEC_CHAR_TABLE)
|
||||
mark_char_table (ptr);
|
||||
|
||||
else if (pvectype == PVEC_BOOL_VECTOR)
|
||||
/* No Lisp_Objects to mark in a bool vector. */
|
||||
VECTOR_MARK (ptr);
|
||||
|
||||
else if (pvectype != PVEC_SUBR)
|
||||
mark_vectorlike (ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case Lisp_Symbol:
|
||||
|
@ -6091,52 +6150,6 @@ mark_object (Lisp_Object arg)
|
|||
#undef CHECK_ALLOCATED
|
||||
#undef CHECK_ALLOCATED_AND_LIVE
|
||||
}
|
||||
|
||||
/* Mark the pointers in a buffer structure. */
|
||||
|
||||
static void
|
||||
mark_buffer (Lisp_Object buf)
|
||||
{
|
||||
register struct buffer *buffer = XBUFFER (buf);
|
||||
register Lisp_Object *ptr, tmp;
|
||||
Lisp_Object base_buffer;
|
||||
|
||||
eassert (!VECTOR_MARKED_P (buffer));
|
||||
VECTOR_MARK (buffer);
|
||||
|
||||
MARK_INTERVAL_TREE (BUF_INTERVALS (buffer));
|
||||
|
||||
/* For now, we just don't mark the undo_list. It's done later in
|
||||
a special way just before the sweep phase, and after stripping
|
||||
some of its elements that are not needed any more. */
|
||||
|
||||
if (buffer->overlays_before)
|
||||
{
|
||||
XSETMISC (tmp, buffer->overlays_before);
|
||||
mark_object (tmp);
|
||||
}
|
||||
if (buffer->overlays_after)
|
||||
{
|
||||
XSETMISC (tmp, buffer->overlays_after);
|
||||
mark_object (tmp);
|
||||
}
|
||||
|
||||
/* buffer-local Lisp variables start at `undo_list',
|
||||
tho only the ones from `name' on are GC'd normally. */
|
||||
for (ptr = &buffer->BUFFER_INTERNAL_FIELD (name);
|
||||
ptr <= &PER_BUFFER_VALUE (buffer,
|
||||
PER_BUFFER_VAR_OFFSET (LAST_FIELD_PER_BUFFER));
|
||||
ptr++)
|
||||
mark_object (*ptr);
|
||||
|
||||
/* If this is an indirect buffer, mark its base buffer. */
|
||||
if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer))
|
||||
{
|
||||
XSETBUFFER (base_buffer, buffer->base_buffer);
|
||||
mark_buffer (base_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the Lisp pointers in the terminal objects.
|
||||
Called by Fgarbage_collect. */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue