* libguile/gc.h:
* libguile/gc.c (scm_gc_pin_object): New function.
(scm_gc_object_address): New function, to be used instead of SCM_UNPACK
when an object's address is exposed, for example via hashq.
* libguile/atomic.c:
* libguile/cache-internal.h:
* libguile/continuations.c:
* libguile/dynstack.c:
* libguile/dynstack.h:
* libguile/ephemerons.c:
* libguile/exceptions.c:
* libguile/finalizers.c:
* libguile/fluids-internal.h:
* libguile/fluids.c:
* libguile/foreign.c:
* libguile/frames.c:
* libguile/hash.c:
* libguile/hashtab.c:
* libguile/intrinsics.c:
* libguile/memoize.c:
* libguile/print.c:
* libguile/programs.c:
* libguile/smob.c:
* libguile/struct.c:
* libguile/struct.h:
* libguile/variable.c:
* libguile/vm.c: Use the new functions everywhere that is needed.
Because they take a thread, sometimes we have to do some extra plumbing.
This way we don't allocate an untagged wake data, and we don't need a
type tag. On the other hand we have to roll a more complicated seqlock,
but that's fine.
Also switch to require C11 atomics.
* libguile/atomics-internal.h: Remove fallback for when we don't have
C11 atomics.
(scm_atomic_ref_uint32, scm_atomic_swap_uint32, scm_atomic_set_uint32):
New helpers.
* libguile/threads-internal.h:
* libguile/async.h:
* libguile/async.c: Inline the thread wake data. Happily, waking a
remote thread is still wait-free from both sides.
Avoids sloppy allocations.
* libguile/ports-internal.h (scm_is_port_type):
(scm_to_port_type, scm_from_port_type): New helpers.
* libguile/goops.c (scm_make_port_classes):
(create_port_classes): Use a list and be thread-safe.
* libguile/scm.h (scm_tc7_port_type):
* libguile/ports-internal.h (struct scm_t_port_type):
* libguile/ports.c (scm_make_port_type): These objects have been
allocated pointerless since 2011, but since 2016 at least they have had
SCM members. Oops!
Before, it was untagged, which is a problem for precise tracing.
* libguile/threads.c (make_launch_data, protect_launch_data)
(unprotect_launch_data, really_launch, launch_thread)
(scm_sys_call_with_new_thread): Use a vector for launch data.
Allows us to inline the "struct scm_dynamic_state", avoiding an untagged
traced allocation.
* libguile/threads-internal.h: New file.
* libguile/Makefile.am (noinst_HEADERS): Add new file.
Adapt all users, notably of SCM_I_CURRENT_THREAD and scm_i_misc_mutex.
Requires a full rebuild!!
* libguile/struct.h (SCM_VTABLE_UNBOXED_FIELDS):
(SCM_VTABLE_FIELD_IS_UNBOXED): Use logbit? to determine if a field is
unboxed.
* module/language/cps/guile-vm/lower-primcalls.scm
(vtable-has-unboxed-fields?): Just check against SCM_INUM0.
(vtable-field-boxed?): Likewise, the bitmask is an integer.
* libguile/struct.c (set_vtable_access_fields): Set UNBOXED_FIELDS
bitmask as integer.
Also move most internal vector representation into a private header
file.
* libguile/vectors-internal.h: New file.
* libguile/vectors.h (SCM_I_IS_MUTABLE_VECTOR, SCM_I_VECTOR_WELTS)
(SCM_I_VECTOR_ELTS, SCM_I_VECTOR_LENGTH): Remove these internal
definitions.
* libguile/vectors.c: Adapt to use new data types.
* libguile/eval.c: Include internal file.
* libguile/init.c: Include internal file.
* libguile/array-handle.c (scm_array_get_handle): Use new functions.
* libguile/hashtab.h (SCM_HASHTABLE_VECTOR):
(SCM_SET_HASHTABLE_VECTOR):
(SCM_HASHTABLE):
(SCM_HASHTABLE_N_ITEMS):
(SCM_SET_HASHTABLE_N_ITEMS):
(SCM_HASHTABLE_INCREMENT):
(SCM_HASHTABLE_DECREMENT):
(SCM_HASHTABLE_UPPER):
(SCM_HASHTABLE_LOWER):
(SCM_HASHTABLE_N_BUCKETS):
(SCM_HASHTABLE_BUCKET):
(SCM_SET_HASHTABLE_BUCKET): Remove these internal definitions from the
public interface.
(scm_t_hashtable): Add a tag, and add buckets.
(scm_is_hashtable):
(scm_to_hashtable):
(scm_from_hashtable): New helpers.
* libguile/modules.c (scm_module_reverse_lookup): Adapt to hash table
API change.
* libguile/hashtab.c: Rework to access hash table data through the typed
"struct scm_t_hashtable".
* libguile/foreign.h (SCM_IMMUTABLE_POINTER): Remove. This was part of
the implementation of static subrs, a long long time ago, but hasn't
been used since 2013 (27337b6373).
* libguile/numbers.h (scm_t_double, scm_t_complex): Change type and pad
to scm_t_bits.
(struct scm_fraction): New type.
(scm_is_fraction, scm_to_fraction, scm_from_fraction)
(scm_fraction_numerator, scm_fraction_denominator): New helpers.
(SCM_FRACTIONP, SCM_FRACTION_NUMERATOR, SCM_FRACTION_DENOMINATOR): Use
new helpers.
* libguile/numbers.c (scm_i_make_ratio_already_reduced): Allocate using
scm_allocate_tagged.
* libguile/keywords-internal.h: New file.
* libguile/Makefile.am (noinst_HEADERS): Add new file.
* libguile/hash.c:
* libguile/init.c:
* libguile/keywords.c: Include new file.
(scm_symbol_to_keyword): Allocate via scm_allocate_tagged.
* libguile/gc.h:
* libguile/pairs.h (scm_pair_car_loc, scm_pair_cdr_loc): New helpers.
(SCM_CARLOC, SCM_CDRLOC): Move here from gc.h.
* libguile/list.c (scm_list_1, scm_list_2, scm_list_3): Just use
scm_cons.
* libguile/pairs.h: Remove inline scm_cons, scm_car, scm_cdr defnitions;
this is less important now with the VM. Add a "struct scm_pair", and
make all SCM_CAR / SCM_CDR checks use it. For now it does type checking
as well.
* libguile/pairs.c (scm_cons, scm_car, scm_cdr): Implement here.
* libguile/scm.h (SCM_DEBUG_PAIR_ACCESSES): No more macro!
* libguile/posix.c (free_string_pointers):
(free_string_pointers_on_unwind):
(allocate_string_pointers): Move here from string.c, and use malloc/free
instead of GC facilities. Adapt all users.
* libguile/strings.h:
* libguile/strings.c (scm_i_allocate_string_pointers): Remove.
* libguile/struct.c (scm_struct_init_1_default):
(scm_struct_init_1): New helpers.
(scm_struct_init_array): Use new helpers.
(scm_struct_init_list): New function.
(scm_make_struct_no_tail): Use scm_struct_init_list instead of mallocing.