[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
scratch/igc 62d7c958c83 2/2: Implement weak-value, weak-key-and-value ha
From: |
Pip Cet |
Subject: |
scratch/igc 62d7c958c83 2/2: Implement weak-value, weak-key-and-value hash tables |
Date: |
Mon, 1 Jul 2024 19:13:37 -0400 (EDT) |
branch: scratch/igc
commit 62d7c958c831faf0e8e881e3847ff27a4b78be11
Author: Pip Cet <pipcet@protonmail.com>
Commit: Pip Cet <pipcet@protonmail.com>
Implement weak-value, weak-key-and-value hash tables
* src/fns.c (allocate_weak_hash_table)
(maybe_resize_weak_hash_table): Set internal pointers according to
weakness. Remove unnecessary memset call.
* src/igc.c (fix_weak_hash_table_strong_part)
(fix_weak_hash_table_weak_part): Scan only the non-fixnum part of weak
tables.
(igc_alloc_weak_hash_table_strong_part)
(igc_alloc_weak_hash_table_weak_part): Use exact limits when determining
the size of weak hash tables.
---
src/fns.c | 53 ++++++++++++++++++++++++------
src/igc.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 133 insertions(+), 31 deletions(-)
diff --git a/src/fns.c b/src/fns.c
index a2dd2111faa..b9c43f61938 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5458,12 +5458,29 @@ allocate_weak_hash_table (hash_table_weakness_t weak,
ssize_t size, ssize_t inde
struct Lisp_Weak_Hash_Table *ret =
ALLOCATE_PLAIN_PSEUDOVECTOR (struct Lisp_Weak_Hash_Table,
PVEC_WEAK_HASH_TABLE);
ret->strong = igc_alloc_weak_hash_table_strong_part (weak, size, index_bits);
- ret->strong->hash = ret->strong->entries + 0;
- ret->strong->value = ret->strong->entries + 1 * size;
- ret->strong->next = ret->strong->entries + 2 * size;
- ret->strong->index = ret->strong->entries + 3 * size;
ret->weak = igc_alloc_weak_hash_table_weak_part (weak, size, index_bits);
- ret->strong->key = ret->weak->entries;
+ ret->strong->hash = ret->strong->entries + 0;
+ ret->strong->next = ret->strong->entries + 1 * size;
+ switch (weak)
+ {
+ case Weak_Key:
+ ret->strong->key = ret->weak->entries;
+ ret->strong->value = ret->strong->entries + 2 * size;
+ ret->strong->index = ret->strong->entries + 3 * size;
+ break;
+ case Weak_Value:
+ ret->strong->key = ret->strong->entries + 2 * size;
+ ret->strong->value = ret->weak->entries;
+ ret->strong->index = ret->strong->entries + 3 * size;
+ break;
+ case Weak_Key_And_Value:
+ ret->strong->key = ret->weak->entries;
+ ret->strong->value = ret->weak->entries + size;
+ ret->strong->index = ret->strong->entries + 2 * size;
+ break;
+ default:
+ emacs_abort ();
+ }
return ret;
}
@@ -5587,10 +5604,27 @@ maybe_resize_weak_hash_table (struct
Lisp_Weak_Hash_Table *h)
memcpy (strong, h->strong, sizeof *strong);
strong->hash = strong->entries + 0;
- strong->value = strong->entries + 1 * new_size;
- strong->next = strong->entries + 2 * new_size;
- strong->index = strong->entries + 3 * new_size;
- strong->key = weak->entries;
+ strong->next = strong->entries + 1 * new_size;
+ switch (h->strong->weakness)
+ {
+ case Weak_Key:
+ strong->key = weak->entries;
+ strong->value = strong->entries + 2 * new_size;
+ strong->index = strong->entries + 3 * new_size;
+ break;
+ case Weak_Value:
+ strong->key = strong->entries + 2 * new_size;
+ strong->value = weak->entries;
+ strong->index = strong->entries + 3 * new_size;
+ break;
+ case Weak_Key_And_Value:
+ strong->key = weak->entries;
+ strong->value = weak->entries + new_size;
+ strong->index = strong->entries + 2 * new_size;
+ break;
+ default:
+ emacs_abort ();
+ }
strong->count = make_fixnum (0);
for (ptrdiff_t i = 0; i < new_size - 1; i++)
@@ -5624,7 +5658,6 @@ maybe_resize_weak_hash_table (struct Lisp_Weak_Hash_Table
*h)
Fputhash (k, v, make_lisp_weak_hash_table (pseudo));
}
- memset (h->weak->entries, 0, 4 * old_size * sizeof
(h->weak->entries[0]));
h->strong = strong;
h->weak = weak;
}
diff --git a/src/igc.c b/src/igc.c
index 876fc0a3a0c..8dd10256131 100644
--- a/src/igc.c
+++ b/src/igc.c
@@ -1877,10 +1877,27 @@ fix_weak_hash_table_strong_part (mps_ss_t ss, struct
Lisp_Weak_Hash_Table_Strong
MPS_SCAN_BEGIN (ss)
{
if (t->weak && t->weak->strong == t)
- for (ssize_t i = 0; i < 4 * XFIXNUM (t->table_size); i++)
- {
- IGC_FIX12_OBJ (ss, &t->entries[i].lisp_object);
- }
+ {
+ ssize_t limit;
+ switch (t->weakness)
+ {
+ case Weak_Key:
+ limit = 3 * XFIXNUM (t->table_size);
+ break;
+ case Weak_Value:
+ limit = 3 * XFIXNUM (t->table_size);
+ break;
+ case Weak_Key_And_Value:
+ limit = 2 * XFIXNUM (t->table_size);
+ break;
+ default:
+ emacs_abort ();
+ }
+ for (ssize_t i = 2 * XFIXNUM (t->table_size); i < limit; i++)
+ {
+ IGC_FIX12_OBJ (ss, &t->entries[i].lisp_object);
+ }
+ }
}
MPS_SCAN_END (ss);
return MPS_RES_OK;
@@ -1894,22 +1911,42 @@ fix_weak_hash_table_weak_part (mps_ss_t ss, struct
Lisp_Weak_Hash_Table_Weak_Par
IGC_FIX12_RAW (ss, &w->strong);
struct Lisp_Weak_Hash_Table_Strong_Part *t = w->strong;
if (t && t->weak == w)
- for (ssize_t i = 0; i < 4 * XFIXNUM (t->table_size); i++)
- {
- bool was_nil = NILP (w->entries[i].lisp_object);
- IGC_FIX12_OBJ (ss, &w->entries[i].lisp_object);
- bool is_now_nil = NILP (w->entries[i].lisp_object);
+ {
+ ssize_t limit;
+ switch (t->weakness)
+ {
+ case Weak_Key:
+ limit = XFIXNUM (t->table_size);
+ break;
+ case Weak_Value:
+ limit = XFIXNUM (t->table_size);
+ break;
+ case Weak_Key_And_Value:
+ limit = 2 * XFIXNUM (t->table_size);
+ break;
+ default:
+ emacs_abort ();
+ }
- if (is_now_nil && !was_nil)
- {
- struct Lisp_Weak_Hash_Table pseudo_h =
- {
- .strong = t,
- .weak = w,
- };
- weak_hash_splat_from_table (&pseudo_h, i);
- }
- }
+ for (ssize_t i = 0; i < limit; i++)
+ {
+ bool was_nil = NILP (w->entries[i].lisp_object);
+ IGC_FIX12_OBJ (ss, &w->entries[i].lisp_object);
+ bool is_now_nil = NILP (w->entries[i].lisp_object);
+
+ if (is_now_nil && !was_nil)
+ {
+ struct Lisp_Weak_Hash_Table pseudo_h =
+ {
+ .strong = t,
+ .weak = w,
+ };
+ weak_hash_splat_from_table
+ (&pseudo_h, ((t->weakness == Weak_Key_And_Value) ?
+ (i % XFIXNUM (t->table_size)) : i);
+ }
+ }
+ }
}
MPS_SCAN_END (ss);
return MPS_RES_OK;
@@ -3747,14 +3784,46 @@ igc_make_hash_table_vec (size_t n)
struct Lisp_Weak_Hash_Table_Strong_Part *
igc_alloc_weak_hash_table_strong_part (hash_table_weakness_t weak, size_t
size, size_t index_bits)
{
- return alloc (sizeof (struct Lisp_Weak_Hash_Table_Strong_Part) + 5 * size *
sizeof (union Lisp_Weak_Hash_Table_Entry),
+ size_t total_size;
+ switch (weak)
+ {
+ case Weak_Key:
+ total_size = 3 * size + ((ptrdiff_t)1 << index_bits);
+ break;
+ case Weak_Value:
+ total_size = 3 * size + ((ptrdiff_t)1 << index_bits);
+ break;
+ case Weak_Key_And_Value:
+ total_size = 2 * size + ((ptrdiff_t)1 << index_bits);
+ break;
+ default:
+ emacs_abort ();
+ }
+ return alloc (sizeof (struct Lisp_Weak_Hash_Table_Strong_Part) +
+ total_size * sizeof (union Lisp_Weak_Hash_Table_Entry),
IGC_OBJ_WEAK_HASH_TABLE_STRONG_PART);
}
struct Lisp_Weak_Hash_Table_Weak_Part *
igc_alloc_weak_hash_table_weak_part (hash_table_weakness_t weak, size_t size,
size_t index_bits)
{
- return alloc (sizeof (struct Lisp_Weak_Hash_Table_Weak_Part) + 5 * size *
sizeof (union Lisp_Weak_Hash_Table_Entry),
+ size_t total_size;
+ switch (weak)
+ {
+ case Weak_Key:
+ total_size = size;
+ break;
+ case Weak_Value:
+ total_size = size;
+ break;
+ case Weak_Key_And_Value:
+ total_size = 2 * size;
+ break;
+ default:
+ emacs_abort ();
+ }
+ return alloc (sizeof (struct Lisp_Weak_Hash_Table_Weak_Part) +
+ total_size * sizeof (union Lisp_Weak_Hash_Table_Entry),
IGC_OBJ_WEAK_HASH_TABLE_WEAK_PART);
}