purecopy_hash_table (struct Lisp_Hash_Table *table)
{
eassert (NILP (table->weak));
- eassert (!NILP (table->pure));
+ eassert (table->pure);
struct Lisp_Hash_Table *pure = pure_alloc (sizeof *pure, Lisp_Vectorlike);
struct hash_table_test pure_test = table->test;
pure->header = table->header;
pure->weak = purecopy (Qnil);
pure->rehash_size = purecopy (table->rehash_size);
- pure->rehash_threshold = purecopy (table->rehash_threshold);
pure->hash = purecopy (table->hash);
pure->next = purecopy (table->next);
pure->next_free = purecopy (table->next_free);
pure->index = purecopy (table->index);
pure->count = table->count;
+ pure->pure = table->pure;
+ pure->rehash_threshold = table->rehash_threshold;
pure->key_and_value = purecopy (table->key_and_value);
- pure->pure = purecopy (table->pure);
return pure;
}
/* Do not purify hash tables which haven't been defined with
:purecopy as non-nil or are weak - they aren't guaranteed to
not change. */
- if (!NILP (table->weak) || NILP (table->pure))
+ if (!NILP (table->weak) || !table->pure)
{
/* Instead, add the hash table to the list of pinned objects,
so that it will be marked during GC. */
(table, 1,
make_hash_table (hashtest_equal, make_number (DEFAULT_HASH_SIZE),
make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil));
+ DEFAULT_REHASH_THRESHOLD,
+ Qnil, false));
h = XHASH_TABLE (XCHAR_TABLE (table)->extras[1]);
i = hash_lookup (h, category_set, &hash);
if (i >= 0)
Lisp_Object
make_hash_table (struct hash_table_test test,
Lisp_Object size, Lisp_Object rehash_size,
- Lisp_Object rehash_threshold, Lisp_Object weak,
- Lisp_Object pure)
+ float rehash_threshold, Lisp_Object weak,
+ bool pure)
{
struct Lisp_Hash_Table *h;
Lisp_Object table;
eassert (INTEGERP (size) && XINT (size) >= 0);
eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
|| (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
- eassert (FLOATP (rehash_threshold)
- && 0 < XFLOAT_DATA (rehash_threshold)
- && XFLOAT_DATA (rehash_threshold) <= 1.0);
+ eassert (0 < rehash_threshold && rehash_threshold <= 1.0);
if (XFASTINT (size) == 0)
size = make_number (1);
sz = XFASTINT (size);
- index_float = sz / XFLOAT_DATA (rehash_threshold);
+ index_float = sz / rehash_threshold;
index_size = (index_float < INDEX_SIZE_BOUND + 1
? next_almost_prime (index_float)
: INDEX_SIZE_BOUND + 1);
else
new_size = INDEX_SIZE_BOUND + 1;
}
- index_float = new_size / XFLOAT_DATA (h->rehash_threshold);
+ index_float = new_size / h->rehash_threshold;
index_size = (index_float < INDEX_SIZE_BOUND + 1
? next_almost_prime (index_float)
: INDEX_SIZE_BOUND + 1);
usage: (make-hash-table &rest KEYWORD-ARGS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- Lisp_Object test, size, rehash_size, rehash_threshold, weak, pure;
+ Lisp_Object test, size, rehash_size, weak;
+ float rehash_threshold;
+ bool pure;
struct hash_table_test testdesc;
ptrdiff_t i;
USE_SAFE_ALLOCA;
/* See if there's a `:purecopy PURECOPY' argument. */
i = get_key_arg (QCpurecopy, nargs, args, used);
- pure = i ? args[i] : Qnil;
+ pure = i && !NILP (args[i]);
/* See if there's a `:size SIZE' argument. */
i = get_key_arg (QCsize, nargs, args, used);
size = i ? args[i] : Qnil;
/* Look for `:rehash-threshold THRESHOLD'. */
i = get_key_arg (QCrehash_threshold, nargs, args, used);
- rehash_threshold = i ? args[i] : make_float (DEFAULT_REHASH_THRESHOLD);
- if (! (FLOATP (rehash_threshold)
- && 0 < XFLOAT_DATA (rehash_threshold)
- && XFLOAT_DATA (rehash_threshold) <= 1))
- signal_error ("Invalid hash table rehash threshold", rehash_threshold);
+ rehash_threshold =
+ i ? (FLOATP (args[i]) ? XFLOAT_DATA (args[i]) : -1.0)
+ : DEFAULT_REHASH_THRESHOLD;
+ if (! (0 < rehash_threshold && rehash_threshold <= 1))
+ signal_error ("Invalid hash table rehash threshold", args[i]);
/* Look for `:weakness WEAK'. */
i = get_key_arg (QCweakness, nargs, args, used);
doc: /* Return the current rehash threshold of TABLE. */)
(Lisp_Object table)
{
- return check_hash_table (table)->rehash_threshold;
+ return make_float (check_hash_table (table)->rehash_threshold);
}
new size by multiplying the old size with this factor. */
Lisp_Object rehash_size;
- /* Resize hash table when number of entries/ table size is >= this
- ratio, a float. */
- Lisp_Object rehash_threshold;
-
/* Vector of hash codes. If hash[I] is nil, this means that the
I-th entry is unused. */
Lisp_Object hash;
hash table size to reduce collisions. */
Lisp_Object index;
- /* Non-nil if the table can be purecopied. The table cannot be
- changed afterwards. */
- Lisp_Object pure;
-
/* Only the fields above are traced normally by the GC. The ones below
`count' are special and are either ignored by the GC or traced in
a special way (e.g. because of weakness). */
/* Number of key/value entries in the table. */
ptrdiff_t count;
+ /* Non-nil if the table can be purecopied. The table cannot be
+ changed afterwards. */
+ bool_bf pure : 1;
+
+ /* Resize hash table when number of entries/ table size is >= this
+ ratio, a float. */
+ float rehash_threshold;
+
/* Vector of keys and values. The key of item I is found at index
2 * I, the value is found at index 2 * I + 1.
This is gc_marked specially if the table is weak. */
extern void sweep_weak_hash_tables (void);
EMACS_UINT hash_string (char const *, ptrdiff_t);
EMACS_UINT sxhash (Lisp_Object, int);
-Lisp_Object make_hash_table (struct hash_table_test, Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object, Lisp_Object);
+Lisp_Object make_hash_table (struct hash_table_test test,
+ Lisp_Object size, Lisp_Object rehash_size,
+ float rehash_threshold, Lisp_Object weak,
+ bool pure);
ptrdiff_t hash_lookup (struct Lisp_Hash_Table *, Lisp_Object, EMACS_UINT *);
ptrdiff_t hash_put (struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
EMACS_UINT);
print_object (h->rehash_size, printcharfun, escapeflag);
}
- if (!NILP (h->rehash_threshold))
- {
- print_c_string (" rehash-threshold ", printcharfun);
- print_object (h->rehash_threshold, printcharfun, escapeflag);
- }
+ print_c_string (" rehash-threshold ", printcharfun);
+ print_object (make_float (h->rehash_threshold),
+ printcharfun, escapeflag);
- if (!NILP (h->pure))
+ if (h->pure)
{
print_c_string (" purecopy ", printcharfun);
- print_object (h->pure, printcharfun, escapeflag);
+ print_object (h->pure ? Qt : Qnil, printcharfun, escapeflag);
}
print_c_string (" data ", printcharfun);
Lisp_Object log = make_hash_table (hashtest_profiler,
make_number (heap_size),
make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil);
+ DEFAULT_REHASH_THRESHOLD,
+ Qnil, false);
struct Lisp_Hash_Table *h = XHASH_TABLE (log);
/* What is special about our hash-tables is that the keys are pre-filled
doc: /* Hash table of character codes indexed by X keysym codes. */);
Vx_keysym_table = make_hash_table (hashtest_eql, make_number (900),
make_float (DEFAULT_REHASH_SIZE),
- make_float (DEFAULT_REHASH_THRESHOLD),
- Qnil, Qnil);
+ DEFAULT_REHASH_THRESHOLD,
+ Qnil, false);
DEFVAR_BOOL ("x-frame-normalize-before-maximize",
x_frame_normalize_before_maximize,