diff options
| author | Ethan Kong | 2024-10-19 12:43:27 +0800 |
|---|---|---|
| committer | Eli Zaretskii | 2024-11-09 10:56:54 +0200 |
| commit | 200214ca68f00722bf906bbf2a2afa81d139d5dc (patch) | |
| tree | bba78233ccb13fca8c144889e239db336a68cbf5 /src/fns.c | |
| parent | 766ec1f9e08e6f2c7c22b514a6f2e65f79341023 (diff) | |
| download | emacs-200214ca68f00722bf906bbf2a2afa81d139d5dc.tar.gz emacs-200214ca68f00722bf906bbf2a2afa81d139d5dc.zip | |
Fix 'internal_equal' so that it uses at most one hash table
The old implementation passed the hash table by value in
recursive tests, which would cause each recursive level to
initialize its own hash table, causing excess memory usage.
* src/fns.c (internal_equal): Delegate to 'internal_equal_1'.
(internal_equal_1): New function; body from old 'internal_equal'.
Pass the hash table argument by reference instead of by value.
(Bug#73883)
Diffstat (limited to 'src/fns.c')
| -rw-r--r-- | src/fns.c | 23 |
1 files changed, 15 insertions, 8 deletions
| @@ -2823,8 +2823,8 @@ static ptrdiff_t hash_lookup_with_hash (struct Lisp_Hash_Table *h, | |||
| 2823 | if EQUAL_KIND == EQUAL_NO_QUIT. */ | 2823 | if EQUAL_KIND == EQUAL_NO_QUIT. */ |
| 2824 | 2824 | ||
| 2825 | static bool | 2825 | static bool |
| 2826 | internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | 2826 | internal_equal_1 (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, |
| 2827 | int depth, Lisp_Object ht) | 2827 | int depth, Lisp_Object *ht) |
| 2828 | { | 2828 | { |
| 2829 | tail_recurse: | 2829 | tail_recurse: |
| 2830 | if (depth > 10) | 2830 | if (depth > 10) |
| @@ -2832,13 +2832,13 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2832 | eassert (equal_kind != EQUAL_NO_QUIT); | 2832 | eassert (equal_kind != EQUAL_NO_QUIT); |
| 2833 | if (depth > 200) | 2833 | if (depth > 200) |
| 2834 | error ("Stack overflow in equal"); | 2834 | error ("Stack overflow in equal"); |
| 2835 | if (NILP (ht)) | 2835 | if (NILP (*ht)) |
| 2836 | ht = CALLN (Fmake_hash_table, QCtest, Qeq); | 2836 | *ht = CALLN (Fmake_hash_table, QCtest, Qeq); |
| 2837 | switch (XTYPE (o1)) | 2837 | switch (XTYPE (o1)) |
| 2838 | { | 2838 | { |
| 2839 | case Lisp_Cons: case Lisp_Vectorlike: | 2839 | case Lisp_Cons: case Lisp_Vectorlike: |
| 2840 | { | 2840 | { |
| 2841 | struct Lisp_Hash_Table *h = XHASH_TABLE (ht); | 2841 | struct Lisp_Hash_Table *h = XHASH_TABLE (*ht); |
| 2842 | hash_hash_t hash = hash_from_key (h, o1); | 2842 | hash_hash_t hash = hash_from_key (h, o1); |
| 2843 | ptrdiff_t i = hash_lookup_with_hash (h, o1, hash); | 2843 | ptrdiff_t i = hash_lookup_with_hash (h, o1, hash); |
| 2844 | if (i >= 0) | 2844 | if (i >= 0) |
| @@ -2888,8 +2888,8 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2888 | { | 2888 | { |
| 2889 | if (! CONSP (o2)) | 2889 | if (! CONSP (o2)) |
| 2890 | return false; | 2890 | return false; |
| 2891 | if (! internal_equal (XCAR (o1), XCAR (o2), | 2891 | if (! internal_equal_1 (XCAR (o1), XCAR (o2), |
| 2892 | equal_kind, depth + 1, ht)) | 2892 | equal_kind, depth + 1, ht)) |
| 2893 | return false; | 2893 | return false; |
| 2894 | o2 = XCDR (o2); | 2894 | o2 = XCDR (o2); |
| 2895 | if (EQ (XCDR (o1), o2)) | 2895 | if (EQ (XCDR (o1), o2)) |
| @@ -2964,7 +2964,7 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2964 | Lisp_Object v1, v2; | 2964 | Lisp_Object v1, v2; |
| 2965 | v1 = AREF (o1, i); | 2965 | v1 = AREF (o1, i); |
| 2966 | v2 = AREF (o2, i); | 2966 | v2 = AREF (o2, i); |
| 2967 | if (!internal_equal (v1, v2, equal_kind, depth + 1, ht)) | 2967 | if (!internal_equal_1 (v1, v2, equal_kind, depth + 1, ht)) |
| 2968 | return false; | 2968 | return false; |
| 2969 | } | 2969 | } |
| 2970 | return true; | 2970 | return true; |
| @@ -2985,6 +2985,13 @@ internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | |||
| 2985 | return false; | 2985 | return false; |
| 2986 | } | 2986 | } |
| 2987 | 2987 | ||
| 2988 | static bool | ||
| 2989 | internal_equal (Lisp_Object o1, Lisp_Object o2, enum equal_kind equal_kind, | ||
| 2990 | int depth, Lisp_Object ht) | ||
| 2991 | { | ||
| 2992 | return internal_equal_1 (o1, o2, equal_kind, depth, &ht); | ||
| 2993 | } | ||
| 2994 | |||
| 2988 | /* Return -1/0/1 for the </=/> lexicographic relation between bool-vectors. */ | 2995 | /* Return -1/0/1 for the </=/> lexicographic relation between bool-vectors. */ |
| 2989 | static int | 2996 | static int |
| 2990 | bool_vector_cmp (Lisp_Object a, Lisp_Object b) | 2997 | bool_vector_cmp (Lisp_Object a, Lisp_Object b) |