diff options
| author | Stefan Monnier | 2007-10-02 21:24:47 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2007-10-02 21:24:47 +0000 |
| commit | 878f97ffedc5b4fc785beac809c3d4392f531eca (patch) | |
| tree | 862d3533e412791972f9fd44fa4072d8173ff357 /src | |
| parent | 5b2f56dfa64ff88188ece5093589a52542163e46 (diff) | |
| download | emacs-878f97ffedc5b4fc785beac809c3d4392f531eca.tar.gz emacs-878f97ffedc5b4fc785beac809c3d4392f531eca.zip | |
* 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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/alloc.c | 45 | ||||
| -rw-r--r-- | src/fns.c | 18 | ||||
| -rw-r--r-- | src/lisp.h | 19 | ||||
| -rw-r--r-- | src/print.c | 2 |
5 files changed, 37 insertions, 55 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index be974e36d50..a30815d2bd8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,13 @@ | |||
| 1 | 2007-10-02 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2007-10-02 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * lisp.h (struct Lisp_Hash_Table): Move non-traced elements at the end. | ||
| 4 | Turn `count' into an integer. | ||
| 5 | * fns.c (make_hash_table, hash_put, hash_remove, hash_clear) | ||
| 6 | (sweep_weak_table, sweep_weak_hash_tables, Fhash_table_count): | ||
| 7 | * print.c (print_object) <HASH_TABLE_P>: `count' is an int. | ||
| 8 | * alloc.c (allocate_hash_table): Use ALLOCATE_PSEUDOVECTOR. | ||
| 9 | (mark_object) <HASH_TABLE_P>: Use mark_vectorlike. | ||
| 10 | |||
| 3 | * alloc.c (allocate_pseudovector): New fun. | 11 | * alloc.c (allocate_pseudovector): New fun. |
| 4 | (ALLOCATE_PSEUDOVECTOR): New macro. | 12 | (ALLOCATE_PSEUDOVECTOR): New macro. |
| 5 | (allocate_window, allocate_terminal, allocate_frame) | 13 | (allocate_window, allocate_terminal, allocate_frame) |
diff --git a/src/alloc.c b/src/alloc.c index 72e910f8faa..a3c9ec40f05 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -2986,20 +2986,12 @@ allocate_pseudovector (memlen, lisplen, tag) | |||
| 2986 | (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag)) | 2986 | (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag)) |
| 2987 | 2987 | ||
| 2988 | struct Lisp_Hash_Table * | 2988 | struct Lisp_Hash_Table * |
| 2989 | allocate_hash_table () | 2989 | allocate_hash_table (void) |
| 2990 | { | 2990 | { |
| 2991 | EMACS_INT len = VECSIZE (struct Lisp_Hash_Table); | 2991 | return ALLOCATE_PSEUDOVECTOR (struct Lisp_Hash_Table, count, PVEC_HASH_TABLE); |
| 2992 | struct Lisp_Vector *v = allocate_vectorlike (len); | 2992 | } |
| 2993 | EMACS_INT i; | ||
| 2994 | 2993 | ||
| 2995 | v->size = len; | ||
| 2996 | for (i = 0; i < len; ++i) | ||
| 2997 | v->contents[i] = Qnil; | ||
| 2998 | 2994 | ||
| 2999 | return (struct Lisp_Hash_Table *) v; | ||
| 3000 | } | ||
| 3001 | |||
| 3002 | |||
| 3003 | struct window * | 2995 | struct window * |
| 3004 | allocate_window () | 2996 | allocate_window () |
| 3005 | { | 2997 | { |
| @@ -5617,33 +5609,10 @@ mark_object (arg) | |||
| 5617 | else if (GC_HASH_TABLE_P (obj)) | 5609 | else if (GC_HASH_TABLE_P (obj)) |
| 5618 | { | 5610 | { |
| 5619 | struct Lisp_Hash_Table *h = XHASH_TABLE (obj); | 5611 | struct Lisp_Hash_Table *h = XHASH_TABLE (obj); |
| 5620 | 5612 | if (mark_vectorlike ((struct Lisp_Vector *)h)) | |
| 5621 | /* Stop if already marked. */ | 5613 | { /* If hash table is not weak, mark all keys and values. |
| 5622 | if (VECTOR_MARKED_P (h)) | 5614 | For weak tables, mark only the vector. */ |
| 5623 | break; | 5615 | if (GC_NILP (h->weak)) |
| 5624 | |||
| 5625 | /* Mark it. */ | ||
| 5626 | CHECK_LIVE (live_vector_p); | ||
| 5627 | VECTOR_MARK (h); | ||
| 5628 | |||
| 5629 | /* Mark contents. */ | ||
| 5630 | /* Do not mark next_free or next_weak. | ||
| 5631 | Being in the next_weak chain | ||
| 5632 | should not keep the hash table alive. | ||
| 5633 | No need to mark `count' since it is an integer. */ | ||
| 5634 | mark_object (h->test); | ||
| 5635 | mark_object (h->weak); | ||
| 5636 | mark_object (h->rehash_size); | ||
| 5637 | mark_object (h->rehash_threshold); | ||
| 5638 | mark_object (h->hash); | ||
| 5639 | mark_object (h->next); | ||
| 5640 | mark_object (h->index); | ||
| 5641 | mark_object (h->user_hash_function); | ||
| 5642 | mark_object (h->user_cmp_function); | ||
| 5643 | |||
| 5644 | /* If hash table is not weak, mark all keys and values. | ||
| 5645 | For weak tables, mark only the vector. */ | ||
| 5646 | if (GC_NILP (h->weak)) | ||
| 5647 | mark_object (h->key_and_value); | 5616 | mark_object (h->key_and_value); |
| 5648 | else | 5617 | else |
| 5649 | VECTOR_MARK (XVECTOR (h->key_and_value)); | 5618 | VECTOR_MARK (XVECTOR (h->key_and_value)); |
| @@ -4598,7 +4598,7 @@ make_hash_table (test, size, rehash_size, rehash_threshold, weak, | |||
| 4598 | h->weak = weak; | 4598 | h->weak = weak; |
| 4599 | h->rehash_threshold = rehash_threshold; | 4599 | h->rehash_threshold = rehash_threshold; |
| 4600 | h->rehash_size = rehash_size; | 4600 | h->rehash_size = rehash_size; |
| 4601 | h->count = make_number (0); | 4601 | h->count = 0; |
| 4602 | h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil); | 4602 | h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil); |
| 4603 | h->hash = Fmake_vector (size, Qnil); | 4603 | h->hash = Fmake_vector (size, Qnil); |
| 4604 | h->next = Fmake_vector (size, Qnil); | 4604 | h->next = Fmake_vector (size, Qnil); |
| @@ -4778,7 +4778,7 @@ hash_put (h, key, value, hash) | |||
| 4778 | 4778 | ||
| 4779 | /* Increment count after resizing because resizing may fail. */ | 4779 | /* Increment count after resizing because resizing may fail. */ |
| 4780 | maybe_resize_hash_table (h); | 4780 | maybe_resize_hash_table (h); |
| 4781 | h->count = make_number (XFASTINT (h->count) + 1); | 4781 | h->count++; |
| 4782 | 4782 | ||
| 4783 | /* Store key/value in the key_and_value vector. */ | 4783 | /* Store key/value in the key_and_value vector. */ |
| 4784 | i = XFASTINT (h->next_free); | 4784 | i = XFASTINT (h->next_free); |
| @@ -4834,8 +4834,8 @@ hash_remove (h, key) | |||
| 4834 | HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil; | 4834 | HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil; |
| 4835 | HASH_NEXT (h, i) = h->next_free; | 4835 | HASH_NEXT (h, i) = h->next_free; |
| 4836 | h->next_free = make_number (i); | 4836 | h->next_free = make_number (i); |
| 4837 | h->count = make_number (XFASTINT (h->count) - 1); | 4837 | h->count--; |
| 4838 | xassert (XINT (h->count) >= 0); | 4838 | xassert (h->count >= 0); |
| 4839 | break; | 4839 | break; |
| 4840 | } | 4840 | } |
| 4841 | else | 4841 | else |
| @@ -4853,7 +4853,7 @@ void | |||
| 4853 | hash_clear (h) | 4853 | hash_clear (h) |
| 4854 | struct Lisp_Hash_Table *h; | 4854 | struct Lisp_Hash_Table *h; |
| 4855 | { | 4855 | { |
| 4856 | if (XFASTINT (h->count) > 0) | 4856 | if (h->count > 0) |
| 4857 | { | 4857 | { |
| 4858 | int i, size = HASH_TABLE_SIZE (h); | 4858 | int i, size = HASH_TABLE_SIZE (h); |
| 4859 | 4859 | ||
| @@ -4869,7 +4869,7 @@ hash_clear (h) | |||
| 4869 | AREF (h->index, i) = Qnil; | 4869 | AREF (h->index, i) = Qnil; |
| 4870 | 4870 | ||
| 4871 | h->next_free = make_number (0); | 4871 | h->next_free = make_number (0); |
| 4872 | h->count = make_number (0); | 4872 | h->count = 0; |
| 4873 | } | 4873 | } |
| 4874 | } | 4874 | } |
| 4875 | 4875 | ||
| @@ -4939,7 +4939,7 @@ sweep_weak_table (h, remove_entries_p) | |||
| 4939 | HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil; | 4939 | HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil; |
| 4940 | HASH_HASH (h, i) = Qnil; | 4940 | HASH_HASH (h, i) = Qnil; |
| 4941 | 4941 | ||
| 4942 | h->count = make_number (XFASTINT (h->count) - 1); | 4942 | h->count--; |
| 4943 | } | 4943 | } |
| 4944 | else | 4944 | else |
| 4945 | { | 4945 | { |
| @@ -5005,7 +5005,7 @@ sweep_weak_hash_tables () | |||
| 5005 | if (h->size & ARRAY_MARK_FLAG) | 5005 | if (h->size & ARRAY_MARK_FLAG) |
| 5006 | { | 5006 | { |
| 5007 | /* TABLE is marked as used. Sweep its contents. */ | 5007 | /* TABLE is marked as used. Sweep its contents. */ |
| 5008 | if (XFASTINT (h->count) > 0) | 5008 | if (h->count > 0) |
| 5009 | sweep_weak_table (h, 1); | 5009 | sweep_weak_table (h, 1); |
| 5010 | 5010 | ||
| 5011 | /* Add table to the list of used weak hash tables. */ | 5011 | /* Add table to the list of used weak hash tables. */ |
| @@ -5340,7 +5340,7 @@ DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0, | |||
| 5340 | (table) | 5340 | (table) |
| 5341 | Lisp_Object table; | 5341 | Lisp_Object table; |
| 5342 | { | 5342 | { |
| 5343 | return check_hash_table (table)->count; | 5343 | return make_number (check_hash_table (table)->count); |
| 5344 | } | 5344 | } |
| 5345 | 5345 | ||
| 5346 | 5346 | ||
diff --git a/src/lisp.h b/src/lisp.h index 5917e918b31..6dd24813f0e 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1019,13 +1019,6 @@ struct Lisp_Hash_Table | |||
| 1019 | ratio, a float. */ | 1019 | ratio, a float. */ |
| 1020 | Lisp_Object rehash_threshold; | 1020 | Lisp_Object rehash_threshold; |
| 1021 | 1021 | ||
| 1022 | /* Number of key/value entries in the table. */ | ||
| 1023 | Lisp_Object count; | ||
| 1024 | |||
| 1025 | /* Vector of keys and values. The key of item I is found at index | ||
| 1026 | 2 * I, the value is found at index 2 * I + 1. */ | ||
| 1027 | Lisp_Object key_and_value; | ||
| 1028 | |||
| 1029 | /* Vector of hash codes.. If hash[I] is nil, this means that that | 1022 | /* Vector of hash codes.. If hash[I] is nil, this means that that |
| 1030 | entry I is unused. */ | 1023 | entry I is unused. */ |
| 1031 | Lisp_Object hash; | 1024 | Lisp_Object hash; |
| @@ -1049,6 +1042,18 @@ struct Lisp_Hash_Table | |||
| 1049 | /* User-supplied key comparison function, or nil. */ | 1042 | /* User-supplied key comparison function, or nil. */ |
| 1050 | Lisp_Object user_cmp_function; | 1043 | Lisp_Object user_cmp_function; |
| 1051 | 1044 | ||
| 1045 | /* Only the fields above are traced normally by the GC. The ones below | ||
| 1046 | `count'. are special and are either ignored by the GC or traced in | ||
| 1047 | a special way (e.g. because of weakness). */ | ||
| 1048 | |||
| 1049 | /* Number of key/value entries in the table. */ | ||
| 1050 | unsigned int count; | ||
| 1051 | |||
| 1052 | /* Vector of keys and values. The key of item I is found at index | ||
| 1053 | 2 * I, the value is found at index 2 * I + 1. | ||
| 1054 | This is gc_marked specially if the table is weak. */ | ||
| 1055 | Lisp_Object key_and_value; | ||
| 1056 | |||
| 1052 | /* Next weak hash table if this is a weak hash table. The head | 1057 | /* Next weak hash table if this is a weak hash table. The head |
| 1053 | of the list is in weak_hash_tables. */ | 1058 | of the list is in weak_hash_tables. */ |
| 1054 | struct Lisp_Hash_Table *next_weak; | 1059 | struct Lisp_Hash_Table *next_weak; |
diff --git a/src/print.c b/src/print.c index 911422ac25b..ccb2d6e8c45 100644 --- a/src/print.c +++ b/src/print.c | |||
| @@ -1987,7 +1987,7 @@ print_object (obj, printcharfun, escapeflag) | |||
| 1987 | PRINTCHAR (' '); | 1987 | PRINTCHAR (' '); |
| 1988 | strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun, 0); | 1988 | strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun, 0); |
| 1989 | PRINTCHAR (' '); | 1989 | PRINTCHAR (' '); |
| 1990 | sprintf (buf, "%ld/%ld", (long) XFASTINT (h->count), | 1990 | sprintf (buf, "%ld/%ld", (long) h->count, |
| 1991 | (long) XVECTOR (h->next)->size); | 1991 | (long) XVECTOR (h->next)->size); |
| 1992 | strout (buf, -1, -1, printcharfun, 0); | 1992 | strout (buf, -1, -1, printcharfun, 0); |
| 1993 | } | 1993 | } |