aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc.c
diff options
context:
space:
mode:
authorStefan Monnier2007-10-02 21:16:53 +0000
committerStefan Monnier2007-10-02 21:16:53 +0000
commitd2029e5b8196e9d670dcbf96555cd92590a0384c (patch)
tree1c8a46e16b98b40bbac9bf2cbee6993629865f04 /src/alloc.c
parentcf00e751e15a327f5cf3d4953ed658aa6ec670a6 (diff)
downloademacs-d2029e5b8196e9d670dcbf96555cd92590a0384c.tar.gz
emacs-d2029e5b8196e9d670dcbf96555cd92590a0384c.zip
(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.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c215
1 files changed, 84 insertions, 131 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 0d64bf66663..d9652a90e01 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -2338,11 +2338,12 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2338 /* We must allocate one more elements than LENGTH_IN_ELTS for the 2338 /* We must allocate one more elements than LENGTH_IN_ELTS for the
2339 slot `size' of the struct Lisp_Bool_Vector. */ 2339 slot `size' of the struct Lisp_Bool_Vector. */
2340 val = Fmake_vector (make_number (length_in_elts + 1), Qnil); 2340 val = Fmake_vector (make_number (length_in_elts + 1), Qnil);
2341 p = XBOOL_VECTOR (val);
2342 2341
2343 /* Get rid of any bits that would cause confusion. */ 2342 /* Get rid of any bits that would cause confusion. */
2344 p->vector_size = 0; 2343 XVECTOR (val)->size = 0; /* No Lisp_Object to trace in there. */
2345 XSETBOOL_VECTOR (val, p); 2344 XSETPVECTYPE (XVECTOR (val), PVEC_BOOL_VECTOR);
2345
2346 p = XBOOL_VECTOR (val);
2346 p->size = XFASTINT (length); 2347 p->size = XFASTINT (length);
2347 2348
2348 real_init = (NILP (init) ? 0 : -1); 2349 real_init = (NILP (init) ? 0 : -1);
@@ -2351,7 +2352,7 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */)
2351 2352
2352 /* Clear the extraneous bits in the last byte. */ 2353 /* Clear the extraneous bits in the last byte. */
2353 if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR) 2354 if (XINT (length) != length_in_chars * BOOL_VECTOR_BITS_PER_CHAR)
2354 XBOOL_VECTOR (val)->data[length_in_chars - 1] 2355 p->data[length_in_chars - 1]
2355 &= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1; 2356 &= (1 << (XINT (length) % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
2356 2357
2357 return val; 2358 return val;
@@ -2963,6 +2964,27 @@ allocate_vector (nslots)
2963 2964
2964/* Allocate other vector-like structures. */ 2965/* Allocate other vector-like structures. */
2965 2966
2967static struct Lisp_Vector *
2968allocate_pseudovector (memlen, lisplen, tag)
2969 int memlen, lisplen;
2970 EMACS_INT tag;
2971{
2972 struct Lisp_Vector *v = allocate_vectorlike (memlen);
2973 EMACS_INT i;
2974
2975 /* Only the first lisplen slots will be traced normally by the GC. */
2976 v->size = lisplen;
2977 for (i = 0; i < lisplen; ++i)
2978 v->contents[i] = Qnil;
2979
2980 XSETPVECTYPE (v, tag); /* Add the appropriate tag. */
2981 return v;
2982}
2983#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \
2984 ((typ*) \
2985 allocate_pseudovector \
2986 (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag))
2987
2966struct Lisp_Hash_Table * 2988struct Lisp_Hash_Table *
2967allocate_hash_table () 2989allocate_hash_table ()
2968{ 2990{
@@ -2976,78 +2998,47 @@ allocate_hash_table ()
2976 2998
2977 return (struct Lisp_Hash_Table *) v; 2999 return (struct Lisp_Hash_Table *) v;
2978} 3000}
2979 3001
2980 3002
2981struct window * 3003struct window *
2982allocate_window () 3004allocate_window ()
2983{ 3005{
2984 EMACS_INT len = VECSIZE (struct window); 3006 return ALLOCATE_PSEUDOVECTOR(struct window, current_matrix, PVEC_WINDOW);
2985 struct Lisp_Vector *v = allocate_vectorlike (len);
2986 EMACS_INT i;
2987
2988 for (i = 0; i < len; ++i)
2989 v->contents[i] = Qnil;
2990 v->size = len;
2991
2992 return (struct window *) v;
2993} 3007}
2994 3008
2995 3009
2996struct terminal * 3010struct terminal *
2997allocate_terminal () 3011allocate_terminal ()
2998{ 3012{
2999 /* Memory-footprint of the object in nb of Lisp_Object fields. */ 3013 struct terminal *t = ALLOCATE_PSEUDOVECTOR (struct terminal,
3000 EMACS_INT memlen = VECSIZE (struct terminal); 3014 next_terminal, PVEC_TERMINAL);
3001 /* Size if we only count the actual Lisp_Object fields (which need to be 3015 /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */
3002 traced by the GC). */ 3016 bzero (&(t->next_terminal),
3003 EMACS_INT lisplen = PSEUDOVECSIZE (struct terminal, next_terminal); 3017 ((char*)(t+1)) - ((char*)&(t->next_terminal)));
3004 struct Lisp_Vector *v = allocate_vectorlike (memlen);
3005 EMACS_INT i;
3006 Lisp_Object tmp, zero = make_number (0);
3007 3018
3008 for (i = 0; i < lisplen; ++i) 3019 return t;
3009 v->contents[i] = Qnil;
3010 for (;i < memlen; ++i)
3011 v->contents[i] = zero;
3012 v->size = lisplen; /* Only trace the Lisp fields. */
3013 XSETTERMINAL (tmp, v); /* Add the appropriate tag. */
3014
3015 return (struct terminal *) v;
3016} 3020}
3017 3021
3018struct frame * 3022struct frame *
3019allocate_frame () 3023allocate_frame ()
3020{ 3024{
3021 EMACS_INT len = VECSIZE (struct frame); 3025 struct frame *f = ALLOCATE_PSEUDOVECTOR (struct frame,
3022 struct Lisp_Vector *v = allocate_vectorlike (len); 3026 face_cache, PVEC_FRAME);
3023 EMACS_INT i; 3027 /* Zero out the non-GC'd fields. FIXME: This should be made unnecessary. */
3024 3028 bzero (&(f->face_cache),
3025 for (i = 0; i < len; ++i) 3029 ((char*)(f+1)) - ((char*)&(f->face_cache)));
3026 v->contents[i] = make_number (0); 3030 return f;
3027 v->size = len;
3028 return (struct frame *) v;
3029} 3031}
3030 3032
3031 3033
3032struct Lisp_Process * 3034struct Lisp_Process *
3033allocate_process () 3035allocate_process ()
3034{ 3036{
3035 /* Memory-footprint of the object in nb of Lisp_Object fields. */ 3037 return ALLOCATE_PSEUDOVECTOR (struct Lisp_Process, pid, PVEC_PROCESS);
3036 EMACS_INT memlen = VECSIZE (struct Lisp_Process);
3037 /* Size if we only count the actual Lisp_Object fields (which need to be
3038 traced by the GC). */
3039 EMACS_INT lisplen = PSEUDOVECSIZE (struct Lisp_Process, pid);
3040 struct Lisp_Vector *v = allocate_vectorlike (memlen);
3041 EMACS_INT i;
3042
3043 for (i = 0; i < lisplen; ++i)
3044 v->contents[i] = Qnil;
3045 v->size = lisplen;
3046
3047 return (struct Lisp_Process *) v;
3048} 3038}
3049 3039
3050 3040
3041/* Only used for PVEC_WINDOW_CONFIGURATION. */
3051struct Lisp_Vector * 3042struct Lisp_Vector *
3052allocate_other_vector (len) 3043allocate_other_vector (len)
3053 EMACS_INT len; 3044 EMACS_INT len;
@@ -3104,6 +3095,7 @@ The property's value should be an integer between 0 and 10. */)
3104 /* Add 2 to the size for the defalt and parent slots. */ 3095 /* Add 2 to the size for the defalt and parent slots. */
3105 vector = Fmake_vector (make_number (CHAR_TABLE_STANDARD_SLOTS + XINT (n)), 3096 vector = Fmake_vector (make_number (CHAR_TABLE_STANDARD_SLOTS + XINT (n)),
3106 init); 3097 init);
3098 XSETPVECTYPE (XVECTOR (vector), PVEC_CHAR_TABLE);
3107 XCHAR_TABLE (vector)->top = Qt; 3099 XCHAR_TABLE (vector)->top = Qt;
3108 XCHAR_TABLE (vector)->parent = Qnil; 3100 XCHAR_TABLE (vector)->parent = Qnil;
3109 XCHAR_TABLE (vector)->purpose = purpose; 3101 XCHAR_TABLE (vector)->purpose = purpose;
@@ -3122,6 +3114,7 @@ make_sub_char_table (init)
3122{ 3114{
3123 Lisp_Object vector 3115 Lisp_Object vector
3124 = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), init); 3116 = Fmake_vector (make_number (SUB_CHAR_TABLE_STANDARD_SLOTS), init);
3117 XSETPVECTYPE (XVECTOR (vector), PVEC_CHAR_TABLE);
3125 XCHAR_TABLE (vector)->top = Qnil; 3118 XCHAR_TABLE (vector)->top = Qnil;
3126 XCHAR_TABLE (vector)->defalt = Qnil; 3119 XCHAR_TABLE (vector)->defalt = Qnil;
3127 XSETCHAR_TABLE (vector, XCHAR_TABLE (vector)); 3120 XSETCHAR_TABLE (vector, XCHAR_TABLE (vector));
@@ -3186,6 +3179,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT
3186 args[index] = Fpurecopy (args[index]); 3179 args[index] = Fpurecopy (args[index]);
3187 p->contents[index] = args[index]; 3180 p->contents[index] = args[index];
3188 } 3181 }
3182 XSETPVECTYPE (p, PVEC_COMPILED);
3189 XSETCOMPILED (val, p); 3183 XSETCOMPILED (val, p);
3190 return val; 3184 return val;
3191} 3185}
@@ -5442,6 +5436,29 @@ int last_marked_index;
5442 Normally this is zero and the check never goes off. */ 5436 Normally this is zero and the check never goes off. */
5443int mark_object_loop_halt; 5437int mark_object_loop_halt;
5444 5438
5439/* Return non-zero if the object was not yet marked. */
5440static int
5441mark_vectorlike (ptr)
5442 struct Lisp_Vector *ptr;
5443{
5444 register EMACS_INT size = ptr->size;
5445 register int i;
5446
5447 if (VECTOR_MARKED_P (ptr))
5448 return 0; /* Already marked */
5449 VECTOR_MARK (ptr); /* Else mark it */
5450 if (size & PSEUDOVECTOR_FLAG)
5451 size &= PSEUDOVECTOR_SIZE_MASK;
5452
5453 /* Note that this size is not the memory-footprint size, but only
5454 the number of Lisp_Object fields that we should trace.
5455 The distinction is used e.g. by Lisp_Process which places extra
5456 non-Lisp_Object fields at the end of the structure. */
5457 for (i = 0; i < size; i++) /* and then mark its elements */
5458 mark_object (ptr->contents[i]);
5459 return 1;
5460}
5461
5445void 5462void
5446mark_object (arg) 5463mark_object (arg)
5447 Lisp_Object arg; 5464 Lisp_Object arg;
@@ -5571,74 +5588,28 @@ mark_object (arg)
5571 else if (GC_FRAMEP (obj)) 5588 else if (GC_FRAMEP (obj))
5572 { 5589 {
5573 register struct frame *ptr = XFRAME (obj); 5590 register struct frame *ptr = XFRAME (obj);
5574 5591 if (mark_vectorlike (XVECTOR (obj)))
5575 if (VECTOR_MARKED_P (ptr)) break; /* Already marked */ 5592 {
5576 VECTOR_MARK (ptr); /* Else mark it */
5577
5578 CHECK_LIVE (live_vector_p);
5579 mark_object (ptr->name);
5580 mark_object (ptr->icon_name);
5581 mark_object (ptr->title);
5582 mark_object (ptr->focus_frame);
5583 mark_object (ptr->selected_window);
5584 mark_object (ptr->minibuffer_window);
5585 mark_object (ptr->param_alist);
5586 mark_object (ptr->scroll_bars);
5587 mark_object (ptr->condemned_scroll_bars);
5588 mark_object (ptr->menu_bar_items);
5589 mark_object (ptr->face_alist);
5590 mark_object (ptr->menu_bar_vector);
5591 mark_object (ptr->buffer_predicate);
5592 mark_object (ptr->buffer_list);
5593 mark_object (ptr->buried_buffer_list);
5594 mark_object (ptr->menu_bar_window);
5595 mark_object (ptr->tool_bar_window);
5596 mark_face_cache (ptr->face_cache); 5593 mark_face_cache (ptr->face_cache);
5597#ifdef HAVE_WINDOW_SYSTEM 5594#ifdef HAVE_WINDOW_SYSTEM
5598 mark_image_cache (ptr); 5595 mark_image_cache (ptr);
5599 mark_object (ptr->tool_bar_items);
5600 mark_object (ptr->desired_tool_bar_string);
5601 mark_object (ptr->current_tool_bar_string);
5602#endif /* HAVE_WINDOW_SYSTEM */ 5596#endif /* HAVE_WINDOW_SYSTEM */
5603 } 5597 }
5604 else if (GC_BOOL_VECTOR_P (obj))
5605 {
5606 register struct Lisp_Vector *ptr = XVECTOR (obj);
5607
5608 if (VECTOR_MARKED_P (ptr))
5609 break; /* Already marked */
5610 CHECK_LIVE (live_vector_p);
5611 VECTOR_MARK (ptr); /* Else mark it */
5612 } 5598 }
5613 else if (GC_WINDOWP (obj)) 5599 else if (GC_WINDOWP (obj))
5614 { 5600 {
5615 register struct Lisp_Vector *ptr = XVECTOR (obj); 5601 register struct Lisp_Vector *ptr = XVECTOR (obj);
5616 struct window *w = XWINDOW (obj); 5602 struct window *w = XWINDOW (obj);
5617 register int i; 5603 if (mark_vectorlike (ptr))
5618 5604 {
5619 /* Stop if already marked. */
5620 if (VECTOR_MARKED_P (ptr))
5621 break;
5622
5623 /* Mark it. */
5624 CHECK_LIVE (live_vector_p);
5625 VECTOR_MARK (ptr);
5626
5627 /* There is no Lisp data above The member CURRENT_MATRIX in
5628 struct WINDOW. Stop marking when that slot is reached. */
5629 for (i = 0;
5630 (char *) &ptr->contents[i] < (char *) &w->current_matrix;
5631 i++)
5632 mark_object (ptr->contents[i]);
5633
5634 /* Mark glyphs for leaf windows. Marking window matrices is 5605 /* Mark glyphs for leaf windows. Marking window matrices is
5635 sufficient because frame matrices use the same glyph 5606 sufficient because frame matrices use the same glyph
5636 memory. */ 5607 memory. */
5637 if (NILP (w->hchild) 5608 if (NILP (w->hchild)
5638 && NILP (w->vchild) 5609 && NILP (w->vchild)
5639 && w->current_matrix) 5610 && w->current_matrix)
5640 { 5611 {
5641 mark_glyph_matrix (w->current_matrix); 5612 mark_glyph_matrix (w->current_matrix);
5642 mark_glyph_matrix (w->desired_matrix); 5613 mark_glyph_matrix (w->desired_matrix);
5643 } 5614 }
5644 } 5615 }
@@ -5672,29 +5643,13 @@ mark_object (arg)
5672 /* If hash table is not weak, mark all keys and values. 5643 /* If hash table is not weak, mark all keys and values.
5673 For weak tables, mark only the vector. */ 5644 For weak tables, mark only the vector. */
5674 if (GC_NILP (h->weak)) 5645 if (GC_NILP (h->weak))
5675 mark_object (h->key_and_value); 5646 mark_object (h->key_and_value);
5676 else 5647 else
5677 VECTOR_MARK (XVECTOR (h->key_and_value)); 5648 VECTOR_MARK (XVECTOR (h->key_and_value));
5649 }
5678 } 5650 }
5679 else 5651 else
5680 { 5652 mark_vectorlike (XVECTOR (obj));
5681 register struct Lisp_Vector *ptr = XVECTOR (obj);
5682 register EMACS_INT size = ptr->size;
5683 register int i;
5684
5685 if (VECTOR_MARKED_P (ptr)) break; /* Already marked */
5686 CHECK_LIVE (live_vector_p);
5687 VECTOR_MARK (ptr); /* Else mark it */
5688 if (size & PSEUDOVECTOR_FLAG)
5689 size &= PSEUDOVECTOR_SIZE_MASK;
5690
5691 /* Note that this size is not the memory-footprint size, but only
5692 the number of Lisp_Object fields that we should trace.
5693 The distinction is used e.g. by Lisp_Process which places extra
5694 non-Lisp_Object fields at the end of the structure. */
5695 for (i = 0; i < size; i++) /* and then mark its elements */
5696 mark_object (ptr->contents[i]);
5697 }
5698 break; 5653 break;
5699 5654
5700 case Lisp_Symbol: 5655 case Lisp_Symbol:
@@ -5892,12 +5847,10 @@ static void
5892mark_terminals (void) 5847mark_terminals (void)
5893{ 5848{
5894 struct terminal *t; 5849 struct terminal *t;
5895 Lisp_Object tmp;
5896 for (t = terminal_list; t; t = t->next_terminal) 5850 for (t = terminal_list; t; t = t->next_terminal)
5897 { 5851 {
5898 eassert (t->name != NULL); 5852 eassert (t->name != NULL);
5899 XSETVECTOR (tmp, t); 5853 mark_vectorlike ((struct Lisp_Vector *)tmp);
5900 mark_object (tmp);
5901 } 5854 }
5902} 5855}
5903 5856