libxtc
0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_tailcall.h
1
/*-
2
* Copyright (c) 2026, The XTC Project
3
* Use of this source code is governed by the ISC License.
4
*
5
* src/inc/xtc_tailcall.h
6
* Mark functions/call-sites as MUST-be-tail-called. GCC and
7
* Clang both perform tail-call optimization (TCO) when the
8
* last operation in a function is a call to another function
9
* whose return value is also returned. We document the
10
* intent at the call site so a script can verify that the
11
* compiler actually emitted a `jmp` (or arch-equivalent) and
12
* not a `call` followed by `ret`.
13
*
14
* Usage:
15
* - At a call-site that MUST be tail-called for correctness
16
* (e.g. avoiding stack growth in a deep dispatch chain),
17
* annotate via XTC_MUSTTAIL:
18
*
19
* return XTC_MUSTTAIL fn(args);
20
*
21
* - GCC's `__attribute__((musttail))` (15+) and Clang's
22
* `[[clang::musttail]]` are honored. On older toolchains
23
* we fall back to `__attribute__((always_inline))` of a
24
* helper that returns directly.
25
*
26
* Validation:
27
* scripts/check-tailcalls.sh disassembles the static lib
28
* and confirms each annotated site is a `jmp` not a `call`.
29
* Run via `make check-tailcalls`.
30
*
31
* When TCO matters in xtc:
32
* - State-machine dispatch: handler returning a tail-call to
33
* the next state's handler (e.g. parse trees).
34
* - Scheduler dispatch: loop's task-step jumping into the
35
* coroutine entry without growing the loop's stack.
36
* - Lock-free fast paths where one inline helper jumps to
37
* the slow path on miss.
38
*/
39
40
#ifndef XTC_TAILCALL_H
41
#define XTC_TAILCALL_H
42
43
/* musttail is a *statement* attribute, not a function attribute.
44
* Both clang's `[[clang::musttail]]` and gcc-15's
45
* `__attribute__((musttail))` are accepted as statement attributes,
46
* but only in compilers that parse C2x bracket attributes (clang)
47
* or have GCC 15's extension. In strict C11 mode -- which xtc uses --
48
* we fall back to a no-op and rely on the optimizer. The
49
* `scripts/check-tailcalls.sh` validator inspects the .o to confirm
50
* `jmp` was emitted regardless. */
51
/* XTC_MUSTTAIL is a marker; it's prefixed to a function call inside
52
* a return statement to signal intent. In gcc 15+ and clang's C2x
53
* mode the attribute can be attached to the return statement itself
54
* (`__attribute__((musttail)) return foo();`) but the syntactic
55
* position varies enough across toolchains that we keep the macro
56
* as a no-op universally and rely on:
57
* 1. the -O2 optimizer doing TCO when it can, and
58
* 2. scripts/check-tailcalls.sh validating the .o emitted `jmp`.
59
* When compiler enforcement matters more than convenience, callers
60
* can use the explicit form directly. */
61
#define XTC_MUSTTAIL
/* no-op marker; see check-tailcalls.sh */
62
63
/* Marker macro for the validator script: annotated call sites
64
* become a #pragma comment that survives into the disassembly's
65
* line metadata. */
66
#if defined(XTC_TAILCALL_MARK_SITES)
67
# define XTC_TAIL_CALL(expr) \
68
(__extension__ ({ \
69
_Pragma("message \"xtc-tailcall-marker\""); \
70
XTC_MUSTTAIL expr; \
71
}))
72
#else
73
# define XTC_TAIL_CALL(expr) (XTC_MUSTTAIL expr)
74
#endif
75
76
#endif
/* XTC_TAILCALL_H */
src
inc
xtc_tailcall.h
Generated by
1.9.8