Subject: Lisp_Subr header and layout

From: Pip Cet <[email-masked]>
Date: Fri, 03 Jan 2025 14:29:58 +0000

Lisp_Subr::command_modes aren't marked by GC; the vectorlike_header of
Lisp_Subr is often incorrect; Lisp_Subr fields don't follow the usual
order

This is not an acute bug, but it's problematic code which might cause a
bug if something changes.

struct Lisp_Subr contains a "Lisp_Object command_modes" field, whether
or not Emacs is built with native-comp support.  It's only marked by GC
if Emacs is built with native-comp support.  Putting arbitrary values in
there would cause crashes.

Right now, command_modes is always Qnil in non-native-comp builds, so
this isn't a problem as nil doesn't need to be marked explicitly by GC;
it does, however, waste some space (5 KB on 32-bit machines).

I think making the existence of the command_modes field depend on
nativecomp would be the best solution; if we want to use a command_modes
field for non-nativecomp builds, in the future, we have to change the GC
marking code and the pdumper code, but I really don't see the point of
allocating and GC-marking a field that we know is always nil on the off
chance it might be useful in the future.

After this change, struct Lisp_Subr contains no Lisp_Object fields, and
if we want to add one (most likely because ::doc should be a Lisp_Object
rather than an EMACS_INT) again, we should consider making it an
ordinary PVEC, with the Lisp_Object fields first and the POD C data at
the end.  This would eventually allow us to remove the special-casing of
subrs in the GC code, but this would also require us to use the expected
pvec header word value for built-in subrs; right now, we don't.

I'll prepare patches for those two changes (remove command_modes;
correct pvec headers for subrs); not the third (reorder Lisp_Subr
fields) because it's a nativecomp change, and there may be a small
performance impact.

Pip