Exemple #1
0
static void
move_disappearing_links (scm_t_weak_entry *from, scm_t_weak_entry *to,
                         SCM key, SCM value, scm_t_weak_table_kind kind)
{
  if ((kind == SCM_WEAK_TABLE_KIND_KEY || kind == SCM_WEAK_TABLE_KIND_BOTH)
      && SCM_HEAP_OBJECT_P (key))
    {
#ifdef HAVE_GC_MOVE_DISAPPEARING_LINK
      GC_move_disappearing_link ((GC_PTR) &from->key, (GC_PTR) &to->key);
#else
      GC_unregister_disappearing_link (&from->key);
      SCM_I_REGISTER_DISAPPEARING_LINK (&to->key, SCM2PTR (key));
#endif
    }

  if ((kind == SCM_WEAK_TABLE_KIND_VALUE || kind == SCM_WEAK_TABLE_KIND_BOTH)
      && SCM_HEAP_OBJECT_P (value))
    {
#ifdef HAVE_GC_MOVE_DISAPPEARING_LINK
      GC_move_disappearing_link ((GC_PTR) &from->value, (GC_PTR) &to->value);
#else
      GC_unregister_disappearing_link (&from->value);
      SCM_I_REGISTER_DISAPPEARING_LINK (&to->value, SCM2PTR (value));
#endif
    }
}
Exemple #2
0
static SCM
make_weak_vector (size_t len, SCM fill)
#define FUNC_NAME "make-weak-vector"
{
    SCM wv;
    size_t j;

    SCM_ASSERT_RANGE (1, scm_from_size_t (len), len <= VECTOR_MAX_LENGTH);

    if (SCM_UNBNDP (fill))
        fill = SCM_UNSPECIFIED;

    wv = SCM_PACK_POINTER (scm_gc_malloc_pointerless ((len + 1) * sizeof (SCM),
    "weak vector"));

    SCM_SET_CELL_WORD_0 (wv, (len << 8) | scm_tc7_wvect);

    if (SCM_HEAP_OBJECT_P (fill))
    {
        memset (SCM_I_VECTOR_WELTS (wv), 0, len * sizeof (SCM));
        for (j = 0; j < len; j++)
            scm_c_weak_vector_set_x (wv, j, fill);
    }
    else
        for (j = 0; j < len; j++)
            SCM_SIMPLE_VECTOR_SET (wv, j, fill);

    return wv;
}
Exemple #3
0
static void
move_weak_entry (scm_t_weak_entry *from, scm_t_weak_entry *to)
{
  if (from->hash)
    {
      scm_t_weak_entry copy;
      
      copy_weak_entry (from, &copy);
      to->hash = copy.hash;
      to->key = copy.key;

      if (copy.key && SCM_HEAP_OBJECT_P (SCM_PACK (copy.key)))
        {
#ifdef HAVE_GC_MOVE_DISAPPEARING_LINK
          GC_move_disappearing_link ((GC_PTR) &from->key, (GC_PTR) &to->key);
#else
          GC_unregister_disappearing_link ((GC_PTR) &from->key);
          SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &to->key,
                                            (GC_PTR) to->key);
#endif
        }
    }
  else
    {
      to->hash = 0;
      to->key = 0;
    }
}
Exemple #4
0
static void
register_disappearing_links (scm_t_weak_entry *entry,
                             SCM k, SCM v,
                             scm_t_weak_table_kind kind)
{
  if (SCM_UNPACK (k) && SCM_HEAP_OBJECT_P (k)
      && (kind == SCM_WEAK_TABLE_KIND_KEY
          || kind == SCM_WEAK_TABLE_KIND_BOTH))
    SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &entry->key,
                                      (GC_PTR) SCM2PTR (k));

  if (SCM_UNPACK (v) && SCM_HEAP_OBJECT_P (v)
      && (kind == SCM_WEAK_TABLE_KIND_VALUE
          || kind == SCM_WEAK_TABLE_KIND_BOTH))
    SCM_I_REGISTER_DISAPPEARING_LINK ((GC_PTR) &entry->value,
                                      (GC_PTR) SCM2PTR (v));
}
Exemple #5
0
static void
move_weak_entry (scm_t_weak_entry *from, scm_t_weak_entry *to)
{
  if (from->hash)
    {
      scm_t_weak_entry copy;
      
      copy_weak_entry (from, &copy);
      to->hash = copy.hash;
      to->key = copy.key;

      if (copy.key && SCM_HEAP_OBJECT_P (SCM_PACK (copy.key)))
        GC_move_disappearing_link ((void **) &from->key, (void **) &to->key);
    }
  else
    {
      to->hash = 0;
      to->key = 0;
    }
}
Exemple #6
0
static void
resize_set (scm_t_weak_set *set)
{
  scm_t_weak_entry *old_entries, *new_entries;
  int new_size_index;
  unsigned long old_size, new_size, old_k;

  do 
    {
      new_size_index = compute_size_index (set);
      if (new_size_index == set->size_index)
        return;
      new_size = hashset_size[new_size_index];
      new_entries = scm_gc_malloc_pointerless (new_size * sizeof(scm_t_weak_entry),
                                               "weak set");
    }
  while (!is_acceptable_size_index (set, new_size_index));

  old_entries = set->entries;
  old_size = set->size;

  memset (new_entries, 0, new_size * sizeof(scm_t_weak_entry));

  set->size_index = new_size_index;
  set->size = new_size;
  if (new_size_index <= set->min_size_index)
    set->lower = 0;
  else
    set->lower = new_size / 5;
  set->upper = 9 * new_size / 10;
  set->n_items = 0;
  set->entries = new_entries;

  for (old_k = 0; old_k < old_size; old_k++)
    {
      scm_t_weak_entry copy;
      unsigned long new_k, distance;

      if (!old_entries[old_k].hash)
        continue;
      
      copy_weak_entry (&old_entries[old_k], &copy);
      
      if (!copy.key)
        continue;
      
      new_k = hash_to_index (copy.hash, new_size);

      for (distance = 0; ; distance++, new_k = (new_k + 1) % new_size)
        {
          unsigned long other_hash = new_entries[new_k].hash;

          if (!other_hash)
            /* Found an empty entry. */
            break;

          /* Displace the entry if our distance is less, otherwise keep
             looking. */
          if (entry_distance (other_hash, new_k, new_size) < distance)
            {
              rob_from_rich (set, new_k);
              break;
            }
        }
          
      set->n_items++;
      new_entries[new_k].hash = copy.hash;
      new_entries[new_k].key = copy.key;

      if (SCM_HEAP_OBJECT_P (SCM_PACK (copy.key)))
        SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &new_entries[new_k].key,
                                          (void *) new_entries[new_k].key);
    }
}