* src/bytecode.c (exec_byte_code): Reset quitcounter to 1 after longjmp;
the exact value isn't important. This may reduce register pressure a
tiny bit or at least remove a useless stack slot.
Work around a bug in GnuTLS 3.7.11 and earlier: when built
statically, its mistakenly exports symbols hash_lookup and
hash_string, which collide with Emacs symbols of the same name,
preventing temacs from linking statically. Problem reported by
Greg A. Woods (Bug#77476).
Because GnuTLS never uses hash_lookup or hash_string this issue
ordinarily doesn’t seem to prevent temacs from linking to GnuTLS
on GNU/Linux, as it’s linked dynamically and the dynamic linker
never needs to resolve references to either symbol. However, I
suppose a clash or bug could occur even with dynamic linking if
Emacs later loads a module that uses either symbol.
Although GnuTLS should be fixed, Emacs should link statically to
current and older GnuTLS versions in the meantime, and it should
avoid potential problems with dynamic linking. Renaming the two
clashing names is an easy way to do this. For consistency with
the new name for hash_lookup, also rename hash_lookup_with_hash
and hash_lookup_get_hash.
* src/fns.c (hash_find_with_hash): Rename from hash_lookup_with_hash.
(hash_find): Rename from hash_lookup.
(hash_find_get_hash): Rename from hash_lookup_get_hash.
(hash_char_array): Rename from hash_string.
All uses changed.
This fix is prompted by Emacs bug#71744.
The working hypothesis is that there are some bugs in Emacs,
and some in GCC’s diagnostics, and that this patch
fixes the Emacs bugs and works around the GCC diagnostic bugs.
The hypothesis is that GCC diagnostic bugs occur when GCC
coalesces variables or temporaries and some variables
are clobbered by setjmp and some vars/temps are not.
Part of this hypothesis involves GCC diagnosing the wrong variables.
Instead of ignoring the diagnostics, which the hypothesis suggests
indicate either problems in Emacs or in GCC, fix the Emacs bugs
and pacify the GCC false positives, with comments about the GCC bugs.
GCC’s true positives are helpful enough in squashing obscure bugs like
Emacs bug#71744, that it’s worth going to some effort to pacify
-Wclobbered instead of ignoring it.
* src/bytecode.c: Do not ignore -Wclobbered.
(exec_byte_code): Fix violations of the C standard, where setjmp
clobbered quitcounter and bc. If GCC_LINT && __GNUC__ && !__clang__,
work around GCC -Wclobbered warnings for bytestr_data and vectorp.
This makes comparison functions (=, /=, <, <=, >, >=, min, max) quite
a bit faster (10-20 %). Bytecode ops on fixnums are not affected,
nor is `value<`.
* src/data.c (arithcompare): Simplify the code to reduce the number of
branches. Remove the comparison code argument; instead, return the
relation encoded as bits, which can be tested cheaply. All callers
adapted.
* src/lisp.h (enum Arith_Comparison): Remove.
(Cmp_Bit_*, cmp_bits_t): New.
In preparation for the use of `PVEC_COMPILED` objects for
interpreted functions, rename them to use a more neutral name.
* src/lisp.h (enum pvec_type): Rename `PVEC_COMPILED` to `PVEC_CLOSURE`.
(enum Lisp_Compiled): Use `CLOSURE_` prefix i.s.o `COMPILED_`.
Also use `CODE` rather than `BYTECODE`.
(CLOSUREP): Rename from `COMPILEDP`.
(enum Lisp_Closure): Rename from `Lisp_Compiled`.
* src/alloc.c, src/bytecode.c, src/comp.c, src/data.c, src/eval.c,
* src/fns.c, src/lisp.h, src/lread.c, src/pdumper.c, src/print.c,
* src/profiler.c: Rename all uses accordingly.
* src/.gdbinit (xclosure): Rename from `xcompiled`.
(xcompiled): New obsolete alias.
(xpr): Adjust accordingly. Also adjust to new PVEC_CLOSURE tag name.
* src/bytecode.c (exec_byte_code):
We can safely assume that the immediate argument to varref and varset
is a bare symbol; the byte-compiler should guarantee that.
* src/bytecode.c (exec_byte_code):
Only use fast-path optimisations for calls and dynamic variable
reference and setting where the symbol is plain, which is much faster.
The obsolete lazy-loaded bytecode feature, enabled by
`byte-compile-dynamic`, slows down Lisp execution even when not in use
because every call to a bytecode function has to check that function
for laziness.
This change forces up-front loading of all lazy bytecode so that we
can remove all those checks. (Dynamically loaded doc strings are not
affected.)
There is no point in generating lazy bytecode any more so we stop
doing that; this simplifies the compiler. `byte-compile-dynamic` now
has no effect.
This is a fully compatible change; the few remaining users of
`byte-compile-dynamic` should not notice any difference.
* src/lread.c (bytecode_from_rev_list): Force eager loading of
lazy bytecode.
* src/bytecode.c (exec_byte_code): Remove lazy bytecode checks.
* src/eval.c (fetch_and_exec_byte_code, Ffetch_bytecode): Remove.
(funcall_lambda): Call exec_byte_code directly, avoiding checks.
* lisp/subr.el (fetch-bytecode): New definition, obsolete no-op.
* lisp/emacs-lisp/disass.el (disassemble-1):
* lisp/emacs-lisp/bytecomp.el (byte-compile-unfold-bcf):
Remove calls to fetch-bytecode.
(byte-compile-dynamic): Update doc string.
(byte-compile-close-variables, byte-compile-from-buffer)
(byte-compile-insert-header, byte-compile-output-file-form)
(byte-compile--output-docform-recurse, byte-compile-output-docform)
(byte-compile-file-form-defmumble):
Remove effects of byte-compile-dynamic.
* doc/lispref/compile.texi (Dynamic Loading): Remove node now that
the entire `byte-compile-dynamic` facility has been rendered inert.
* etc/NEWS: Announce changes.
This saves several words in the hash table object at the cost of an
indirection at runtime. This seems to be a gain in overall
performance.
FIXME: We cache hash test objects in a rather clumsy way. A better
solution is sought.
* src/lisp.h (struct Lisp_Hash_Table): Use a pointer to the test
struct. All references adapted.
* src/alloc.c (garbage_collect):
* src/fns.c (struct hash_table_user_test, hash_table_user_tests)
(mark_fns, get_hash_table_user_test): New state for caching test
structs, and functions managing it.
This improves performance in several ways. Separate functions are
used depending on whether the caller has a hash value computed or not.
* src/fns.c (hash_lookup_with_hash, hash_lookup_get_hash): New.
(hash_lookup): Remove hash return argument.
All callers adapted.
hash_lookup_with_hash hash_hash_t arg
Produce synthetic backtrace entries for `aref` and `aset` byte-ops
when the index is non-fixnum, or is out of range for vector or record
arguments (bug#64613).
* src/bytecode.c (exec_byte_code): Detect type and range errors
in-line for aref and aset.
* src/data.c (syms_of_data): Declare symbols Qaref and Qaset.
* test/lisp/emacs-lisp/bytecomp-tests.el
(bytecomp-tests--byte-op-error-cases): Add test cases.
Include calls to these primitives from byte-compiled code in
backtraces. For nth and elt, not all errors are covered.
(Bug#64613)
* src/bytecode.c (exec_byte_code): Add error backtrace records for
car, cdr, setcar, setcdr, nth and elt.
* src/data.c (syms_of_data): Add missing defsyms for car, setcar,
setcdr, nth and elt.
* test/lisp/emacs-lisp/bytecomp-tests.el
(bytecomp-tests--error-frame, bytecomp-tests--byte-op-error-cases)
(bytecomp--byte-op-error-backtrace): New test.
* src/editfns.c (narrow_to_region_internal): New function, which
contains the body previously in 'Fnarrow_to_region' but accepts
a third argument.
(Fnarrow_to_region): Use the new function. Update the docstring.
(Fwiden): Update the docstring.
* src/lisp.h: Prototype of the new function.
* src/xdisp.c (handle_fontified_prop): Use the new function instead
of 'Fnarrow_to_region'.
* src/process.c (Finternal_default_process_filter):
* src/lread.c (readevalloop): Remove the third argument to
'Fnarrow_to_region'.
* src/bytecode.c (exec_byte_code):
* lisp/emacs-lisp/comp.el (comp-limplify-lap-inst):
* lisp/emacs-lisp/bytecomp.el: Restore the statu quo ante.
* etc/NEWS: Remove the entry about the new optional argument.
* doc/lispref/positions.texi (Narrowing): Update the documentation.
* src/editfns.c (Fnarrow_to_region): Add the parameter to the
function, and handle it. Update docstring.
(unwind_locked_begv, unwind_locked_zv): New functions.
(Fwiden): Do nothing when restrictions are locked. Update
docstring.
(syms_of_editfns): Replace the 'inhibit-widen' symbol and variable
with a 'restrictions-locked' symbol and variable. Update docstring.
* src/xdisp.c (handle_fontified_prop): Use Fnarrow_to_region with
the new parameter.
(unwind_narrowed_zv): Remove function.
* src/process.c (Finternal_default_process_filter): Add a third
argument to Fnarrow_to_region.
* src/lread.c (readevalloop): Add a third argument to
Fnarrow_to_region.
* src/bytecode.c (exec_byte_code): Add a third argument to
Fnarrow_to_region.
* etc/NEWS (like): Mention the new parameter of 'narrow-to-region'.
* doc/lispref/positions.texi (Narrowing): Document it.
This is a cosmetic change only; there is no change in behaviour.
* lisp/emacs-lisp/bytecomp.el:
* src/bytecode.c (BYTE_CODES, exec_byte_code):
Update and/or remove incorrect, outdated or useless comments.
Clarify. Reorder where appropriate. Rename Bsave_current_buffer to
Bsave_current_buffer_OBSOLETE and Bsave_current_buffer_1 to
Bsave_current_buffer, reflecting the state since 1996.
* src/lisp.h (lisp_h_Qni): New macro.
(DEFUN): Use it.
* src/alloc.c (syms_of_alloc): Use it.
* src/bytecode.c (Fbyte_code): Fix Lisp_Object/int mixup.
* src/bytecode.c (valid_sp): static, not INLINE, as INLINE
should be used only in headers and between INLINE_HEADER_BEGIN
and INLINE_HEADER_END. No need for ‘inline’ here.
Using a plain C struct instead of type-punning Lisp_Object stack slots
makes the bytecode interpreter code more type-safe and potentially
faster (from better alias analysis), and the special-purpose accessors
are no longer needed. It also reduces the stack requirements when
using 64-bit Lisp_Object on 32-bit platforms.
* src/bytecode.c (enum stack_frame_index)
(sf_get_ptr, sf_set_ptr, sf_get_lisp_ptr, sf_set_lisp_ptr,
sf_get_saved_pc, sf_set_saved_pc): Remove.
(BC_STACK_SIZE): Now in bytes, not Lisp words.
(struct bc_frame): New.
(init_bc_thread, mark_bytecode, Finternal_stack_stats, valid_sp)
(exec_byte_code):
* src/lisp.h (struct handler, get_act_rec, set_act_rec):
Adapt to new struct bc_frame.
* src/bytecode.c (Fbyte_code):
* src/composite.c (Fclear_composition_cache):
Prefer CALLN to doing it by hand.
* src/fns.c (ccall2): Remove. All uses replaced by CALLN.
Use a dedicated stack for bytecode, instead of using the C stack.
Stack frames are managed explicitly and we stay in the same
exec_byte_code activation throughout bytecode function calls and
returns. In other words, exec_byte_code no longer uses recursion
for calling bytecode functions.
This results in better performance, and bytecode recursion is no
longer limited by the size of the C stack. The bytecode stack is
currently of fixed size but overflow is handled gracefully by
signalling a Lisp error instead of the hard crash that we get now.
In addition, GC marking of the stack is now faster and more precise.
Full precision could be attained if desired.
* src/alloc.c (ATTRIBUTE_NO_SANITIZE_ADDRESS): Make non-static.
* src/bytecode.c (enum stack_frame_index, BC_STACK_SIZE)
(sf_get_ptr, sf_set_ptr, sf_get_lisp_ptr, sf_set_lisp_ptr)
(sf_get_saved_pc, sf_set_saved_pc, init_bc_thread, free_bc_thread)
(mark_bytecode, Finternal_stack_stats, valid_sp): New.
(exec_byte_code): Adapt to use the new bytecode stack.
(syms_of_bytecode): Add defsubr.
* src/eval.c (unwind_to_catch): Restore saved stack frame.
(push_handler_nosignal): Save stack frame.
* src/lisp.h (struct handler): Add act_rec member.
(get_act_rec, set_act_rec): New.
* src/thread.c (mark_one_thread): Call mark_bytecode.
(finalize_one_thread): Free bytecode thread state.
(Fmake_thread, init_threads): Set up bytecode thread state.
* src/thread.h (struct bc_thread_state): New.
(struct thread_state): Add bytecode thread state.
Pass the function object and encoded arity, not the other components.
This speeds up several call paths and is necessary for improvements to
come.
* src/bytecode.c (Fbyte_code): Make a new byte code object for
execution. This is slower but performance isn't critical here.
(exec_byte_code): Retrieve components from the passed function.
* src/eval.c (fetch_and_exec_byte_code):
* src/lisp.h (exec_byte_code): Update signature.
* src/bytecode.c (BYTE_CODES, enum byte_code_op, exec_byte_code):
Don't display custom messages in debug mode for Bscan_buffer and
Bset_mark which were removed long ago.
* src/bytecode.c (FETCH2):
Use `|` instead of `+` to combine the bytes forming a 16-bit immediate
argument so that GCC (prior to version 12) recognises the idiom and
generates a 16-bit load. This applies for little-endian machines with
cheap unaligned accesses such as x86[-64], arm64 and power64le.
This 1-character change results in a measurable speed gain on many
kinds of Lisp code, as 16-bit immediates are used by all jump
instructions.
Clang performs this optimisation for both `+` and `|` from version 10.