Mercurial > emacs
changeset 85019:21a145f18ed2
(allocate_pseudovector): New fun.
(ALLOCATE_PSEUDOVECTOR): New macro.
(allocate_window, allocate_terminal, allocate_frame)
(allocate_process): Use it.
(mark_vectorlike): New function.
(mark_object) <FRAMEP, WINDOWP, BOOL_VECTOR_P, VECTORP>: Use it.
(mark_terminals): Use it.
(Fmake_bool_vector, Fmake_char_table, make_sub_char_table)
(Fmake_byte_code): Use XSETPVECTYPE.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Tue, 02 Oct 2007 21:16:53 +0000 |
parents | 3389713480bb |
children | db98fea45dfd |
files | src/ChangeLog src/alloc.c |
diffstat | 2 files changed, 112 insertions(+), 132 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Tue Oct 02 21:09:17 2007 +0000 +++ b/src/ChangeLog Tue Oct 02 21:16:53 2007 +0000 @@ -1,7 +1,34 @@ 2007-10-02 Stefan Monnier <monnier@iro.umontreal.ca> + * alloc.c (allocate_pseudovector): New fun. + (ALLOCATE_PSEUDOVECTOR): New macro. + (allocate_window, allocate_terminal, allocate_frame) + (allocate_process): Use it. + (mark_vectorlike): New function. + (mark_object) <FRAMEP, WINDOWP, BOOL_VECTOR_P, VECTORP>: Use it. + (mark_terminals): Use it. + (Fmake_bool_vector, Fmake_char_table, make_sub_char_table) + (Fmake_byte_code): Use XSETPVECTYPE. + + * frame.c (Fframe_parameters): Minor simplification. + + * insdel.c (adjust_markers_for_insert): Generalize assertion checks. + + * marker.c (Fmarker_buffer): Make test for odd case into a failure. + + * buffer.c (Fget_buffer_create, init_buffer_once): + * lread.c (defsubr): + * window.c (Fcurrent_window_configuration): Use XSETPVECTYPE. + + * lisp.h (ARRAY_MARK_FLAG, PSEUDOVECTOR_FLAG): Don't let them be + defined differently in the m/*.h files. + (XCHAR_TABLE, XBOOL_VECTOR): Add assertion checking. + (XSETPVECTYPE): New macro. + (XSETPSEUDOVECTOR): Use it. + * buffer.c (syms_of_buffer) <local-abbrev-table>: Move from abbrev.c. (DEFVAR_PER_BUFFER, defvar_per_buffer): Move from lisp.h and lread.c. + * lisp.h (defvar_per_buffer, DEFVAR_PER_BUFFER): * lread.c (defvar_per_buffer): * abbrev.c (syms_of_abbrev) <local-abbrev-tabl>: Move to buffer.c.
--- a/src/alloc.c Tue Oct 02 21:09:17 2007 +0000 +++ b/src/alloc.c Tue Oct 02 21:16:53 2007 +0000 @@ -2338,11 +2338,12 @@ /* We must allocate one more elements than LENGTH_IN_ELTS for the slot `size' of the struct Lisp_Bool_Vector. */ val = Fmake_vector (make_number (length_in_elts + 1), Qnil); - p = XBOOL_VECTOR (val); /* Get rid of any bits that would cause confusion. */ - p->vector_size = 0; - XSETBOOL_VECTOR (val, p); + XVECTOR (val)->size = 0; /* No Lisp_Object to trace in there. */ + XSETPVECTYPE (XVECTOR (val), PVEC_BOOL_VECTOR); + + p = XBOOL_VECTOR (val); p->size = XFASTINT (length); real_init = (NILP (init) ? 0 : -1); @@ -2351,7 +2352,7 @@ /* Clear the extraneous bits in the last byte. */ if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) - XBOOL_VECTOR (val)->data[length_in_chars - 1] + p->data[length_in_chars - 1] &= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; return val; @@ -2963,6 +2964,27 @@ /* Allocate other vector-like structures. */ +static struct Lisp_Vector * +allocate_pseudovector (memlen, lisplen, tag) + int memlen, lisplen; + EMACS_INT tag; +{ + struct Lisp_Vector *v = allocate_vectorlike (memlen); + EMACS_INT i; + + /* Only the first lisplen slots will be traced normally by the GC. */ + v->size = lisplen; + for (i = 0; i < lisplen; ++i) + v->contents[i] = Qnil; + + XSETPVECTYPE (v, tag); /* Add the appropriate tag. */ + return v; +} +#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \ + ((typ*) \ + allocate_pseudovector \ + (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag)) + struct Lisp_Hash_Table * allocate_hash_table () { @@ -2976,78 +2998,47 @@ return (struct Lisp_Hash_Table *) v; } - - + + struct window * allocate_window () { - EMACS_INT len = VECSIZE (struct window); - struct Lisp_Vector *v = allocate_vectorlike (len); - EMACS_INT i; - - for (i = 0; i < len; ++i) - v->contents[i] = Qnil; - v->size = len; - - return (struct window *) v; + return ALLOCATE_PSEUDOVECTOR(struct window, current_matrix, PVEC_WINDOW); } struct terminal * allocate_terminal () { - /* Memory-footprint of the object in nb of Lisp_Object fields. */ - EMACS_INT memlen = VECSIZE (struct terminal); - /* Size if we only count the actual Lisp_Object fields (which need to be - traced by the GC). */ - EMACS_INT lisplen = PSEUDOVECSIZE (struct terminal, next_terminal); - struct Lisp_Vector *v = allocate_vectorlike (memlen); - EMACS_INT i; - Lisp_Object tmp, zero = make_number (0); - - for (i = 0; i < lisplen; ++i) - v->contents[i] = Qnil; - for (;i < memlen; ++i) - v->contents[i] = zero; - v->size = lisplen; /* Only trace the Lisp fields. */ - XSETTERMINAL (tmp, v); /* Add the appropriate tag. */ - - return (struct terminal *) v; + struct terminal *t = ALLOCATE_PSEUDOVECTOR (struct terminal, + next_terminal, PVEC_TERMINAL); + /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ + bzero (&(t->next_terminal), + ((char*)(t+1)) - ((char*)&(t->next_terminal))); + + return t; } struct frame * allocate_frame () { - EMACS_INT len = VECSIZE (struct frame); - struct Lisp_Vector *v = allocate_vectorlike (len); - EMACS_INT i; - - for (i = 0; i < len; ++i) - v->contents[i] = make_number (0); - v->size = len; - return (struct frame *) v; + struct frame *f = ALLOCATE_PSEUDOVECTOR (struct frame, + face_cache, PVEC_FRAME); + /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */ + bzero (&(f->face_cache), + ((char*)(f+1)) - ((char*)&(f->face_cache))); + return f; } struct Lisp_Process * allocate_process () { - /* Memory-footprint of the object in nb of Lisp_Object fields. */ - EMACS_INT memlen = VECSIZE (struct Lisp_Process); - /* Size if we only count the actual Lisp_Object fields (which need to be - traced by the GC). */ - EMACS_INT lisplen = PSEUDOVECSIZE (struct Lisp_Process, pid); - struct Lisp_Vector *v = allocate_vectorlike (memlen); - EMACS_INT i; - - for (i = 0; i < lisplen; ++i) - v->contents[i] = Qnil; - v->size = lisplen; - - return (struct Lisp_Process *) v; + return ALLOCATE_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS); } +/* Only used for PVEC_WINDOW_CONFIGURATION. */ struct Lisp_Vector * allocate_other_vector (len) EMACS_INT len; @@ -3104,6 +3095,7 @@ /* Add 2 to the size for the defalt and parent slots. */ vector = Fmake_vector (make_number (CHAR_TABLE_STANDARD_SLOTS + XINT (n)), init); + XSETPVECTYPE (XVECTOR (vector), PVEC_CHAR_TABLE); XCHAR_TABLE (vector)->top = Qt; XCHAR_TABLE (vector)->parent = Qnil; XCHAR_TABLE (vector)->purpose = purpose; @@ -3122,6 +3114,7 @@ { Lisp_Object vector = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), init); + XSETPVECTYPE (XVECTOR (vector), PVEC_CHAR_TABLE); XCHAR_TABLE (vector)->top = Qnil; XCHAR_TABLE (vector)->defalt = Qnil; XSETCHAR_TABLE (vector, XCHAR_TABLE (vector)); @@ -3186,6 +3179,7 @@ args[index] = Fpurecopy (args[index]); p->contents[index] = args[index]; } + XSETPVECTYPE (p, PVEC_COMPILED); XSETCOMPILED (val, p); return val; } @@ -5442,6 +5436,29 @@ Normally this is zero and the check never goes off. */ int mark_object_loop_halt; +/* Return non-zero if the object was not yet marked. */ +static int +mark_vectorlike (ptr) + struct Lisp_Vector *ptr; +{ + register EMACS_INT size = ptr->size; + register int i; + + if (VECTOR_MARKED_P (ptr)) + return 0; /* Already marked */ + VECTOR_MARK (ptr); /* Else mark it */ + if (size & PSEUDOVECTOR_FLAG) + size &= PSEUDOVECTOR_SIZE_MASK; + + /* Note that this size is not the memory-footprint size, but only + the number of Lisp_Object fields that we should trace. + The distinction is used e.g. by Lisp_Process which places extra + non-Lisp_Object fields at the end of the structure. */ + for (i = 0; i < size; i++) /* and then mark its elements */ + mark_object (ptr->contents[i]); + return 1; +} + void mark_object (arg) Lisp_Object arg; @@ -5571,74 +5588,28 @@ else if (GC_FRAMEP (obj)) { register struct frame *ptr = XFRAME (obj); - - if (VECTOR_MARKED_P (ptr)) break; /* Already marked */ - VECTOR_MARK (ptr); /* Else mark it */ - - CHECK_LIVE (live_vector_p); - mark_object (ptr->name); - mark_object (ptr->icon_name); - mark_object (ptr->title); - mark_object (ptr->focus_frame); - mark_object (ptr->selected_window); - mark_object (ptr->minibuffer_window); - mark_object (ptr->param_alist); - mark_object (ptr->scroll_bars); - mark_object (ptr->condemned_scroll_bars); - mark_object (ptr->menu_bar_items); - mark_object (ptr->face_alist); - mark_object (ptr->menu_bar_vector); - mark_object (ptr->buffer_predicate); - mark_object (ptr->buffer_list); - mark_object (ptr->buried_buffer_list); - mark_object (ptr->menu_bar_window); - mark_object (ptr->tool_bar_window); + if (mark_vectorlike (XVECTOR (obj))) + { mark_face_cache (ptr->face_cache); #ifdef HAVE_WINDOW_SYSTEM mark_image_cache (ptr); - mark_object (ptr->tool_bar_items); - mark_object (ptr->desired_tool_bar_string); - mark_object (ptr->current_tool_bar_string); #endif /* HAVE_WINDOW_SYSTEM */ } - else if (GC_BOOL_VECTOR_P (obj)) - { - register struct Lisp_Vector *ptr = XVECTOR (obj); - - if (VECTOR_MARKED_P (ptr)) - break; /* Already marked */ - CHECK_LIVE (live_vector_p); - VECTOR_MARK (ptr); /* Else mark it */ } else if (GC_WINDOWP (obj)) { register struct Lisp_Vector *ptr = XVECTOR (obj); struct window *w = XWINDOW (obj); - register int i; - - /* Stop if already marked. */ - if (VECTOR_MARKED_P (ptr)) - break; - - /* Mark it. */ - CHECK_LIVE (live_vector_p); - VECTOR_MARK (ptr); - - /* There is no Lisp data above The member CURRENT_MATRIX in - struct WINDOW. Stop marking when that slot is reached. */ - for (i = 0; - (char *) &ptr->contents[i] < (char *) &w->current_matrix; - i++) - mark_object (ptr->contents[i]); - + if (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); + if (NILP (w->hchild) + && NILP (w->vchild) + && w->current_matrix) + { + mark_glyph_matrix (w->current_matrix); mark_glyph_matrix (w->desired_matrix); } } @@ -5672,29 +5643,13 @@ /* If hash table is not weak, mark all keys and values. For weak tables, mark only the vector. */ if (GC_NILP (h->weak)) - mark_object (h->key_and_value); - else - VECTOR_MARK (XVECTOR (h->key_and_value)); + mark_object (h->key_and_value); + else + VECTOR_MARK (XVECTOR (h->key_and_value)); + } } else - { - register struct Lisp_Vector *ptr = XVECTOR (obj); - register EMACS_INT size = ptr->size; - register int i; - - if (VECTOR_MARKED_P (ptr)) break; /* Already marked */ - CHECK_LIVE (live_vector_p); - VECTOR_MARK (ptr); /* Else mark it */ - if (size & PSEUDOVECTOR_FLAG) - size &= PSEUDOVECTOR_SIZE_MASK; - - /* Note that this size is not the memory-footprint size, but only - the number of Lisp_Object fields that we should trace. - The distinction is used e.g. by Lisp_Process which places extra - non-Lisp_Object fields at the end of the structure. */ - for (i = 0; i < size; i++) /* and then mark its elements */ - mark_object (ptr->contents[i]); - } + mark_vectorlike (XVECTOR (obj)); break; case Lisp_Symbol: @@ -5892,12 +5847,10 @@ mark_terminals (void) { struct terminal *t; - Lisp_Object tmp; for (t = terminal_list; t; t = t->next_terminal) { eassert (t->name != NULL); - XSETVECTOR (tmp, t); - mark_object (tmp); + mark_vectorlike ((struct Lisp_Vector *)tmp); } }