diff options
| author | Andrea Corallo | 2026-03-12 14:30:54 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2026-03-12 14:30:54 +0100 |
| commit | 6198bb89b453a8b93113ac6bbb102043f5636334 (patch) | |
| tree | 0006eddd65f0a0508be443f1a0cc3f22d437c74f /test/src/comp-tests.el | |
| parent | fe121ef586b4adf2befc7e2af42d65f7acc25891 (diff) | |
| download | emacs-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/src/comp-tests.el')
| -rw-r--r-- | test/src/comp-tests.el | 85 |
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. | ||
| 1678 | The caller should produce EXPECTED-FIRST and EXPECTED-SECOND after | ||
| 1679 | successive 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. |
| 1653 | See `comp--func-unique-in-cu-p'." | 1710 | See `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. |
| 1669 | See `comp--func-unique-in-cu-p'." | 1750 | See `comp--func-unique-in-cu-p'." |