X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/9eb879911fb1792a6318fc71e26a41a023e78de0..95385625ed590b286be55ea3b47790e2cd25e993:/src/alloc.c diff --git a/src/alloc.c b/src/alloc.c index 2def77bf0b..1d55fc50d0 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -435,7 +435,7 @@ init_float () free_float (ptr) struct Lisp_Float *ptr; { - XSETFASTINT (ptr->type, (EMACS_INT) float_free_list); + *(struct Lisp_Float **)&ptr->type = float_free_list; float_free_list = ptr; } @@ -448,7 +448,7 @@ make_float (float_value) if (float_free_list) { XSETFLOAT (val, float_free_list); - float_free_list = (struct Lisp_Float *) XFASTINT (float_free_list->type); + float_free_list = *(struct Lisp_Float **)&float_free_list->type; } else { @@ -508,7 +508,7 @@ init_cons () free_cons (ptr) struct Lisp_Cons *ptr; { - XSETFASTINT (ptr->car, (EMACS_INT) cons_free_list); + *(struct Lisp_Cons **)&ptr->car = cons_free_list; cons_free_list = ptr; } @@ -522,7 +522,7 @@ DEFUN ("cons", Fcons, Scons, 2, 2, 0, if (cons_free_list) { XSETCONS (val, cons_free_list); - cons_free_list = (struct Lisp_Cons *) XFASTINT (cons_free_list->car); + cons_free_list = *(struct Lisp_Cons **)&cons_free_list->car; } else { @@ -570,9 +570,8 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, register Lisp_Object val; register int size; - if (!INTEGERP (length) || XINT (length) < 0) - length = wrong_type_argument (Qnatnump, length); - size = XINT (length); + CHECK_NATNUM (length, 0); + size = XFASTINT (length); val = Qnil; while (size-- > 0) @@ -584,33 +583,43 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, struct Lisp_Vector *all_vectors; +struct Lisp_Vector * +allocate_vectorlike (len) + EMACS_INT len; +{ + struct Lisp_Vector *p; + + p = (struct Lisp_Vector *)xmalloc (sizeof (struct Lisp_Vector) + + (len - 1) * sizeof (Lisp_Object)); + VALIDATE_LISP_STORAGE (p, 0); + consing_since_gc += (sizeof (struct Lisp_Vector) + + (len - 1) * sizeof (Lisp_Object)); + + p->next = all_vectors; + all_vectors = p; + return p; +} + DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, "Return a newly created vector of length LENGTH, with each element being INIT.\n\ See also the function `vector'.") (length, init) register Lisp_Object length, init; { - register int sizei, index; - register Lisp_Object vector; + Lisp_Object vector; + register EMACS_INT sizei; + register int index; register struct Lisp_Vector *p; - if (!INTEGERP (length) || XINT (length) < 0) - length = wrong_type_argument (Qnatnump, length); - sizei = XINT (length); - - p = (struct Lisp_Vector *) xmalloc (sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object)); - VALIDATE_LISP_STORAGE (p, 0); - - XSETVECTOR (vector, p); - consing_since_gc += sizeof (struct Lisp_Vector) + (sizei - 1) * sizeof (Lisp_Object); + CHECK_NATNUM (length, 0); + sizei = XFASTINT (length); + p = allocate_vectorlike (sizei); p->size = sizei; - p->next = all_vectors; - all_vectors = p; - for (index = 0; index < sizei; index++) p->contents[index] = init; + XSETVECTOR (vector, p); return vector; } @@ -659,7 +668,7 @@ significance.") args[index] = Fpurecopy (args[index]); p->contents[index] = args[index]; } - XSETTYPE (val, Lisp_Compiled); + XSETCOMPILED (val, val); return val; } @@ -708,8 +717,7 @@ Its value and function definition are void, and its property list is nil.") if (symbol_free_list) { XSETSYMBOL (val, symbol_free_list); - symbol_free_list - = (struct Lisp_Symbol *) XFASTINT (symbol_free_list->value); + symbol_free_list = *(struct Lisp_Symbol **)&symbol_free_list->value; } else { @@ -733,22 +741,22 @@ Its value and function definition are void, and its property list is nil.") return val; } -/* Allocation of markers. +/* Allocation of markers and other objects that share that structure. Works like allocation of conses. */ #define MARKER_BLOCK_SIZE \ - ((1020 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker)) + ((1020 - sizeof (struct marker_block *)) / sizeof (union Lisp_Misc)) struct marker_block { struct marker_block *next; - struct Lisp_Marker markers[MARKER_BLOCK_SIZE]; + union Lisp_Misc markers[MARKER_BLOCK_SIZE]; }; struct marker_block *marker_block; int marker_block_index; -struct Lisp_Marker *marker_free_list; +union Lisp_Misc *marker_free_list; void init_marker () @@ -760,36 +768,47 @@ init_marker () marker_free_list = 0; } -DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, - "Return a newly allocated marker which does not point at any place.") - () +/* Return a newly allocated Lisp_Misc object, with no substructure. */ +Lisp_Object +allocate_misc () { - register Lisp_Object val; - register struct Lisp_Marker *p; + Lisp_Object val; if (marker_free_list) { - XSETMARKER (val, marker_free_list); - marker_free_list - = (struct Lisp_Marker *) XFASTINT (marker_free_list->chain); + XSETMISC (val, marker_free_list); + marker_free_list = marker_free_list->u_free.chain; } else { if (marker_block_index == MARKER_BLOCK_SIZE) { - struct marker_block *new = (struct marker_block *) xmalloc (sizeof (struct marker_block)); + struct marker_block *new + = (struct marker_block *) xmalloc (sizeof (struct marker_block)); VALIDATE_LISP_STORAGE (new, sizeof *new); new->next = marker_block; marker_block = new; marker_block_index = 0; } - XSETMARKER (val, &marker_block->markers[marker_block_index++]); + XSETMISC (val, &marker_block->markers[marker_block_index++]); } + consing_since_gc += sizeof (union Lisp_Misc); + return val; +} + +DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, + "Return a newly allocated marker which does not point at any place.") + () +{ + register Lisp_Object val; + register struct Lisp_Marker *p; + + val = allocate_misc (); + XMISC (val)->type = Lisp_Misc_Marker; p = XMARKER (val); p->buffer = 0; p->bufpos = 0; p->chain = Qnil; - consing_since_gc += sizeof (struct Lisp_Marker); return val; } @@ -875,10 +894,9 @@ Both LENGTH and INIT must be numbers.") register Lisp_Object val; register unsigned char *p, *end, c; - if (!INTEGERP (length) || XINT (length) < 0) - length = wrong_type_argument (Qnatnump, length); + CHECK_NATNUM (length, 0); CHECK_NUMBER (init, 1); - val = make_uninit_string (XINT (length)); + val = make_uninit_string (XFASTINT (length)); c = XINT (init); p = XSTRING (val)->data; end = p + XSTRING (val)->size; @@ -1109,9 +1127,6 @@ Does not copy symbols.") (obj) register Lisp_Object obj; { - register Lisp_Object new, tem; - register int i; - if (NILP (Vpurify_flag)) return obj; @@ -1119,40 +1134,33 @@ Does not copy symbols.") && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) return obj; -#ifdef SWITCH_ENUM_BUG - switch ((int) XTYPE (obj)) -#else - switch (XTYPE (obj)) -#endif - { - case Lisp_Marker: - error ("Attempt to copy a marker to pure storage"); - - case Lisp_Cons: - return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr); - + if (CONSP (obj)) + return pure_cons (XCONS (obj)->car, XCONS (obj)->cdr); #ifdef LISP_FLOAT_TYPE - case Lisp_Float: - return make_pure_float (XFLOAT (obj)->data); + else if (FLOATP (obj)) + return make_pure_float (XFLOAT (obj)->data); #endif /* LISP_FLOAT_TYPE */ - - case Lisp_String: - return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size); - - case Lisp_Compiled: - case Lisp_Vector: - new = make_pure_vector (XVECTOR (obj)->size); - for (i = 0; i < XVECTOR (obj)->size; i++) - { - tem = XVECTOR (obj)->contents[i]; - XVECTOR (new)->contents[i] = Fpurecopy (tem); - } - XSETTYPE (new, XTYPE (obj)); - return new; - - default: + else if (STRINGP (obj)) + return make_pure_string (XSTRING (obj)->data, XSTRING (obj)->size); + else if (COMPILEDP (obj) || VECTORP (obj)) + { + register struct Lisp_Vector *vec; + register int i, size; + + size = XVECTOR (obj)->size; + vec = XVECTOR (make_pure_vector (size)); + for (i = 0; i < size; i++) + vec->contents[i] = Fpurecopy (XVECTOR (obj)->contents[i]); + if (COMPILEDP (obj)) + XSETCOMPILED (obj, vec); + else + XSETVECTOR (obj, vec); return obj; } + else if (MARKERP (obj)) + error ("Attempt to copy a marker to pure storage"); + else + return obj; } /* Recording what needs to be marked for gc. */ @@ -1426,7 +1434,8 @@ clear_marks () { register int i; for (i = 0; i < lim; i++) - XUNMARK (sblk->markers[i].chain); + if (sblk->markers[i].type == Lisp_Misc_Marker) + XUNMARK (sblk->markers[i].u_marker.chain); lim = MARKER_BLOCK_SIZE; } } @@ -1513,78 +1522,78 @@ mark_object (objptr) } break; - case Lisp_Vector: - case Lisp_Window: - case Lisp_Process: - case Lisp_Window_Configuration: - { - register struct Lisp_Vector *ptr = XVECTOR (obj); - register EMACS_INT size = ptr->size; - /* The reason we use ptr1 is to avoid an apparent hardware bug - that happens occasionally on the FSF's HP 300s. - The bug is that a2 gets clobbered by recursive calls to mark_object. - The clobberage seems to happen during function entry, - perhaps in the moveml instruction. - Yes, this is a crock, but we have to do it. */ - struct Lisp_Vector *volatile ptr1 = ptr; - register int i; - - if (size & ARRAY_MARK_FLAG) break; /* Already marked */ - ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ - for (i = 0; i < size; i++) /* and then mark its elements */ - mark_object (&ptr1->contents[i]); - } - break; - - case Lisp_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. */ - { - register struct Lisp_Vector *ptr = XVECTOR (obj); - register EMACS_INT size = ptr->size; - /* See comment above under Lisp_Vector. */ - struct Lisp_Vector *volatile ptr1 = ptr; - register int i; - - if (size & ARRAY_MARK_FLAG) break; /* Already marked */ - ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ - for (i = 0; i < size; i++) /* and then mark its elements */ - { - if (i != COMPILED_CONSTANTS) - mark_object (&ptr1->contents[i]); - } - /* This cast should be unnecessary, but some Mips compiler complains - (MIPS-ABI + SysVR4, DC/OSx, etc). */ - objptr = (Lisp_Object *) &ptr1->contents[COMPILED_CONSTANTS]; - goto loop; - } - + case Lisp_Vectorlike: + if (GC_SUBRP (obj)) + break; + else if (GC_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); + register EMACS_INT size = ptr->size; + /* See comment above under Lisp_Vector. */ + struct Lisp_Vector *volatile ptr1 = ptr; + register int i; + + if (size & ARRAY_MARK_FLAG) + break; /* Already marked */ + ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ + size &= PSEUDOVECTOR_SIZE_MASK; + for (i = 0; i < size; i++) /* and then mark its elements */ + { + if (i != COMPILED_CONSTANTS) + mark_object (&ptr1->contents[i]); + } + /* This cast should be unnecessary, but some Mips compiler complains + (MIPS-ABI + SysVR4, DC/OSx, etc). */ + objptr = (Lisp_Object *) &ptr1->contents[COMPILED_CONSTANTS]; + goto loop; + } #ifdef MULTI_FRAME - case Lisp_Frame: - { - /* See comment above under Lisp_Vector for why this is volatile. */ - register struct frame *volatile ptr = XFRAME (obj); - register EMACS_INT size = ptr->size; - - if (size & ARRAY_MARK_FLAG) break; /* Already marked */ - ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ - - mark_object (&ptr->name); - mark_object (&ptr->focus_frame); - mark_object (&ptr->width); - mark_object (&ptr->height); - 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->menu_bar_vector); - mark_object (&ptr->face_alist); - } - break; + else if (GC_FRAMEP (obj)) + { + /* See comment above under Lisp_Vector for why this is volatile. */ + register struct frame *volatile ptr = XFRAME (obj); + register EMACS_INT size = ptr->size; + + if (size & ARRAY_MARK_FLAG) break; /* Already marked */ + ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ + + mark_object (&ptr->name); + 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); + } + else #endif /* MULTI_FRAME */ + { + register struct Lisp_Vector *ptr = XVECTOR (obj); + register EMACS_INT size = ptr->size; + /* The reason we use ptr1 is to avoid an apparent hardware bug + that happens occasionally on the FSF's HP 300s. + The bug is that a2 gets clobbered by recursive calls to mark_object. + The clobberage seems to happen during function entry, + perhaps in the moveml instruction. + Yes, this is a crock, but we have to do it. */ + struct Lisp_Vector *volatile ptr1 = ptr; + register int i; + + if (size & ARRAY_MARK_FLAG) break; /* Already marked */ + ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ + if (size & PSEUDOVECTOR_FLAG) + size &= PSEUDOVECTOR_SIZE_MASK; + for (i = 0; i < size; i++) /* and then mark its elements */ + mark_object (&ptr1->contents[i]); + } + break; case Lisp_Symbol: { @@ -1613,17 +1622,65 @@ mark_object (objptr) } break; - case Lisp_Marker: - XMARK (XMARKER (obj)->chain); - /* DO NOT mark thru the marker's chain. - The buffer's markers chain does not preserve markers from gc; - instead, markers are removed from the chain when freed by gc. */ + case Lisp_Misc: + switch (XMISC (obj)->type) + { + case Lisp_Misc_Marker: + XMARK (XMARKER (obj)->chain); + /* DO NOT mark thru the marker's chain. + The buffer's markers chain does not preserve markers from gc; + instead, markers are removed from the chain when freed by gc. */ + break; + + case Lisp_Misc_Buffer_Local_Value: + case Lisp_Misc_Some_Buffer_Local_Value: + { + register struct Lisp_Buffer_Local_Value *ptr + = XBUFFER_LOCAL_VALUE (obj); + if (XMARKBIT (ptr->car)) break; + XMARK (ptr->car); + /* If the cdr is nil, avoid recursion for the car. */ + if (EQ (ptr->cdr, Qnil)) + { + objptr = &ptr->car; + goto loop; + } + mark_object (&ptr->car); + /* See comment above under Lisp_Vector for why not use ptr here. */ + objptr = &XBUFFER_LOCAL_VALUE (obj)->cdr; + goto loop; + } + + case Lisp_Misc_Intfwd: + case Lisp_Misc_Boolfwd: + case Lisp_Misc_Objfwd: + case Lisp_Misc_Buffer_Objfwd: + /* Don't bother with Lisp_Buffer_Objfwd, + since all markable slots in current buffer marked anyway. */ + /* Don't need to do Lisp_Objfwd, since the places they point + are protected with staticpro. */ + break; + + case Lisp_Misc_Overlay: + { + struct Lisp_Overlay *ptr = XOVERLAY (obj); + if (!XMARKBIT (ptr->plist)) + { + XMARK (ptr->plist); + mark_object (&ptr->start); + mark_object (&ptr->end); + objptr = &ptr->plist; + goto loop; + } + } + break; + + default: + abort (); + } break; case Lisp_Cons: - case Lisp_Buffer_Local_Value: - case Lisp_Some_Buffer_Local_Value: - case Lisp_Overlay: { register struct Lisp_Cons *ptr = XCONS (obj); if (XMARKBIT (ptr->car)) break; @@ -1652,15 +1709,6 @@ mark_object (objptr) break; case Lisp_Int: - case Lisp_Subr: - case Lisp_Intfwd: - case Lisp_Boolfwd: - case Lisp_Objfwd: - case Lisp_Buffer_Objfwd: - /* Don't bother with Lisp_Buffer_Objfwd, - since all markable slots in current buffer marked anyway. */ - /* Don't need to do Lisp_Objfwd, since the places they point - are protected with staticpro. */ break; default: @@ -1729,8 +1777,8 @@ gc_sweep () for (i = 0; i < lim; i++) if (!XMARKBIT (cblk->conses[i].car)) { - XSETFASTINT (cblk->conses[i].car, (EMACS_INT) cons_free_list); num_free++; + *(struct Lisp_Cons **)&cblk->conses[i].car = cons_free_list; cons_free_list = &cblk->conses[i]; } else @@ -1759,8 +1807,8 @@ gc_sweep () for (i = 0; i < lim; i++) if (!XMARKBIT (fblk->floats[i].type)) { - XSETFASTINT (fblk->floats[i].type, (EMACS_INT) float_free_list); num_free++; + *(struct Lisp_Float **)&fblk->floats[i].type = float_free_list; float_free_list = &fblk->floats[i]; } else @@ -1823,7 +1871,7 @@ gc_sweep () for (i = 0; i < lim; i++) if (!XMARKBIT (sblk->symbols[i].plist)) { - XSETFASTINT (sblk->symbols[i].value, (EMACS_INT) symbol_free_list); + *(struct Lisp_Symbol **)&sblk->symbols[i].value = symbol_free_list; symbol_free_list = &sblk->symbols[i]; num_free++; } @@ -1842,10 +1890,10 @@ gc_sweep () #ifndef standalone /* Put all unmarked markers on free list. - Dechain each one first from the buffer it points into. */ + Dechain each one first from the buffer it points into, + but only if it's a real marker. */ { register struct marker_block *mblk; - struct Lisp_Marker *tem1; register int lim = marker_block_index; register int num_free = 0, num_used = 0; @@ -1855,21 +1903,48 @@ gc_sweep () { register int i; for (i = 0; i < lim; i++) - if (!XMARKBIT (mblk->markers[i].chain)) - { - Lisp_Object tem; - tem1 = &mblk->markers[i]; /* tem1 avoids Sun compiler bug */ - XSETMARKER (tem, tem1); - unchain_marker (tem); - XSETFASTINT (mblk->markers[i].chain, (EMACS_INT) marker_free_list); - marker_free_list = &mblk->markers[i]; - num_free++; - } - else - { - num_used++; - XUNMARK (mblk->markers[i].chain); - } + { + Lisp_Object *markword; + switch (mblk->markers[i].type) + { + case Lisp_Misc_Marker: + markword = &mblk->markers[i].u_marker.chain; + break; + case Lisp_Misc_Buffer_Local_Value: + case Lisp_Misc_Some_Buffer_Local_Value: + markword = &mblk->markers[i].u_buffer_local_value.car; + break; + case Lisp_Misc_Overlay: + markword = &mblk->markers[i].u_overlay.plist; + break; + default: + markword = 0; + break; + } + if (markword && !XMARKBIT (*markword)) + { + Lisp_Object tem; + if (mblk->markers[i].type == Lisp_Misc_Marker) + { + /* tem1 avoids Sun compiler bug */ + struct Lisp_Marker *tem1 = &mblk->markers[i].u_marker; + XSETMARKER (tem, tem1); + unchain_marker (tem); + } + /* We could leave the type alone, since nobody checks it, + but this might catch bugs faster. */ + mblk->markers[i].type = Lisp_Misc_Free; + mblk->markers[i].u_free.chain = marker_free_list; + marker_free_list = &mblk->markers[i]; + num_free++; + } + else + { + num_used++; + if (markword) + XUNMARK (*markword); + } + } lim = MARKER_BLOCK_SIZE; }