<feed xmlns='http://www.w3.org/2005/Atom'>
<title>emacs/src/alloc.c, branch feature/igc</title>
<subtitle>Emacs is the extensible, customizable, self-documenting real-time display editor. 
</subtitle>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/'/>
<entry>
<title>Alternative implementation for weak hash tables</title>
<updated>2026-02-02T21:29:19+00:00</updated>
<author>
<name>Helmut Eller</name>
</author>
<published>2026-02-02T21:29:19+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=51f686e688b3bd437c5e89ac6a3f213f9f990142'/>
<id>51f686e688b3bd437c5e89ac6a3f213f9f990142</id>
<content type='text'>
It can be enabled with -DUSE_EPHEMERON_POOL.

This variant uses the ephemeron pool and hence sovles the key-in-value
problem.

This version stores key/values pairs a vector-of-pairs instead of a
pair-of-vectors.  The same vector-of-pairs type is used for weak and
non-weak.  This avoids the code duplication used by the pair-of-vector
version; though it adds a bit of overhead to the non-weak code path.

* src/lisp.h: (struct vector_pair [!USE_EPHEMERON_POOL]): New type.
(struct pair_vector [USE_EPHEMERON_POOL]):New type.
(hash_table_kv): New typedef used to both version.
(hash_table_kv_create, hash_table_kv_free, hash_table_kv_key)
(hash_table_kv_value, hash_table_kv_set_key, hash_table_kv_set_value)
(hash_table_kv_null): New helpers
(struct Lisp_Hash_Table): Use a single field kv of type hash_table_kv
instead of two fields.
(HASH_KEY, HASH_VALUE, WEAK_HASH_KEY, WEAK_HASH_VALUE, DOHASH)
(DOHASH_WEAK, set_hash_key_slot, set_hash_value_slot)
(set_weak_hash_key_slot, set_weak_hash_value_slot): Adapt to
hash_table_kv.
(DOHASH [USE_EPHEMERON_POOL]): New version.
* src/igc.h (enum igc_obj_type): Add IGC_OBJ_PAIR_VECTOR,
IGC_OBJ_WEAK_KEY_PAIR_VECTOR, IGC_OBJ_WEAK_VALUE_PAIR_VECTOR,
IGC_OBJ_WEAK_OR_PAIR_VECTOR.
(igc_alloc_pair_vector): New prototype.
* src/igc.c (obj_type_names, set_header, dflt_scan_obj, thread_ap):
Handle new tpes.
(struct igc_thread, create_ephemeron_ap, create_thread_aps)
(igc_thread_remove): Add allocation point for ephemeron pool.
(struct igc, make_pool_aeph, make_igc): Add ephemeron pool.
(as_igc_header, fix_pair_vector, decode_ptr, encode_ptr)
(increment_ndeleted, splat_pair, fix_weak_key_pair, fix_weak_value_pair)
(fix_weak_or_pair, fix_weak_and_pair, scan_pair_vector)
(fix_weak_key_pair_vector, fix_weak_value_pair_vector)
(fix_weak_or_pair_vector, fix_weak_and_pair_vector): New helpers.
(fix_hash_table, fix_weak_hash_table_strong_part)
(fix_weak_hash_table_weak_part): Adapt to hash_table_kv.
(igc_alloc_pair_vector): New function.
* src/fns.c (maybe_resize_hash_table): Call maybe_resize_hash_table.
(Fgethash): Add assertion for HASH_UNUSED_ENTRY_KEY.
(Fhash_table_count): Take deleted entries into account.
(hash_table_kv_init, hash_table_kv_create)
(hash_table_kv_resize, hash_table_kv_free): New helpers.
(hash_table_kv_ndeleted, hash_table_ndeleted)
(hash_table_count, reclaim_deleted_entries)
(maybe_reclaim_deleted_entries): New helpers.
(make_hash_table, copy_hash_table, hash_table_thaw, hash_table_rehash)
(allocate_weak_hash_table_parts, make_weak_hash_table)
(maybe_resize_weak_hash_table): Adapt to hash_table_kv.
* src/alloc.c (cleanup_vector): Adapt to hash_table_kv.
* src/pdumper.c (hash_table_contents, hash_table_freeze)
(dump_hash_table): Adapt to hash_table_kv.
(dump_hash_table_kv_slot, dump_hash_table_kv, dump_hash_table_kv_part):
New helpers.
* src/print.c (print_object): Use Fhash_table_count instead
of the h-&gt;count field.
* test/src/fns-tests.el (ft--check-entries): Check hash-table-count.
(ft-weak-fixnums2, ft--test-weak-fixnums2): New test.
(ft--test-ephemeron-table): Better check for hash-table-count.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It can be enabled with -DUSE_EPHEMERON_POOL.

This variant uses the ephemeron pool and hence sovles the key-in-value
problem.

This version stores key/values pairs a vector-of-pairs instead of a
pair-of-vectors.  The same vector-of-pairs type is used for weak and
non-weak.  This avoids the code duplication used by the pair-of-vector
version; though it adds a bit of overhead to the non-weak code path.

* src/lisp.h: (struct vector_pair [!USE_EPHEMERON_POOL]): New type.
(struct pair_vector [USE_EPHEMERON_POOL]):New type.
(hash_table_kv): New typedef used to both version.
(hash_table_kv_create, hash_table_kv_free, hash_table_kv_key)
(hash_table_kv_value, hash_table_kv_set_key, hash_table_kv_set_value)
(hash_table_kv_null): New helpers
(struct Lisp_Hash_Table): Use a single field kv of type hash_table_kv
instead of two fields.
(HASH_KEY, HASH_VALUE, WEAK_HASH_KEY, WEAK_HASH_VALUE, DOHASH)
(DOHASH_WEAK, set_hash_key_slot, set_hash_value_slot)
(set_weak_hash_key_slot, set_weak_hash_value_slot): Adapt to
hash_table_kv.
(DOHASH [USE_EPHEMERON_POOL]): New version.
* src/igc.h (enum igc_obj_type): Add IGC_OBJ_PAIR_VECTOR,
IGC_OBJ_WEAK_KEY_PAIR_VECTOR, IGC_OBJ_WEAK_VALUE_PAIR_VECTOR,
IGC_OBJ_WEAK_OR_PAIR_VECTOR.
(igc_alloc_pair_vector): New prototype.
* src/igc.c (obj_type_names, set_header, dflt_scan_obj, thread_ap):
Handle new tpes.
(struct igc_thread, create_ephemeron_ap, create_thread_aps)
(igc_thread_remove): Add allocation point for ephemeron pool.
(struct igc, make_pool_aeph, make_igc): Add ephemeron pool.
(as_igc_header, fix_pair_vector, decode_ptr, encode_ptr)
(increment_ndeleted, splat_pair, fix_weak_key_pair, fix_weak_value_pair)
(fix_weak_or_pair, fix_weak_and_pair, scan_pair_vector)
(fix_weak_key_pair_vector, fix_weak_value_pair_vector)
(fix_weak_or_pair_vector, fix_weak_and_pair_vector): New helpers.
(fix_hash_table, fix_weak_hash_table_strong_part)
(fix_weak_hash_table_weak_part): Adapt to hash_table_kv.
(igc_alloc_pair_vector): New function.
* src/fns.c (maybe_resize_hash_table): Call maybe_resize_hash_table.
(Fgethash): Add assertion for HASH_UNUSED_ENTRY_KEY.
(Fhash_table_count): Take deleted entries into account.
(hash_table_kv_init, hash_table_kv_create)
(hash_table_kv_resize, hash_table_kv_free): New helpers.
(hash_table_kv_ndeleted, hash_table_ndeleted)
(hash_table_count, reclaim_deleted_entries)
(maybe_reclaim_deleted_entries): New helpers.
(make_hash_table, copy_hash_table, hash_table_thaw, hash_table_rehash)
(allocate_weak_hash_table_parts, make_weak_hash_table)
(maybe_resize_weak_hash_table): Adapt to hash_table_kv.
* src/alloc.c (cleanup_vector): Adapt to hash_table_kv.
* src/pdumper.c (hash_table_contents, hash_table_freeze)
(dump_hash_table): Adapt to hash_table_kv.
(dump_hash_table_kv_slot, dump_hash_table_kv, dump_hash_table_kv_part):
New helpers.
* src/print.c (print_object): Use Fhash_table_count instead
of the h-&gt;count field.
* test/src/fns-tests.el (ft--check-entries): Check hash-table-count.
(ft-weak-fixnums2, ft--test-weak-fixnums2): New test.
(ft--test-ephemeron-table): Better check for hash-table-count.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'master' into feature/igc</title>
<updated>2026-01-30T08:50:17+00:00</updated>
<author>
<name>Helmut Eller</name>
</author>
<published>2026-01-30T08:50:17+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=0fc6ab4597e5363d56f14500b475a98f2fbf5d98'/>
<id>0fc6ab4597e5363d56f14500b475a98f2fbf5d98</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>; * src/alloc.c (Fgarbage_collect_heapsize): Avoid compiler warning.</title>
<updated>2026-01-21T11:44:31+00:00</updated>
<author>
<name>Eli Zaretskii</name>
</author>
<published>2026-01-21T11:44:31+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=ac8bc9a2e2f2062bce8788ea5f058baa317953f1'/>
<id>ac8bc9a2e2f2062bce8788ea5f058baa317953f1</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>(garbage-collect-heapsize): New function</title>
<updated>2026-01-20T21:09:22+00:00</updated>
<author>
<name>Stefan Monnier</name>
</author>
<published>2026-01-13T18:41:55+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=4150c2e22e93ca6bdf682b0067d430e412db3688'/>
<id>4150c2e22e93ca6bdf682b0067d430e412db3688</id>
<content type='text'>
The info returned from `garbage-collect` is really handy to
track the evolution of the heap size, but sadly it's available only
at the cost of running a full GC, which has two big downsides:
it's slow, it affects what we're measuring, and it can't be used
in `post-gc-hook`.
So, this patch makes it available without running the GC.

* src/alloc.c (Fgarbage_collect_heapsize): New function, extracted from
`Fgarbage_collect`.
(Fgarbage_collect): Use it.
(syms_of_alloc): defsubr it.

* doc/lispref/internals.texi (Garbage Collection): Extract
documentation for it from that of `garbage-collect`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The info returned from `garbage-collect` is really handy to
track the evolution of the heap size, but sadly it's available only
at the cost of running a full GC, which has two big downsides:
it's slow, it affects what we're measuring, and it can't be used
in `post-gc-hook`.
So, this patch makes it available without running the GC.

* src/alloc.c (Fgarbage_collect_heapsize): New function, extracted from
`Fgarbage_collect`.
(Fgarbage_collect): Use it.
(syms_of_alloc): defsubr it.

* doc/lispref/internals.texi (Garbage Collection): Extract
documentation for it from that of `garbage-collect`.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge branch 'master' into feature/igc</title>
<updated>2026-01-02T20:01:55+00:00</updated>
<author>
<name>Helmut Eller</name>
</author>
<published>2026-01-02T20:01:55+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=e049ec683d3e504e2ae36b37500405b37a162786'/>
<id>e049ec683d3e504e2ae36b37500405b37a162786</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>; Add 2026 to copyright years.</title>
<updated>2026-01-01T12:54:34+00:00</updated>
<author>
<name>Sean Whitton</name>
</author>
<published>2026-01-01T12:54:34+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=c31f6adc31d48076c63ad82b83b2970e1b0d7b9b'/>
<id>c31f6adc31d48076c63ad82b83b2970e1b0d7b9b</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Include malloc.h early in alloc.c</title>
<updated>2025-12-07T23:45:20+00:00</updated>
<author>
<name>Paul Eggert</name>
</author>
<published>2025-12-07T23:21:46+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=2b7261d7f50410ab12b95c71674405f09a5e80fe'/>
<id>2b7261d7f50410ab12b95c71674405f09a5e80fe</id>
<content type='text'>
* src/alloc.c, src/gmalloc.c: Include &lt;malloc.h&gt; before &lt;stdlib.h&gt;.
This mimics include patterns elsewhere, and avoids a problem if
malloc.h declares realloc (i.e., rpl_realloc) early as extern,
whereas Gnulib stdlib.h declares it later as inline which means it
is extern inline, which clashes with gmalloc’s definition of
rpl_realloc when gmalloc.o is used.  Problem discovered when
building Emacs on Ubuntu 25.10 with "./configure CC='gcc -m32'
emacs_cv_struct_alignment=no gl_cv_header_working_stdalign_h=no".
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* src/alloc.c, src/gmalloc.c: Include &lt;malloc.h&gt; before &lt;stdlib.h&gt;.
This mimics include patterns elsewhere, and avoids a problem if
malloc.h declares realloc (i.e., rpl_realloc) early as extern,
whereas Gnulib stdlib.h declares it later as inline which means it
is extern inline, which clashes with gmalloc’s definition of
rpl_realloc when gmalloc.o is used.  Problem discovered when
building Emacs on Ubuntu 25.10 with "./configure CC='gcc -m32'
emacs_cv_struct_alignment=no gl_cv_header_working_stdalign_h=no".
</pre>
</div>
</content>
</entry>
<entry>
<title>Tally GMP allocations</title>
<updated>2025-12-01T14:58:11+00:00</updated>
<author>
<name>Helmut Eller</name>
</author>
<published>2025-12-01T14:37:57+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=43a000c31bc77cf84a700d1b35a8f6a3fd654c0c'/>
<id>43a000c31bc77cf84a700d1b35a8f6a3fd654c0c</id>
<content type='text'>
Without this, bignum allocations in the pidigits don't properly trigger
GC.  This patch changes the peak memory usage for the pidigits benchmark
by a factor of 6.  The benchmark also begins to spend much more time in
GC, as it should be:

|        | max rss   | elapsed time |
|--------+-----------+--------------|
| before | 392472 KB | 6.7 s        |
| after  | 58512 KB  | 32.93 s      |

* src/bignum.h (init_gmp_memory_functions): Declare new function.
* src/alloc.c (init_gmp_memory_functions): Implement it.
(xmalloc_for_gmp): New helper.
(xrealloc_for_gmp, xfree_for_gmp): Moved here from bignum.c.
* src/bignum.c (init_bignum): Call init_gmp_memory_functions.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Without this, bignum allocations in the pidigits don't properly trigger
GC.  This patch changes the peak memory usage for the pidigits benchmark
by a factor of 6.  The benchmark also begins to spend much more time in
GC, as it should be:

|        | max rss   | elapsed time |
|--------+-----------+--------------|
| before | 392472 KB | 6.7 s        |
| after  | 58512 KB  | 32.93 s      |

* src/bignum.h (init_gmp_memory_functions): Declare new function.
* src/alloc.c (init_gmp_memory_functions): Implement it.
(xmalloc_for_gmp): New helper.
(xrealloc_for_gmp, xfree_for_gmp): Moved here from bignum.c.
* src/bignum.c (init_bignum): Call init_gmp_memory_functions.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Add "flat" representation for bignums"</title>
<updated>2025-11-26T08:34:00+00:00</updated>
<author>
<name>Helmut Eller</name>
</author>
<published>2025-11-26T08:34:00+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=842c659b0bb52b110da877d8505d2d81765a8d2b'/>
<id>842c659b0bb52b110da877d8505d2d81765a8d2b</id>
<content type='text'>
This reverts commit 1a339d54ea7e6a005973c7eb392155b2ce7065d5.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 1a339d54ea7e6a005973c7eb392155b2ce7065d5.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add "flat" representation for bignums</title>
<updated>2025-11-25T19:21:28+00:00</updated>
<author>
<name>Helmut Eller</name>
</author>
<published>2025-11-25T19:21:28+00:00</published>
<link rel='alternate' type='text/html' href='https://jason.zzq.org/git/emacs/commit/?id=1a339d54ea7e6a005973c7eb392155b2ce7065d5'/>
<id>1a339d54ea7e6a005973c7eb392155b2ce7065d5</id>
<content type='text'>
If FLAT_BIGNUMS is defined, Lisp_Bignums are a vector of GMP limbs
instead of a mpz_t (i.e. pointer to limb array).

The primary difficulty was the changed return type of the bignum_val
function.  The idiom "*bignum_val (foo)" was used all over the place.
For the flat representation, it seems impossible to define bignum_val
such that it returns a pointer.  I changed the return type to a struct,
but that made it necessary to change the idiom to "bignum_val (foo).z".

* src/bignum.h (FLAT_BIGNUMS): Define if HAVE_MPS.
(struct Lisp_Bignums): Define alternative representation.
(struct bignum_val): New helper struct.
(bignum_val): Change return type and define different version for flat
bignums.
(bignum_integer): Define a separate version for flat bignums.
(BIGNUM_VAL): New macro.
(init_gmp_memory_functions): New.  Define the prototype here for a
function that is implemented in alloc.c.
(mpz_set_integer): Update for changed xbignum_val.
* src/bignum.c (init_bignum): Call init_gmp_memory_functions.
(make_bignum_from_mpz): New helper.
(make_bignum_bits, make_bignum_str): Adapted for flat bignums.
(bignum_to_double, bignum_to_uintmax, bignum_bufsize, bignum_to_c_string)
(get_random_bignum): Adapt to changed bignum_val.
* src/alloc.c (xmalloc_for_gmp): New.
(xrealloc_for_gmp, xfree_for_gmp): Moved here from bignum.c.  Call
tally_consing.
(init_gmp_memory_functions): New.
(cleanup_vector): Adapt to flat bignums.
* src/data.c (Fnatnump, arithcompare, Fminus, integer_remainder)
(Flogcount, Fash, expt_integer, Fadd1, Fsub1, Flognot): Adapt to changed
bignum_val.
* src/emacs-module.c (module_extract_big_integer): Adapt to changed
bignum_val.
* src/floatfns.c (Fabs, Flogb): Adapt to changed bignum_val.
* src/fns.c (Frandom, Ftake, Fntake, Fnthcdr, Fmemql, Feql)
(internal_equal_1, value_cmp, sxhash_bignum): Adapt to changed
bignum_val.
* src/igc.c (finalize_bignum, finalize_vector, maybe_finalize): Adapt to
flat bignums.
* src/pdumper.c (dump_bignum): Define separate version for flat bignums.
(dump_cold_bignum, dump_do_dump_relocation): Adapt to changed
bignum_val.
* src/timefns.c (ztrillion, ticks_hz_to_timespec, ticks_hz_hz_ticks)
(lispint_arith): Adapt to changed bignum_val.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If FLAT_BIGNUMS is defined, Lisp_Bignums are a vector of GMP limbs
instead of a mpz_t (i.e. pointer to limb array).

The primary difficulty was the changed return type of the bignum_val
function.  The idiom "*bignum_val (foo)" was used all over the place.
For the flat representation, it seems impossible to define bignum_val
such that it returns a pointer.  I changed the return type to a struct,
but that made it necessary to change the idiom to "bignum_val (foo).z".

* src/bignum.h (FLAT_BIGNUMS): Define if HAVE_MPS.
(struct Lisp_Bignums): Define alternative representation.
(struct bignum_val): New helper struct.
(bignum_val): Change return type and define different version for flat
bignums.
(bignum_integer): Define a separate version for flat bignums.
(BIGNUM_VAL): New macro.
(init_gmp_memory_functions): New.  Define the prototype here for a
function that is implemented in alloc.c.
(mpz_set_integer): Update for changed xbignum_val.
* src/bignum.c (init_bignum): Call init_gmp_memory_functions.
(make_bignum_from_mpz): New helper.
(make_bignum_bits, make_bignum_str): Adapted for flat bignums.
(bignum_to_double, bignum_to_uintmax, bignum_bufsize, bignum_to_c_string)
(get_random_bignum): Adapt to changed bignum_val.
* src/alloc.c (xmalloc_for_gmp): New.
(xrealloc_for_gmp, xfree_for_gmp): Moved here from bignum.c.  Call
tally_consing.
(init_gmp_memory_functions): New.
(cleanup_vector): Adapt to flat bignums.
* src/data.c (Fnatnump, arithcompare, Fminus, integer_remainder)
(Flogcount, Fash, expt_integer, Fadd1, Fsub1, Flognot): Adapt to changed
bignum_val.
* src/emacs-module.c (module_extract_big_integer): Adapt to changed
bignum_val.
* src/floatfns.c (Fabs, Flogb): Adapt to changed bignum_val.
* src/fns.c (Frandom, Ftake, Fntake, Fnthcdr, Fmemql, Feql)
(internal_equal_1, value_cmp, sxhash_bignum): Adapt to changed
bignum_val.
* src/igc.c (finalize_bignum, finalize_vector, maybe_finalize): Adapt to
flat bignums.
* src/pdumper.c (dump_bignum): Define separate version for flat bignums.
(dump_cold_bignum, dump_do_dump_relocation): Adapt to changed
bignum_val.
* src/timefns.c (ztrillion, ticks_hz_to_timespec, ticks_hz_hz_ticks)
(lispint_arith): Adapt to changed bignum_val.
</pre>
</div>
</content>
</entry>
</feed>
