The profiler stored data being collected in Lisp hash tables but
relied heavily on their exact internal representation, which made it
difficult and error-prone to change the hash table implementation.
In particular, the profiler has special run-time requirements that are
not easily met using standard Lisp data structures: accesses and
updates are made from async signal handlers in almost any messy
context you can think of and are therefore very constrained in what
they can do.
The new profiler tables are designed specifically for their purpose
and are more efficient and, by not being coupled to Lisp hash tables,
easier to keep safe.
The old profiler morphed internal hash tables to ones usable from Lisp
and thereby made them impossible to use internally; now export_log
just makes new hash table objects for Lisp. The Lisp part of the
profiler remains entirely unchanged.
* src/alloc.c (garbage_collect): Mark profiler tables.
* src/eval.c (get_backtrace): Fill an array of Lisp values instead of
a Lisp vector.
* src/profiler.c (log_t): No longer a Lisp hash table but a custom
data structure: a fully associative fixed-sized cache that maps
fixed-size arrays of Lisp objects to counts.
(make_log): Build new struct.
(mark_log, free_log, get_log_count, set_log_count, get_key_vector)
(log_hash_index, remove_log_entry, trace_equal, trace_hash)
(make_profiler_log, free_profiler_log, mark_profiler): New.
(cmpfn_profiler, hashtest_profiler, hashfn_profiler)
(syms_of_profiler_for_pdumper): Remove.
(approximate_median, evict_lower_half, record_backtrace, export_log)
(Fprofiler_cpu_log, Fprofiler_memory_log, syms_of_profiler):
Adapt to the new data structure.