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