![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
Functions | |
| objects (build_dir) | |
| source_of (obj, build_dir) | |
| scan (build_dir) | |
| split_header_defined (state_syms) | |
| propagate (defines, state_syms, calls) | |
| main () | |
Variables | |
| REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| MUTABLE_SECTIONS = re.compile(r"^\.(data|bss|sdata|sbss|tdata|tbss)(\.|$)") | |
| READONLY_SECTIONS = re.compile(r"^\.(rodata|data\.rel\.ro)(\.|$)") | |
| NOISE | |
Classify every translation unit as stateless or stateful, and say why.
"Stateless" here means: calling it twice with the same arguments does the same thing, because
it reads and writes nothing that outlives the call. That is the property that lets a module be
reused, tested, threaded, or ported without dragging the application with it -- and the whole
point of sorting the tree by it is that checking becomes mechanical. Once a directory is known
stateless, anything built only from it is stateless too, and nobody has to re-derive that.
Measured from the linker's own view, not from reading source: `nm` on the compiled objects.
DIRECT the object defines mutable storage at file scope -- `d`/`b` for a static, `D`/`B`
for a global. Read-only data (`r`/`R`) is not state.
INDIRECT the object calls a symbol defined by an object that has state. Transitive, so a
module three hops from a global is still reported, with the chain that gets there.
Needs a build directory whose objects still carry symbol tables: an LTO build (`-flto
-fno-fat-lto-objects`, which this tree uses in Release) emits bytecode that `nm` cannot read.
Use a Debug build.
Usage:
tools/statelessness_audit.py [--build DIR] [--dir src/system] [--json]
tools/statelessness_audit.py --chains dt_screen_dpi # why is this one stateful?
| statelessness_audit.main | ( | void | ) |
Definition at line 197 of file statelessness_audit.py.
References main(), propagate(), scan(), and split_header_defined().
Referenced by main().
| statelessness_audit.objects | ( | build_dir | ) |
Definition at line 51 of file statelessness_audit.py.
Referenced by scan().
| statelessness_audit.propagate | ( | defines, | |
| state_syms, | |||
| calls | |||
| ) |
Stateful = has state, or reaches something that has. Returns file -> chain.
Definition at line 179 of file statelessness_audit.py.
Referenced by main().
| statelessness_audit.scan | ( | build_dir | ) |
Definition at line 83 of file statelessness_audit.py.
References objects(), and source_of().
Referenced by main().
| statelessness_audit.source_of | ( | obj, | |
| build_dir | |||
| ) |
Map an object path back to its source. Two shapes, and getting only the first is how src/widgets -- an entire CMake target -- silently reported zero translation units: build/src/CMakeFiles/lib_ansel.dir/common/bar.c.o -> src/common/bar.c build/src/widgets/CMakeFiles/ansel_widgets.dir/bar.c.o -> src/widgets/bar.c The general rule covers both: drop the build directory, then drop the `CMakeFiles/<target>.dir/` component wherever it sits, and what is left is the path relative to the project root.
Definition at line 60 of file statelessness_audit.py.
Referenced by scan().
| statelessness_audit.split_header_defined | ( | state_syms | ) |
A mutable symbol defined in more than one object came from a header. `static const char *dt_supported_extensions[]` in config.h and `loaders_info[]` in common/image.h are emitted into every translation unit that includes them, so they show up as "own state" for 170 files that never heard of them. They are still mutable storage -- `const char *` makes the pointee const, not the array -- and each copy is independently writable, which is worth fixing at the header. But they are the header's problem, not each includer's, and counting them per-includer buries every real finding.
Definition at line 131 of file statelessness_audit.py.
Referenced by main().
| statelessness_audit.MUTABLE_SECTIONS = re.compile(r"^\.(data|bss|sdata|sbss|tdata|tbss)(\.|$)") |
Definition at line 41 of file statelessness_audit.py.
| statelessness_audit.NOISE |
Definition at line 45 of file statelessness_audit.py.
| statelessness_audit.READONLY_SECTIONS = re.compile(r"^\.(rodata|data\.rel\.ro)(\.|$)") |
Definition at line 42 of file statelessness_audit.py.
| statelessness_audit.REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
Definition at line 33 of file statelessness_audit.py.