The recent changes to clustering make this more likely to happen.
This doesn't handle overflow resulting from changing styles in the tab
title, but those are less common.
refs: https://github.com/wez/wezterm/issues/2560
Since we're no longer tied to contiguous Vertex slices, we can
record the Quad data used for HeapQuadAllocator in a smaller structure,
so that's what this does.
It reduces the per-Quad storage from 272 bytes down to 84 bytes,
which helps with overall memory usage: the default cache size is 1024
lines worth of quads, so this can add up to multiple MB of RAM.
refs: https://github.com/wez/wezterm/issues/2626
This reduces peak heap usage by several MB by making better use
of allocated memory--no wasted overhead in the Vec capacity.
refs: https://github.com/wez/wezterm/issues/2626
When a line is rapidly updated with only some of the cells being
actually changed (eg: progress counter or other status being frequently
updated), it is desirable to avoid paying the cost of shaping the entire
line.
When bidi is not enabled we can assume that it is safe to break clusters
on whitespace boundaries. Doing so allows each of those whitespace
separated words to be shaped and potentially cached independently,
which reduces the amount of CPU time spent for the whole line.
This commit just adjusts the clustering, which reduces the CPU
utilization a bit.
refs: https://github.com/wez/wezterm/issues/2701
Do it "more properly": use intrusive list linkage to manage three
indices:
* hash lookup
* recency
* frequency
eviction is frequency based, but in order to avoid things that were
super hot in the past and that are no longer hot clogging up the cache,
eviction will incrementally age out least recently used entries that
haven't been active in the span of some number of get/put operations.
Aging scales down the frequency value to reduce its strength, so an aged
item isn't necessarily immediately a candidate for removal, it just
makes it more likely to be picked up by the frequency based removal as
it goes unused for an extended period.
In a56904e40d the desktop file was patched
to use "wezterm start" instead of "wezterm". As an unneeded addendum
that patch also included the unnecessary addition of ending command-line
parsing by passing the "--" option at the end.
As it turns out, some consumers of wezterm's desktop file want wezterm
to parse command line flags. For example KDE's kio passes the whole
cmdline via the "-e" flag, because it is widely used for most terminal
emulators as the primary mean of passing the cmdline.
To solve this we remove the unneeded "--" again, because we now also
support the "-e" option.
After all, all trailing arguments will automatically be parsed by
wezterm as the cmdline of the program to run.
The only sideeffect of this change is that we now cannot longer start
programs that share a name with a "wezterm start" option, for example if
the user has installed an executable at /usr/bin/--always-new-process
then this edge case will not work anymore.
Given that this would be an extremely unlikely scenario, it makes more
sense to improve compatibility by supporting the usecase of passing the
cmdline with the "-e" flag.
refs: #2622
refs: #2271
refs: https://bugs.kde.org/show_bug.cgi?id=459616
Right now wezterm already allows to pass a cmdline to execute (instead
of the shell) by calling "wezterm start" with trailing arguments, e.g.
wezterm start -- bash
However, most other terminals implement this via a "-e" option. This
seems to be adopted widely in the wild, such that some third-party
frameworks just blindly expect the user's terminal to use the "-e"
option for this.
One such notable framework is kio from KDE Plasma, that calls the user's
terminal in that way when launching a desktop file that uses
Terminal=true. [1]
To solve this problem, we add a compatibility layer by adding a dummy
"-e" option. This will then consume the "-e" leaving the remaining
arguments as trailing arguments, which will later be consumed by our
existing implementation in the "prog" option.
Given that clap does not really support multiple arguments writing to
the same destination [2], this seems like the most sane implementation,
even if it is a hack.
It seems to work reliable, even for edge cases where we pass wezterm
options as trailing arguments, e.g. the following will just work and do
the expected outcome (and will **not** parse "--position" as a wezterm
argument):
wezterm start -e echo --position 10,10
Fixes#2622
[1] https://bugs.kde.org/show_bug.cgi?id=459616
[2] https://github.com/clap-rs/clap/issues/3146
We were only using block_on from it, which we can call from the
underlying async_io crate.
Notably, removing async_std from the deps avoids async-global-executor
being pulled in and spawning nproc threads that are never used by
wezterm.
I can't think of a good reason for this being here. I think I
may have been lazy about resolving the lifetime annotations
and just stuck in an extra buffer while building the original
version of this logic, and then forgot about it.
This commit resolves the lifetime annotations and directly
references the passed in buffer.
refs: https://github.com/wez/wezterm/issues/2626
I spent a few hours in heap profilers. What I found was:
* Inefficient use of heap when building up runs of
`Action::Print(char)`.
-> Solve by adding `Action::PrintString(String)`
and accumulating utf8 bytes rather than u32 codepoints.
* Inefficient use of heap when building Quad buffers: the default
exponential growth of `Vec` tended to waste 40%-75% of the allocated
capacity, and since we could keep ~1024 of these in cache, there's
a lot of potential for waste.
-> Solve by bounding the growth to 64 at a time. This has similar
characteristics to exponential growth at the default 80x24 terminal
size. May need to add a config option for this step size for users
with very large terminals.
* Lazy eviction from the LFU caches. The underlying cache advisor is
somewhat probabilistic and has a minimum cache size of 256, making
it difficult to maintain low heap utilization.
-> Solve by replacing it with a very simple LFU algorithm. It doesn't
seem to hurt much at the default terminal size with the default
cache sizes. If we make the cache sizes smaller, its overhead is
reduced.
Some further experimentation is needed to adjust defaults, but this
should help reduce heap usage.
refs: https://github.com/wez/wezterm/issues/2626