changeset 85021:a0c901e4e649

* lisp.h (struct Lisp_Hash_Table): Move non-traced elements at the end. Turn `count' into an integer. * fns.c (make_hash_table, hash_put, hash_remove, hash_clear) (sweep_weak_table, sweep_weak_hash_tables, Fhash_table_count): * print.c (print_object) <HASH_TABLE_P>: `count' is an int. * alloc.c (allocate_hash_table): Use ALLOCATE_PSEUDOVECTOR. (mark_object) <HASH_TABLE_P>: Use mark_vectorlike.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Tue, 02 Oct 2007 21:24:47 +0000
parents db98fea45dfd
children 96eb42c9e0e3
files src/ChangeLog src/alloc.c src/fns.c src/lisp.h src/print.c
diffstat 5 files changed, 38 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Tue Oct 02 21:19:17 2007 +0000
+++ b/src/ChangeLog	Tue Oct 02 21:24:47 2007 +0000
@@ -1,5 +1,13 @@
 2007-10-02  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+	* lisp.h (struct Lisp_Hash_Table): Move non-traced elements at the end.
+	Turn `count' into an integer.
+	* fns.c (make_hash_table, hash_put, hash_remove, hash_clear)
+	(sweep_weak_table, sweep_weak_hash_tables, Fhash_table_count):
+	* print.c (print_object) <HASH_TABLE_P>: `count' is an int.
+	* alloc.c (allocate_hash_table): Use ALLOCATE_PSEUDOVECTOR.
+	(mark_object) <HASH_TABLE_P>: Use mark_vectorlike.
+
 	* alloc.c (allocate_pseudovector): New fun.
 	(ALLOCATE_PSEUDOVECTOR): New macro.
 	(allocate_window, allocate_terminal, allocate_frame)
--- a/src/alloc.c	Tue Oct 02 21:19:17 2007 +0000
+++ b/src/alloc.c	Tue Oct 02 21:24:47 2007 +0000
@@ -2986,20 +2986,12 @@
        (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag))
 
 struct Lisp_Hash_Table *
-allocate_hash_table ()
+allocate_hash_table (void)
 {
-  EMACS_INT len = VECSIZE (struct Lisp_Hash_Table);
-  struct Lisp_Vector *v = allocate_vectorlike (len);
-  EMACS_INT i;
-
-  v->size = len;
-  for (i = 0; i < len; ++i)
-    v->contents[i] = Qnil;
-
-  return (struct Lisp_Hash_Table *) v;
+  return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE);
 }
-  
-  
+
+
 struct window *
 allocate_window ()
 {
@@ -5617,33 +5609,10 @@
       else if (GC_HASH_TABLE_P (obj))
 	{
 	  struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
-
-	  /* Stop if already marked.  */
-	  if (VECTOR_MARKED_P (h))
-	    break;
-
-	  /* Mark it.  */
-	  CHECK_LIVE (live_vector_p);
-	  VECTOR_MARK (h);
-
-	  /* Mark contents.  */
-	  /* Do not mark next_free or next_weak.
-	     Being in the next_weak chain
-	     should not keep the hash table alive.
-	     No need to mark `count' since it is an integer.  */
-	  mark_object (h->test);
-	  mark_object (h->weak);
-	  mark_object (h->rehash_size);
-	  mark_object (h->rehash_threshold);
-	  mark_object (h->hash);
-	  mark_object (h->next);
-	  mark_object (h->index);
-	  mark_object (h->user_hash_function);
-	  mark_object (h->user_cmp_function);
-
-	  /* If hash table is not weak, mark all keys and values.
-	     For weak tables, mark only the vector.  */
-	  if (GC_NILP (h->weak))
+	  if (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 (GC_NILP (h->weak))
 		mark_object (h->key_and_value);
 	      else
 		VECTOR_MARK (XVECTOR (h->key_and_value));
--- a/src/fns.c	Tue Oct 02 21:19:17 2007 +0000
+++ b/src/fns.c	Tue Oct 02 21:24:47 2007 +0000
@@ -4598,7 +4598,7 @@
   h->weak = weak;
   h->rehash_threshold = rehash_threshold;
   h->rehash_size = rehash_size;
-  h->count = make_number (0);
+  h->count = 0;
   h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil);
   h->hash = Fmake_vector (size, Qnil);
   h->next = Fmake_vector (size, Qnil);
@@ -4778,7 +4778,7 @@
 
   /* Increment count after resizing because resizing may fail.  */
   maybe_resize_hash_table (h);
-  h->count = make_number (XFASTINT (h->count) + 1);
+  h->count++;
 
   /* Store key/value in the key_and_value vector.  */
   i = XFASTINT (h->next_free);
@@ -4834,8 +4834,8 @@
 	  HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil;
 	  HASH_NEXT (h, i) = h->next_free;
 	  h->next_free = make_number (i);
-	  h->count = make_number (XFASTINT (h->count) - 1);
-	  xassert (XINT (h->count) >= 0);
+	  h->count--;
+	  xassert (h->count >= 0);
 	  break;
 	}
       else
@@ -4853,7 +4853,7 @@
 hash_clear (h)
      struct Lisp_Hash_Table *h;
 {
-  if (XFASTINT (h->count) > 0)
+  if (h->count > 0)
     {
       int i, size = HASH_TABLE_SIZE (h);
 
@@ -4869,7 +4869,7 @@
 	AREF (h->index, i) = Qnil;
 
       h->next_free = make_number (0);
-      h->count = make_number (0);
+      h->count = 0;
     }
 }
 
@@ -4939,7 +4939,7 @@
 		  HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil;
 		  HASH_HASH (h, i) = Qnil;
 
-		  h->count = make_number (XFASTINT (h->count) - 1);
+		  h->count--;
 		}
 	      else
 		{
@@ -5005,7 +5005,7 @@
       if (h->size & ARRAY_MARK_FLAG)
 	{
 	  /* TABLE is marked as used.  Sweep its contents.  */
-	  if (XFASTINT (h->count) > 0)
+	  if (h->count > 0)
 	    sweep_weak_table (h, 1);
 
 	  /* Add table to the list of used weak hash tables.  */
@@ -5340,7 +5340,7 @@
      (table)
      Lisp_Object table;
 {
-  return check_hash_table (table)->count;
+  return make_number (check_hash_table (table)->count);
 }
 
 
--- a/src/lisp.h	Tue Oct 02 21:19:17 2007 +0000
+++ b/src/lisp.h	Tue Oct 02 21:24:47 2007 +0000
@@ -1019,13 +1019,6 @@
      ratio, a float.  */
   Lisp_Object rehash_threshold;
 
-  /* Number of key/value entries in the table.  */
-  Lisp_Object count;
-
-  /* Vector of keys and values.  The key of item I is found at index
-     2 * I, the value is found at index 2 * I + 1.  */
-  Lisp_Object key_and_value;
-
   /* Vector of hash codes.. If hash[I] is nil, this means that that
      entry I is unused.  */
   Lisp_Object hash;
@@ -1049,6 +1042,18 @@
   /* User-supplied key comparison function, or nil.  */
   Lisp_Object user_cmp_function;
 
+  /* Only the fields above are traced normally by the GC.  The ones below
+     `count'.  are special and are either ignored by the GC or traced in
+     a special way (e.g. because of weakness).  */
+
+  /* Number of key/value entries in the table.  */
+  unsigned int count;
+
+  /* Vector of keys and values.  The key of item I is found at index
+     2 * I, the value is found at index 2 * I + 1.
+     This is gc_marked specially if the table is weak.  */
+  Lisp_Object key_and_value;
+
   /* Next weak hash table if this is a weak hash table.  The head
      of the list is in weak_hash_tables.  */
   struct Lisp_Hash_Table *next_weak;
--- a/src/print.c	Tue Oct 02 21:19:17 2007 +0000
+++ b/src/print.c	Tue Oct 02 21:24:47 2007 +0000
@@ -1987,7 +1987,7 @@
 	      PRINTCHAR (' ');
 	      strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun, 0);
 	      PRINTCHAR (' ');
-	      sprintf (buf, "%ld/%ld", (long) XFASTINT (h->count),
+	      sprintf (buf, "%ld/%ld", (long) h->count,
 		       (long) XVECTOR (h->next)->size);
 	      strout (buf, -1, -1, printcharfun, 0);
 	    }