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.
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)
(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;
+ return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE);
+}
- v->size = len;
- for (i = 0; i < len; ++i)
- v->contents[i] = Qnil;
- return (struct Lisp_Hash_Table *) v;
-}
-
-
struct window *
allocate_window ()
{
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));
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);
/* 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);
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
hash_clear (h)
struct Lisp_Hash_Table *h;
{
- if (XFASTINT (h->count) > 0)
+ if (h->count > 0)
{
int i, size = HASH_TABLE_SIZE (h);
AREF (h->index, i) = Qnil;
h->next_free = make_number (0);
- h->count = make_number (0);
+ h->count = 0;
}
}
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
{
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. */
(table)
Lisp_Object table;
{
- return check_hash_table (table)->count;
+ return make_number (check_hash_table (table)->count);
}
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;
/* 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;
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);
}