2018-06-20 19:17:06 +02:00
|
|
|
|
/* Copyright 2011-2014,2017-2018
|
2018-06-20 20:01:49 +02:00
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
|
|
|
|
This file is part of Guile.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is free software: you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU Lesser General Public License as published
|
|
|
|
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
|
|
Guile is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with Guile. If not, see
|
|
|
|
|
|
<https://www.gnu.org/licenses/>. */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
|
# include <config.h>
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "alist.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "bdw-gc.h"
|
|
|
|
|
|
#include "eval.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "finalizers.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "gsubr.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "hash.h"
|
|
|
|
|
|
#include "numbers.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include "pairs.h"
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "ports.h"
|
|
|
|
|
|
#include "procs.h"
|
|
|
|
|
|
#include "threads.h"
|
|
|
|
|
|
#include "weak-list.h"
|
2018-06-20 18:31:24 +02:00
|
|
|
|
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "weak-table.h"
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2018-06-20 18:31:24 +02:00
|
|
|
|
#include <gc/gc_typed.h>
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
/* Weak Tables
|
|
|
|
|
|
|
|
|
|
|
|
This file implements weak hash tables. Weak hash tables are
|
|
|
|
|
|
generally used when you want to augment some object with additional
|
|
|
|
|
|
data, but when you don't have space to store the data in the object.
|
|
|
|
|
|
For example, procedure properties are implemented with weak tables.
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
This is a normal bucket-and-chain hash table, except that the chain
|
|
|
|
|
|
entries are allocated in such a way that the GC doesn't trace the
|
|
|
|
|
|
weak values. For doubly-weak tables, this means that the entries are
|
|
|
|
|
|
allocated as an "atomic" piece of memory. Key-weak and value-weak
|
|
|
|
|
|
tables use a special GC kind with a custom mark procedure. When
|
|
|
|
|
|
items are added weakly into table, a disappearing link is registered
|
|
|
|
|
|
to their locations. If the referent is collected, then that link
|
|
|
|
|
|
will be zeroed out.
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
An entry in the table consists of the key and the value, together
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
with the hash code of the key.
|
|
|
|
|
|
|
|
|
|
|
|
Note that since the weak references are stored in an atomic region
|
|
|
|
|
|
with disappearing links, they need to be accessed with the GC alloc
|
|
|
|
|
|
lock. `read_weak_entry' will do that for you. The hash code itself
|
|
|
|
|
|
can be read outside the lock, though.
|
2011-10-23 23:23:47 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
typedef struct scm_weak_entry scm_t_weak_entry;
|
|
|
|
|
|
|
|
|
|
|
|
struct scm_weak_entry {
|
2011-10-23 23:23:47 +02:00
|
|
|
|
unsigned long hash;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry *next;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_t_bits key;
|
|
|
|
|
|
scm_t_bits value;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
};
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct weak_entry_data {
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry *entry;
|
|
|
|
|
|
scm_t_bits key;
|
|
|
|
|
|
scm_t_bits value;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static void*
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
do_read_weak_entry (void *data)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct weak_entry_data *e = data;
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
e->key = e->entry->key;
|
|
|
|
|
|
e->value = e->entry->value;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
read_weak_entry (scm_t_weak_entry *entry, scm_t_bits *key, scm_t_bits *value)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct weak_entry_data data;
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
data.entry = entry;
|
|
|
|
|
|
GC_call_with_alloc_lock (do_read_weak_entry, &data);
|
|
|
|
|
|
|
|
|
|
|
|
*key = data.key;
|
|
|
|
|
|
*value = data.value;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
register_disappearing_links (scm_t_weak_entry *entry,
|
|
|
|
|
|
SCM k, SCM v,
|
|
|
|
|
|
scm_t_weak_table_kind kind)
|
|
|
|
|
|
{
|
2011-10-24 18:13:51 +02:00
|
|
|
|
if (SCM_UNPACK (k) && SCM_HEAP_OBJECT_P (k)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
&& (kind == SCM_WEAK_TABLE_KIND_KEY
|
|
|
|
|
|
|| kind == SCM_WEAK_TABLE_KIND_BOTH))
|
2012-07-06 16:52:54 +02:00
|
|
|
|
SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &entry->key,
|
|
|
|
|
|
SCM2PTR (k));
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2011-10-24 18:13:51 +02:00
|
|
|
|
if (SCM_UNPACK (v) && SCM_HEAP_OBJECT_P (v)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
&& (kind == SCM_WEAK_TABLE_KIND_VALUE
|
|
|
|
|
|
|| kind == SCM_WEAK_TABLE_KIND_BOTH))
|
2012-07-06 16:52:54 +02:00
|
|
|
|
SCM_I_REGISTER_DISAPPEARING_LINK ((void **) &entry->value,
|
|
|
|
|
|
SCM2PTR (v));
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
unregister_disappearing_links (scm_t_weak_entry *entry,
|
|
|
|
|
|
scm_t_weak_table_kind kind)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (kind == SCM_WEAK_TABLE_KIND_KEY || kind == SCM_WEAK_TABLE_KIND_BOTH)
|
2012-07-06 16:52:54 +02:00
|
|
|
|
GC_unregister_disappearing_link ((void **) &entry->key);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
if (kind == SCM_WEAK_TABLE_KIND_VALUE || kind == SCM_WEAK_TABLE_KIND_BOTH)
|
2012-07-06 16:52:54 +02:00
|
|
|
|
GC_unregister_disappearing_link ((void **) &entry->value);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry **buckets; /* the data */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_i_pthread_mutex_t lock; /* the lock */
|
|
|
|
|
|
scm_t_weak_table_kind kind; /* what kind of table it is */
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unsigned long n_buckets; /* total number of buckets. */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
unsigned long n_items; /* number of items in table */
|
|
|
|
|
|
unsigned long lower; /* when to shrink */
|
|
|
|
|
|
unsigned long upper; /* when to grow */
|
|
|
|
|
|
int size_index; /* index into hashtable_size */
|
|
|
|
|
|
int min_size_index; /* minimum size_index */
|
2017-10-31 08:43:09 +01:00
|
|
|
|
GC_word last_gc_no;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
} scm_t_weak_table;
|
|
|
|
|
|
|
|
|
|
|
|
|
refactor tc7 and tc16 checks
* libguile/tags.h (SCM_HAS_TYP7, SCM_HAS_TYP7S, SCM_HAS_TYP16): New
macros.
* libguile/bytevectors.h (SCM_BYTEVECTOR_P):
* libguile/control.h (SCM_PROMPT_P):
* libguile/filesys.h (SCM_DIRP):
* libguile/fluids.h (SCM_WITH_FLUIDS_P, SCM_FLUID_P)
(SCM_I_DYNAMIC_STATE_P):
* libguile/foreign.h (SCM_POINTER_P):
* libguile/fports.h (SCM_FPORTP):
* libguile/frames.h (SCM_VM_FRAME_P):
* libguile/hashtab.h (SCM_HASHTABLE_P):
* libguile/inline.h (scm_get_byte_or_eof):
* libguile/numbers.h (SCM_REALP, SCM_BIGP, SCM_COMPLEXP, SCM_FRACTIONP):
* libguile/objcodes.h (SCM_OBJCODE_P):
* libguile/ports.h (SCM_OUTPUT_PORT_P):
* libguile/programs.h (SCM_PROGRAM_P):
* libguile/smob.h (SCM_SMOB_PREDICATE):
* libguile/srfi-14.h (SCM_CHARSETP):
* libguile/strings.c (IS_STRING):
* libguile/strports.h (SCM_STRPORTP):
* libguile/symbols.h (scm_is_symbol):
* libguile/variable.h (SCM_VARIABLEP):
* libguile/vectors.h (SCM_I_IS_VECTOR, SCM_I_IS_NONWEAK_VECTOR):
* libguile/vm-i-system.c (call, tail-call, mv-call)
* libguile/vm.h (SCM_VM_P, SCM_VM_CONT_P):
* libguile/weak-set.c (SCM_WEAK_SET_P):
* libguile/weak-table.c (SCM_WEAK_TABLE_P):
* libguile/weak-vector.h (SCM_I_WVECTP): Use them.
2011-10-24 17:34:47 +02:00
|
|
|
|
#define SCM_WEAK_TABLE_P(x) (SCM_HAS_TYP7 (x, scm_tc7_weak_table))
|
2011-10-23 23:23:47 +02:00
|
|
|
|
#define SCM_VALIDATE_WEAK_TABLE(pos, arg) \
|
|
|
|
|
|
SCM_MAKE_VALIDATE_MSG (pos, arg, WEAK_TABLE_P, "weak-table")
|
|
|
|
|
|
#define SCM_WEAK_TABLE(x) ((scm_t_weak_table *) SCM_CELL_WORD_1 (x))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-10-31 09:10:55 +01:00
|
|
|
|
/* GC descriptors for the various kinds of scm_t_weak_entry. */
|
|
|
|
|
|
static GC_descr weak_key_descr;
|
|
|
|
|
|
static GC_descr weak_value_descr;
|
|
|
|
|
|
static GC_descr doubly_weak_descr;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
static scm_t_weak_entry *
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
allocate_entry (scm_t_weak_table_kind kind)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_entry *ret;
|
|
|
|
|
|
|
|
|
|
|
|
switch (kind)
|
|
|
|
|
|
{
|
|
|
|
|
|
case SCM_WEAK_TABLE_KIND_KEY:
|
2017-10-31 09:10:55 +01:00
|
|
|
|
ret = GC_malloc_explicitly_typed (sizeof (*ret), weak_key_descr);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
break;
|
|
|
|
|
|
case SCM_WEAK_TABLE_KIND_VALUE:
|
2017-10-31 09:10:55 +01:00
|
|
|
|
ret = GC_malloc_explicitly_typed (sizeof (*ret), weak_value_descr);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
break;
|
|
|
|
|
|
case SCM_WEAK_TABLE_KIND_BOTH:
|
2017-10-31 09:10:55 +01:00
|
|
|
|
ret = GC_malloc_explicitly_typed (sizeof (*ret), doubly_weak_descr);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
abort ();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
static void
|
|
|
|
|
|
add_entry (scm_t_weak_table *table, scm_t_weak_entry *entry)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned long bucket = entry->hash % table->n_buckets;
|
|
|
|
|
|
entry->next = table->buckets[bucket];
|
|
|
|
|
|
table->buckets[bucket] = entry;
|
|
|
|
|
|
table->n_items++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Growing or shrinking is triggered when the load factor
|
|
|
|
|
|
*
|
|
|
|
|
|
* L = N / S (N: number of items in table, S: bucket vector length)
|
|
|
|
|
|
*
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
* passes an upper limit of 0.9 or a lower limit of 0.25.
|
2011-10-23 23:23:47 +02:00
|
|
|
|
*
|
|
|
|
|
|
* The implementation stores the upper and lower number of items which
|
|
|
|
|
|
* trigger a resize in the hashtable object.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Possible hash table sizes (primes) are stored in the array
|
|
|
|
|
|
* hashtable_size.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned long hashtable_size[] = {
|
|
|
|
|
|
31, 61, 113, 223, 443, 883, 1759, 3517, 7027, 14051, 28099, 56197, 112363,
|
|
|
|
|
|
224717, 449419, 898823, 1797641, 3595271, 7190537, 14381041, 28762081,
|
|
|
|
|
|
57524111, 115048217, 230096423
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#define HASHTABLE_SIZE_N (sizeof(hashtable_size)/sizeof(unsigned long))
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
static void
|
|
|
|
|
|
resize_table (scm_t_weak_table *table)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry **old_buckets, **new_buckets;
|
|
|
|
|
|
int new_size_index;
|
|
|
|
|
|
unsigned long old_n_buckets, new_n_buckets, old_k;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
new_size_index = table->size_index;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
if (table->n_items < table->lower)
|
|
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
/* Rehashing is not triggered when i <= min_size. */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
do
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
new_size_index -= 1;
|
|
|
|
|
|
while (new_size_index > table->min_size_index
|
|
|
|
|
|
&& table->n_items < hashtable_size[new_size_index] / 4);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
2012-02-13 15:29:21 +01:00
|
|
|
|
else if (table->n_items > table->upper)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
new_size_index += 1;
|
|
|
|
|
|
if (new_size_index >= HASHTABLE_SIZE_N)
|
|
|
|
|
|
/* Limit max bucket count. */
|
2012-02-13 15:29:21 +01:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
else
|
|
|
|
|
|
/* Nothing to do. */
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
new_n_buckets = hashtable_size[new_size_index];
|
|
|
|
|
|
new_buckets = scm_gc_malloc (sizeof (*new_buckets) * new_n_buckets,
|
|
|
|
|
|
"weak table buckets");
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
old_buckets = table->buckets;
|
|
|
|
|
|
old_n_buckets = table->n_buckets;
|
2012-02-13 15:29:21 +01:00
|
|
|
|
|
|
|
|
|
|
table->size_index = new_size_index;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
table->n_buckets = new_n_buckets;
|
2012-02-13 15:29:21 +01:00
|
|
|
|
if (new_size_index <= table->min_size_index)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
table->lower = 0;
|
|
|
|
|
|
else
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
table->lower = new_n_buckets / 4;
|
|
|
|
|
|
table->upper = 9 * new_n_buckets / 10;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
table->n_items = 0;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
table->buckets = new_buckets;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (old_k = 0; old_k < old_n_buckets; old_k++)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry *entry = old_buckets[old_k];
|
|
|
|
|
|
while (entry)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry *next = entry->next;
|
|
|
|
|
|
entry->next = NULL;
|
|
|
|
|
|
add_entry (table, entry);
|
|
|
|
|
|
entry = next;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Run after GC via do_vacuum_weak_table, this function runs over the
|
|
|
|
|
|
whole table, removing lost weak references, reshuffling the table as it
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
goes. It might resize the table if it reaps enough buckets. */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
static void
|
|
|
|
|
|
vacuum_weak_table (scm_t_weak_table *table)
|
|
|
|
|
|
{
|
2017-10-31 08:43:09 +01:00
|
|
|
|
GC_word gc_no = GC_get_gc_no ();
|
2011-10-23 23:23:47 +02:00
|
|
|
|
unsigned long k;
|
|
|
|
|
|
|
2017-10-31 08:43:09 +01:00
|
|
|
|
if (gc_no == table->last_gc_no)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
table->last_gc_no = gc_no;
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (k = 0; k < table->n_buckets; k++)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry **loc = table->buckets + k;
|
|
|
|
|
|
scm_t_weak_entry *entry;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (entry = *loc; entry; entry = *loc)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_bits key, value;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
read_weak_entry (entry, &key, &value);
|
|
|
|
|
|
if (!key || !value)
|
|
|
|
|
|
/* Lost weak reference; prune entry. */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
*loc = entry->next;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
table->n_items--;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
entry->next = NULL;
|
|
|
|
|
|
unregister_disappearing_links (entry, table->kind);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
else
|
|
|
|
|
|
loc = &entry->next;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (table->n_items < table->lower)
|
|
|
|
|
|
resize_table (table);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
weak_table_ref (scm_t_weak_table *table, unsigned long hash,
|
|
|
|
|
|
scm_t_table_predicate_fn pred, void *closure,
|
|
|
|
|
|
SCM dflt)
|
|
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unsigned long bucket = hash % table->n_buckets;
|
|
|
|
|
|
scm_t_weak_entry *entry;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (entry = table->buckets[bucket]; entry; entry = entry->next)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
if (entry->hash == hash)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_bits key, value;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
read_weak_entry (entry, &key, &value);
|
|
|
|
|
|
if (key && value && pred (SCM_PACK (key), SCM_PACK (value), closure))
|
2011-10-23 23:23:47 +02:00
|
|
|
|
/* Found. */
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
return SCM_PACK (value);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return dflt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
weak_table_put_x (scm_t_weak_table *table, unsigned long hash,
|
|
|
|
|
|
scm_t_table_predicate_fn pred, void *closure,
|
|
|
|
|
|
SCM key, SCM value)
|
|
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unsigned long bucket = hash % table->n_buckets;
|
|
|
|
|
|
scm_t_weak_entry *entry;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (entry = table->buckets[bucket]; entry; entry = entry->next)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
if (entry->hash == hash)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_bits k, v;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
read_weak_entry (entry, &k, &v);
|
|
|
|
|
|
if (k && v && pred (SCM_PACK (k), SCM_PACK (v), closure))
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unregister_disappearing_links (entry, table->kind);
|
|
|
|
|
|
key = SCM_PACK (k);
|
|
|
|
|
|
entry->value = SCM_UNPACK (value);
|
|
|
|
|
|
register_disappearing_links (entry, key, value, table->kind);
|
|
|
|
|
|
return;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-11-26 16:30:57 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
if (table->n_items > table->upper)
|
|
|
|
|
|
/* Full table, time to resize. */
|
|
|
|
|
|
resize_table (table);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
entry = allocate_entry (table->kind);
|
|
|
|
|
|
entry->hash = hash;
|
|
|
|
|
|
entry->key = SCM_UNPACK (key);
|
|
|
|
|
|
entry->value = SCM_UNPACK (value);
|
|
|
|
|
|
register_disappearing_links (entry, key, value, table->kind);
|
|
|
|
|
|
add_entry (table, entry);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
weak_table_remove_x (scm_t_weak_table *table, unsigned long hash,
|
|
|
|
|
|
scm_t_table_predicate_fn pred, void *closure)
|
|
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unsigned long bucket = hash % table->n_buckets;
|
|
|
|
|
|
scm_t_weak_entry **loc = table->buckets + bucket;
|
|
|
|
|
|
scm_t_weak_entry *entry;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (entry = *loc; entry; entry = *loc)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
if (entry->hash == hash)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_bits k, v;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
read_weak_entry (entry, &k, &v);
|
|
|
|
|
|
if (k && v && pred (SCM_PACK (k), SCM_PACK (v), closure))
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
*loc = entry->next;
|
|
|
|
|
|
table->n_items--;
|
|
|
|
|
|
entry->next = NULL;
|
|
|
|
|
|
unregister_disappearing_links (entry, table->kind);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
if (table->n_items < table->lower)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
resize_table (table);
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
loc = &entry->next;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
|
|
|
|
|
|
return;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
make_weak_table (unsigned long k, scm_t_weak_table_kind kind)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_table *table;
|
|
|
|
|
|
|
|
|
|
|
|
int i = 0, n = k ? k : 31;
|
|
|
|
|
|
while (i + 1 < HASHTABLE_SIZE_N && n > hashtable_size[i])
|
|
|
|
|
|
++i;
|
|
|
|
|
|
n = hashtable_size[i];
|
|
|
|
|
|
|
|
|
|
|
|
table = scm_gc_malloc (sizeof (*table), "weak-table");
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
table->buckets = scm_gc_malloc (sizeof (*table->buckets) * n,
|
|
|
|
|
|
"weak table buckets");
|
2011-10-23 23:23:47 +02:00
|
|
|
|
table->kind = kind;
|
|
|
|
|
|
table->n_items = 0;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
table->n_buckets = n;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
table->lower = 0;
|
|
|
|
|
|
table->upper = 9 * n / 10;
|
|
|
|
|
|
table->size_index = i;
|
|
|
|
|
|
table->min_size_index = i;
|
2017-10-31 08:43:09 +01:00
|
|
|
|
table->last_gc_no = GC_get_gc_no ();
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_i_pthread_mutex_init (&table->lock, NULL);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
return scm_cell (scm_tc7_weak_table, (scm_t_bits)table);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_i_weak_table_print (SCM exp, SCM port, scm_print_state *pstate)
|
|
|
|
|
|
{
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts ("#<", port);
|
|
|
|
|
|
scm_puts ("weak-table ", port);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_uintprint (SCM_WEAK_TABLE (exp)->n_items, 10, port);
|
2016-04-26 23:01:14 +02:00
|
|
|
|
scm_putc ('/', port);
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_uintprint (SCM_WEAK_TABLE (exp)->n_buckets, 10, port);
|
2016-04-26 23:07:28 +02:00
|
|
|
|
scm_puts (">", port);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
do_vacuum_weak_table (SCM table)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_table *t;
|
|
|
|
|
|
|
|
|
|
|
|
t = SCM_WEAK_TABLE (table);
|
|
|
|
|
|
|
2013-01-20 12:41:15 +01:00
|
|
|
|
/* Unlike weak sets, the weak table interface allows custom predicates
|
|
|
|
|
|
to call out to arbitrary Scheme. There are two ways that this code
|
|
|
|
|
|
can be re-entrant, then: calling weak hash procedures while in a
|
|
|
|
|
|
custom predicate, or via finalizers run explicitly by (gc) or in an
|
|
|
|
|
|
async (for non-threaded Guile). We add a restriction that
|
|
|
|
|
|
prohibits the first case, by convention. But since we can't
|
2017-10-31 08:43:09 +01:00
|
|
|
|
prohibit the second case, here we trylock instead of lock. In any
|
|
|
|
|
|
case, if the mutex is held by another thread, then the table is in
|
|
|
|
|
|
active use, so the next user of the table will handle the vacuum
|
|
|
|
|
|
for us. */
|
2011-10-23 23:23:47 +02:00
|
|
|
|
if (scm_i_pthread_mutex_trylock (&t->lock) == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
vacuum_weak_table (t);
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-13 15:47:51 +01:00
|
|
|
|
static scm_i_pthread_mutex_t all_weak_tables_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
|
|
static SCM all_weak_tables = SCM_EOL;
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
vacuum_all_weak_tables (void)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_i_pthread_mutex_lock (&all_weak_tables_lock);
|
|
|
|
|
|
scm_i_visit_weak_list (&all_weak_tables, do_vacuum_weak_table);
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&all_weak_tables_lock);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_make_weak_table (unsigned long k, scm_t_weak_table_kind kind)
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = make_weak_table (k, kind);
|
|
|
|
|
|
|
2017-03-13 15:47:51 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&all_weak_tables_lock);
|
|
|
|
|
|
all_weak_tables = scm_i_weak_cons (ret, all_weak_tables);
|
|
|
|
|
|
scm_i_pthread_mutex_unlock (&all_weak_tables_lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_weak_table_p (SCM obj)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (SCM_WEAK_TABLE_P (obj));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_weak_table_ref (SCM table, unsigned long raw_hash,
|
|
|
|
|
|
scm_t_table_predicate_fn pred,
|
|
|
|
|
|
void *closure, SCM dflt)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-ref"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM ret;
|
|
|
|
|
|
scm_t_weak_table *t;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (1, table);
|
|
|
|
|
|
|
|
|
|
|
|
t = SCM_WEAK_TABLE (table);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2017-10-31 08:43:09 +01:00
|
|
|
|
vacuum_weak_table (t);
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
ret = weak_table_ref (t, raw_hash, pred, closure, dflt);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_c_weak_table_put_x (SCM table, unsigned long raw_hash,
|
|
|
|
|
|
scm_t_table_predicate_fn pred,
|
|
|
|
|
|
void *closure, SCM key, SCM value)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-put!"
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_table *t;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (1, table);
|
|
|
|
|
|
|
|
|
|
|
|
t = SCM_WEAK_TABLE (table);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2017-10-31 08:43:09 +01:00
|
|
|
|
vacuum_weak_table (t);
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
weak_table_put_x (t, raw_hash, pred, closure, key, value);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_c_weak_table_remove_x (SCM table, unsigned long raw_hash,
|
|
|
|
|
|
scm_t_table_predicate_fn pred,
|
|
|
|
|
|
void *closure)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-remove!"
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_table *t;
|
|
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (1, table);
|
|
|
|
|
|
|
|
|
|
|
|
t = SCM_WEAK_TABLE (table);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2017-10-31 08:43:09 +01:00
|
|
|
|
vacuum_weak_table (t);
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
weak_table_remove_x (t, raw_hash, pred, closure);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
|
assq_predicate (SCM x, SCM y, void *closure)
|
|
|
|
|
|
{
|
2011-10-24 17:58:22 +02:00
|
|
|
|
return scm_is_eq (x, SCM_PACK_POINTER (closure));
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_weak_table_refq (SCM table, SCM key, SCM dflt)
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_c_weak_table_ref (table, scm_ihashq (key, -1),
|
2011-10-24 17:58:22 +02:00
|
|
|
|
assq_predicate, SCM_UNPACK_POINTER (key),
|
2011-10-23 23:23:47 +02:00
|
|
|
|
dflt);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-03-02 18:26:56 +01:00
|
|
|
|
void
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_weak_table_putq_x (SCM table, SCM key, SCM value)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_weak_table_put_x (table, scm_ihashq (key, -1),
|
2011-10-24 17:58:22 +02:00
|
|
|
|
assq_predicate, SCM_UNPACK_POINTER (key),
|
2011-10-23 23:23:47 +02:00
|
|
|
|
key, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-03-02 18:26:56 +01:00
|
|
|
|
void
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_weak_table_remq_x (SCM table, SCM key)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_c_weak_table_remove_x (table, scm_ihashq (key, -1),
|
2011-10-24 17:58:22 +02:00
|
|
|
|
assq_predicate, SCM_UNPACK_POINTER (key));
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2012-03-02 18:26:56 +01:00
|
|
|
|
void
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_weak_table_clear_x (SCM table)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-clear!"
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_table *t;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unsigned long k;
|
|
|
|
|
|
scm_t_weak_entry *entry;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (1, table);
|
|
|
|
|
|
|
|
|
|
|
|
t = SCM_WEAK_TABLE (table);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2017-10-31 08:43:09 +01:00
|
|
|
|
t->last_gc_no = GC_get_gc_no ();
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (k = 0; k < t->n_buckets; k++)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (entry = t->buckets[k]; entry; entry = entry->next)
|
|
|
|
|
|
unregister_disappearing_links (entry, t->kind);
|
|
|
|
|
|
t->buckets[k] = NULL;
|
|
|
|
|
|
}
|
2011-10-23 23:23:47 +02:00
|
|
|
|
t->n_items = 0;
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_c_weak_table_fold (scm_t_table_fold_fn proc, void *closure,
|
|
|
|
|
|
SCM init, SCM table)
|
|
|
|
|
|
{
|
|
|
|
|
|
scm_t_weak_table *t;
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
unsigned long k;
|
|
|
|
|
|
SCM alist = SCM_EOL;
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
|
|
|
|
|
t = SCM_WEAK_TABLE (table);
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_lock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
2017-10-31 08:43:09 +01:00
|
|
|
|
vacuum_weak_table (t);
|
|
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
for (k = 0; k < t->n_buckets; k++)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_weak_entry *entry;
|
|
|
|
|
|
for (entry = t->buckets[k]; entry; entry = entry->next)
|
2011-10-23 23:23:47 +02:00
|
|
|
|
{
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
scm_t_bits key, value;
|
|
|
|
|
|
read_weak_entry (entry, &key, &value);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
if (key && value)
|
|
|
|
|
|
alist = scm_acons (SCM_PACK (key), SCM_PACK (value), alist);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-02-23 14:18:56 +01:00
|
|
|
|
scm_i_pthread_mutex_unlock (&t->lock);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
|
Weak tables are now bucket-and-chain tables
This change should make weak tables work better with libgc, as the weak
components that need mark functions are smaller, so they don't overflow
the mark queue. Also this prevents the need to move disappearing
links.
* libguile/weak-table.c (scm_t_weak_entry): Change to be a hash table
chain entry.
(struct weak_entry_data, do_read_weak_entry, read_weak_entry): Read
out the key and value directly.
(GC_move_disappearing_link, move_disappearing_links, move_weak_entry):
Remove.
(scm_t_weak_table): Rename "entries" member to "buckets", and "size" to
"n_buckets".
(hash_to_index, entry_distance, rob_from_rich, give_to_poor): Remove.
(mark_weak_key_entry, mark_weak_value_entry): Mark a single link, and
the next link.
(mark_doubly_weak_entry): New kind.
(allocate_entry): Allocate a single entry.
(add_entry): New helper.
(resize_table): Reimplement more like normal hash tables.
(vacuum_weak_table): Adapt to new implementation.
(weak_table_ref, weak_table_put_x, weak_table_remove_x): Adapt.
(make_weak_table): Adapt.
(scm_weak_table_clear_x): Actually unregister the links to prevent a
memory leak.
(scm_c_weak_table_fold): Collect items in an alist, then fold outside
the lock.
(scm_weak_table_prehistory): Initialize doubly_weak_gc_kind.
2017-10-30 18:19:37 +01:00
|
|
|
|
/* Call the proc outside the lock. */
|
|
|
|
|
|
for (; !scm_is_null (alist); alist = scm_cdr (alist))
|
|
|
|
|
|
init = proc (closure, scm_caar (alist), scm_cdar (alist), init);
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
return init;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
fold_trampoline (void *closure, SCM k, SCM v, SCM init)
|
|
|
|
|
|
{
|
2011-10-24 17:58:22 +02:00
|
|
|
|
return scm_call_3 (SCM_PACK_POINTER (closure), k, v, init);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_weak_table_fold (SCM proc, SCM init, SCM table)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-fold"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (3, table);
|
|
|
|
|
|
SCM_VALIDATE_PROC (1, proc);
|
|
|
|
|
|
|
2011-10-24 17:58:22 +02:00
|
|
|
|
return scm_c_weak_table_fold (fold_trampoline, SCM_UNPACK_POINTER (proc), init, table);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
for_each_trampoline (void *closure, SCM k, SCM v, SCM seed)
|
|
|
|
|
|
{
|
2011-10-24 17:58:22 +02:00
|
|
|
|
scm_call_2 (SCM_PACK_POINTER (closure), k, v);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
return seed;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-03-02 18:26:56 +01:00
|
|
|
|
void
|
2011-10-23 23:23:47 +02:00
|
|
|
|
scm_weak_table_for_each (SCM proc, SCM table)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-for-each"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (2, table);
|
|
|
|
|
|
SCM_VALIDATE_PROC (1, proc);
|
|
|
|
|
|
|
2011-10-24 17:58:22 +02:00
|
|
|
|
scm_c_weak_table_fold (for_each_trampoline, SCM_UNPACK_POINTER (proc), SCM_BOOL_F, table);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
static SCM
|
|
|
|
|
|
map_trampoline (void *closure, SCM k, SCM v, SCM seed)
|
|
|
|
|
|
{
|
2011-10-24 17:58:22 +02:00
|
|
|
|
return scm_cons (scm_call_2 (SCM_PACK_POINTER (closure), k, v), seed);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SCM
|
|
|
|
|
|
scm_weak_table_map_to_list (SCM proc, SCM table)
|
|
|
|
|
|
#define FUNC_NAME "weak-table-map->list"
|
|
|
|
|
|
{
|
|
|
|
|
|
SCM_VALIDATE_WEAK_TABLE (2, table);
|
|
|
|
|
|
SCM_VALIDATE_PROC (1, proc);
|
|
|
|
|
|
|
2011-10-24 17:58:22 +02:00
|
|
|
|
return scm_c_weak_table_fold (map_trampoline, SCM_UNPACK_POINTER (proc), SCM_EOL, table);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-10-24 07:57:17 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Legacy interface. */
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_make_weak_key_hash_table, "make-weak-key-hash-table", 0, 1, 0,
|
|
|
|
|
|
(SCM n),
|
|
|
|
|
|
"@deffnx {Scheme Procedure} make-weak-value-hash-table size\n"
|
|
|
|
|
|
"@deffnx {Scheme Procedure} make-doubly-weak-hash-table size\n"
|
|
|
|
|
|
"Return a weak hash table with @var{size} buckets.\n"
|
|
|
|
|
|
"\n"
|
|
|
|
|
|
"You can modify weak hash tables in exactly the same way you\n"
|
|
|
|
|
|
"would modify regular hash tables. (@pxref{Hash Tables})")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_weak_key_hash_table
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_c_make_weak_table (SCM_UNBNDP (n) ? 0 : scm_to_ulong (n),
|
|
|
|
|
|
SCM_WEAK_TABLE_KIND_KEY);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_make_weak_value_hash_table, "make-weak-value-hash-table", 0, 1, 0,
|
|
|
|
|
|
(SCM n),
|
|
|
|
|
|
"Return a hash table with weak values with @var{size} buckets.\n"
|
|
|
|
|
|
"(@pxref{Hash Tables})")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_weak_value_hash_table
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_c_make_weak_table (SCM_UNBNDP (n) ? 0 : scm_to_ulong (n),
|
|
|
|
|
|
SCM_WEAK_TABLE_KIND_VALUE);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-08 14:46:31 +01:00
|
|
|
|
SCM_DEFINE (scm_make_doubly_weak_hash_table, "make-doubly-weak-hash-table", 0, 1, 0,
|
2011-10-24 07:57:17 +02:00
|
|
|
|
(SCM n),
|
|
|
|
|
|
"Return a hash table with weak keys and values with @var{size}\n"
|
|
|
|
|
|
"buckets. (@pxref{Hash Tables})")
|
|
|
|
|
|
#define FUNC_NAME s_scm_make_doubly_weak_hash_table
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_c_make_weak_table (SCM_UNBNDP (n) ? 0 : scm_to_ulong (n),
|
|
|
|
|
|
SCM_WEAK_TABLE_KIND_BOTH);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_key_hash_table_p, "weak-key-hash-table?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"@deffnx {Scheme Procedure} weak-value-hash-table? obj\n"
|
|
|
|
|
|
"@deffnx {Scheme Procedure} doubly-weak-hash-table? obj\n"
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is the specified weak hash\n"
|
|
|
|
|
|
"table. Note that a doubly weak hash table is neither a weak key\n"
|
|
|
|
|
|
"nor a weak value hash table.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_key_hash_table_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (SCM_WEAK_TABLE_P (obj) &&
|
|
|
|
|
|
SCM_WEAK_TABLE (obj)->kind == SCM_WEAK_TABLE_KIND_KEY);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_weak_value_hash_table_p, "weak-value-hash-table?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is a weak value hash table.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_weak_value_hash_table_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (SCM_WEAK_TABLE_P (obj) &&
|
|
|
|
|
|
SCM_WEAK_TABLE (obj)->kind == SCM_WEAK_TABLE_KIND_VALUE);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SCM_DEFINE (scm_doubly_weak_hash_table_p, "doubly-weak-hash-table?", 1, 0, 0,
|
|
|
|
|
|
(SCM obj),
|
|
|
|
|
|
"Return @code{#t} if @var{obj} is a doubly weak hash table.")
|
|
|
|
|
|
#define FUNC_NAME s_scm_doubly_weak_hash_table_p
|
|
|
|
|
|
{
|
|
|
|
|
|
return scm_from_bool (SCM_WEAK_TABLE_P (obj) &&
|
|
|
|
|
|
SCM_WEAK_TABLE (obj)->kind == SCM_WEAK_TABLE_KIND_BOTH);
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef FUNC_NAME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-10-23 23:23:47 +02:00
|
|
|
|
void
|
|
|
|
|
|
scm_weak_table_prehistory (void)
|
|
|
|
|
|
{
|
2017-10-31 09:10:55 +01:00
|
|
|
|
GC_word weak_key_bitmap[GC_BITMAP_SIZE (scm_t_weak_entry)] = { 0 };
|
|
|
|
|
|
GC_word weak_value_bitmap[GC_BITMAP_SIZE (scm_t_weak_entry)] = { 0 };
|
|
|
|
|
|
GC_word doubly_weak_bitmap[GC_BITMAP_SIZE (scm_t_weak_entry)] = { 0 };
|
|
|
|
|
|
|
|
|
|
|
|
GC_set_bit (weak_key_bitmap, GC_WORD_OFFSET (scm_t_weak_entry, next));
|
|
|
|
|
|
GC_set_bit (weak_value_bitmap, GC_WORD_OFFSET (scm_t_weak_entry, next));
|
|
|
|
|
|
GC_set_bit (doubly_weak_bitmap, GC_WORD_OFFSET (scm_t_weak_entry, next));
|
|
|
|
|
|
|
|
|
|
|
|
GC_set_bit (weak_key_bitmap, GC_WORD_OFFSET (scm_t_weak_entry, value));
|
|
|
|
|
|
GC_set_bit (weak_value_bitmap, GC_WORD_OFFSET (scm_t_weak_entry, key));
|
|
|
|
|
|
|
|
|
|
|
|
weak_key_descr = GC_make_descriptor (weak_key_bitmap,
|
|
|
|
|
|
GC_WORD_LEN (scm_t_weak_entry));
|
|
|
|
|
|
weak_value_descr = GC_make_descriptor (weak_value_bitmap,
|
|
|
|
|
|
GC_WORD_LEN (scm_t_weak_entry));
|
|
|
|
|
|
doubly_weak_descr = GC_make_descriptor (doubly_weak_bitmap,
|
|
|
|
|
|
GC_WORD_LEN (scm_t_weak_entry));
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
scm_init_weak_table ()
|
|
|
|
|
|
{
|
2018-06-20 17:19:31 +02:00
|
|
|
|
#include "weak-table.x"
|
2017-03-13 15:47:51 +01:00
|
|
|
|
|
|
|
|
|
|
scm_i_register_async_gc_callback (vacuum_all_weak_tables);
|
2011-10-23 23:23:47 +02:00
|
|
|
|
}
|