emacs-diffs
[Top][All Lists]
Advanced

[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);
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]