aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorAndrea Corallo2026-03-12 14:30:54 +0100
committerAndrea Corallo2026-03-12 14:30:54 +0100
commit6198bb89b453a8b93113ac6bbb102043f5636334 (patch)
tree0006eddd65f0a0508be443f1a0cc3f22d437c74f /test
parentfe121ef586b4adf2befc7e2af42d65f7acc25891 (diff)
downloademacs-scratch/better-comp.tar.gz
emacs-scratch/better-comp.zip
nativecomp: optimize local CU calls at speed 2scratch/better-comp
* etc/NEWS: Document speed-2 local call optimization. * etc/TODO: Remove completed item. * lisp/emacs-lisp/comp.el (comp--cu-local-func-c-name-v): New function. (comp--call-optim-form-call): Enable named local direct calls at speed 2. (comp--function-trampoline-form): New helper. (comp-trampoline-compile, comp-local-function-trampoline-compile): Share trampoline generation. * lisp/emacs-lisp/comp-run.el (comp-local-function-trampoline--install-now): New function. (comp-local-function-trampoline-install): Install local trampolines. Defer trampoline compilation until after load. * src/comp.c (emit_call, emit_ctxt_code, compile_function) (load_comp_unit, unload_comp_unit): Add local function relocation support. (native_comp_local_function_p): New function. (comp--install-local-function-trampoline): New subr. (syms_of_comp): Register it and update trampoline docs. * src/comp.h (Lisp_Native_Comp_Unit): Add local relocation slot. (native_comp_local_function_p): Declare. * src/data.c (Ffset): Install local trampolines for redefined named local native functions. Keep skipping anonymous lambdas. * src/pdumper.c: Clear local relocation state. * test/src/comp-tests.el (comp-tests--run-in-sub-emacs): New helper. (comp-tests--direct-call-redefinition-form): New helper. (comp-tests-direct-call-redefinition-speed-split): New test. (comp-tests-anonymous-lambda-recompile): New test. (comp-tests-direct-call-with-lambdas): Use an explicit output file.
Diffstat (limited to 'test')
-rw-r--r--test/src/comp-tests.el85
1 files changed, 83 insertions, 2 deletions
diff --git a/test/src/comp-tests.el b/test/src/comp-tests.el
index e322bdb057e..32d5859562f 100644
--- a/test/src/comp-tests.el
+++ b/test/src/comp-tests.el
@@ -1648,6 +1648,63 @@ folded."
1648 (or (comp-tests-mentioned-p 'direct-call insn) 1648 (or (comp-tests-mentioned-p 'direct-call insn)
1649 (comp-tests-mentioned-p 'direct-callref insn)))))) 1649 (comp-tests-mentioned-p 'direct-callref insn))))))
1650 1650
1651(defun comp-tests--unbind-direct-call-functions ()
1652 "Clear shared definitions used by the direct-call fixture."
1653 (dolist (sym '(comp-tests-direct-call-caller-f
1654 comp-tests-direct-call-callee-f))
1655 (when (fboundp sym)
1656 (fmakunbound sym))))
1657
1658(defun comp-tests--run-in-sub-emacs (form)
1659 "Run FORM in a fresh batch Emacs and return (STATUS . OUTPUT)."
1660 (let* ((default-directory (expand-file-name ".." invocation-directory))
1661 (emacs (expand-file-name invocation-name invocation-directory))
1662 (buf (generate-new-buffer " *comp-sub-emacs*")))
1663 (unwind-protect
1664 (cons
1665 (call-process emacs nil buf nil
1666 "--batch" "--no-init-file" "--no-site-file"
1667 "--no-site-lisp"
1668 "--eval" "(setq native-comp-eln-load-path (list temporary-file-directory))"
1669 "-L" "test" "-l" "ert"
1670 "-l" "test/src/comp-tests.el"
1671 "--eval" (prin1-to-string form))
1672 (with-current-buffer buf
1673 (buffer-string)))
1674 (kill-buffer buf))))
1675
1676(defun comp-tests--direct-call-redefinition-form (speed expected-first expected-second)
1677 "Return a form checking direct-call redefinition at SPEED.
1678The caller should produce EXPECTED-FIRST and EXPECTED-SECOND after
1679successive callee redefinitions."
1680 `(let* ((native-comp-speed ,speed)
1681 (native-comp-eln-load-path (list temporary-file-directory))
1682 (source ,(ert-resource-file "comp-test-direct-call.el"))
1683 (output (make-temp-file ,(format "comp-test-direct-call-speed%d-" speed)
1684 nil ".eln")))
1685 (comp-tests--unbind-direct-call-functions)
1686 (delete-file output)
1687 (let ((comp-post-pass-hooks
1688 '((comp--final
1689 (lambda (_)
1690 (unless (comp-tests-has-direct-call-p
1691 'comp-tests-direct-call-caller-f)
1692 (error "missing direct call optimization")))))))
1693 (native-compile source output))
1694 (load output)
1695 (let ((orig (symbol-function 'comp-tests-direct-call-callee-f)))
1696 (unwind-protect
1697 (progn
1698 (fset 'comp-tests-direct-call-callee-f
1699 (lambda (x) (+ x 100)))
1700 (unless (= (comp-tests-direct-call-caller-f 3) ,expected-first)
1701 (error "unexpected first result at speed %d" ,speed))
1702 (fset 'comp-tests-direct-call-callee-f
1703 (lambda (x) (+ x 200)))
1704 (unless (= (comp-tests-direct-call-caller-f 3) ,expected-second)
1705 (error "unexpected second result at speed %d" ,speed)))
1706 (fset 'comp-tests-direct-call-callee-f orig)))))
1707
1651(comp-deftest direct-call-with-lambdas () 1708(comp-deftest direct-call-with-lambdas ()
1652 "Check that anonymous lambdas don't prevent direct calls at speed 3. 1709 "Check that anonymous lambdas don't prevent direct calls at speed 3.
1653See `comp--func-unique-in-cu-p'." 1710See `comp--func-unique-in-cu-p'."
@@ -1657,13 +1714,37 @@ See `comp--func-unique-in-cu-p'."
1657 (lambda (_) 1714 (lambda (_)
1658 (should (comp-tests-has-direct-call-p 1715 (should (comp-tests-has-direct-call-p
1659 'comp-tests-direct-call-caller-f))))))) 1716 'comp-tests-direct-call-caller-f)))))))
1660 (load (native-compile 1717 (let* ((source (ert-resource-file "comp-test-direct-call.el"))
1661 (ert-resource-file "comp-test-direct-call.el"))) 1718 (output (make-temp-file "comp-test-direct-call-lambdas-" nil ".eln")))
1719 (comp-tests--unbind-direct-call-functions)
1720 (delete-file output)
1721 (native-compile source output)
1722 (load output))
1662 (declare-function comp-tests-direct-call-caller-f nil) 1723 (declare-function comp-tests-direct-call-caller-f nil)
1663 (should (native-comp-function-p 1724 (should (native-comp-function-p
1664 (symbol-function 'comp-tests-direct-call-caller-f))) 1725 (symbol-function 'comp-tests-direct-call-caller-f)))
1665 (should (= (comp-tests-direct-call-caller-f 3) 4)))) 1726 (should (= (comp-tests-direct-call-caller-f 3) 4))))
1666 1727
1728(comp-deftest anonymous-lambda-recompile ()
1729 "Check that recompiling standalone lambdas does not recurse via `fset'."
1730 (let ((f1 (native-compile '(lambda () 1)))
1731 (f2 (native-compile '(lambda () 2))))
1732 (should (native-comp-function-p f1))
1733 (should (native-comp-function-p f2))
1734 (should (= (funcall f1) 1))
1735 (should (= (funcall f2) 2))))
1736
1737(comp-deftest direct-call-redefinition-speed-split ()
1738 "Check speed-2 and speed-3 redefinition behavior for named direct calls."
1739 (dolist (case '((2 103 203) (3 4 4)))
1740 (pcase-let* ((`(,speed ,expected-first ,expected-second) case)
1741 (`(,status . ,output)
1742 (comp-tests--run-in-sub-emacs
1743 (comp-tests--direct-call-redefinition-form
1744 speed expected-first expected-second))))
1745 (ert-info ((format "speed %d subprocess output:\n%s" speed output))
1746 (should (zerop status))))))
1747
1667(comp-deftest direct-call-with-duplicate-names () 1748(comp-deftest direct-call-with-duplicate-names ()
1668 "Check that duplicate names only block their own direct calls. 1749 "Check that duplicate names only block their own direct calls.
1669See `comp--func-unique-in-cu-p'." 1750See `comp--func-unique-in-cu-p'."