Closes #522
vt: limit maximum value of params in vt_param_get() #523
param-value-limit into master @ -13,0 +14,4 @@
// We zero excess bits in parsed param values. In most cases this will
// effectively be a no-op; but it prevents negative returns for edge
// cases involving unusually large values.
static_assert(INT_MAX >= 0x7fffffff, "POSIX requires INT_MAX >= 0x7fffffff");
nit/style: for large comments like this, use:
/*
* This is a very long comment
*/
@ -13,1 +17,4 @@
static_assert(INT_MAX >= 0x7fffffff, "POSIX requires INT_MAX >= 0x7fffffff");
const unsigned value_mask = 0x7fffffff;
if (term->vt.params.idx > idx) {
I also noted that this:
diff --git a/vt.h b/vt.h
index e4d67c8..033e023 100644
--- a/vt.h
+++ b/vt.h
@@ -17,7 +17,7 @@ vt_param_get(const struct terminal *term, size_t idx, int default_value)
static_assert(INT_MAX >= 0x7fffffff, "POSIX requires INT_MAX >= 0x7fffffff");
const unsigned value_mask = 0x7fffffff;
- if (term->vt.params.idx > idx) {
+ if (likely(term->vt.params.idx > idx)) {
unsigned value = term->vt.params.v[idx].value & value_mask;
return value != 0 ? (int)value : default_value;
}
generates slightly smaller code:
0000000000000000 <vt_param_get>:
0: 89 d0 mov %edx,%eax
2: 0f b6 97 24 05 00 00 movzbl 0x524(%rdi),%edx
9: 48 39 f2 cmp %rsi,%rdx
c: 76 14 jbe 22 <vt_param_get+0x22>
e: 48 8d 14 f6 lea (%rsi,%rsi,8),%rdx
12: 8b 94 d7 a4 00 00 00 mov 0xa4(%rdi,%rdx,8),%edx
19: 81 e2 ff ff ff 7f and 0ドルx7fffffff,%edx
1f: 0f 45 c2 cmovne %edx,%eax
22: c3 ret
vs.
0000000000000000 <vt_param_get>:
0: 89 d0 mov %edx,%eax
2: 0f b6 97 24 05 00 00 movzbl 0x524(%rdi),%edx
9: 48 39 f2 cmp %rsi,%rdx
c: 77 02 ja 10 <vt_param_get+0x10>
e: c3 ret
f: 90 nop
10: 48 8d 14 f6 lea (%rsi,%rsi,8),%rdx
14: 8b 94 d7 a4 00 00 00 mov 0xa4(%rdi,%rdx,8),%edx
1b: 81 e2 ff ff ff 7f and 0ドルx7fffffff,%edx
21: 0f 45 c2 cmovne %edx,%eax
24: c3 ret
I'm not so sure if this branch really is "likely", even though the code does look a bit cleaner. 033円[K and 033円[m seem quite common in TUI programs. I think it's a slippery slope to use it based on specific results, rather than as part of a covenant with the compiler.
Hmm, on second thoughts, most shells and curses programs do seem to generate a lot more CSI sequences with params than without them. I've added this as an additional commit.
Ah, ok :)
I'll run some benchmarks later today, but I think we wont see a difference. Compiling vt_param_get() as a standalone function, we have:
before:
0000000000000000 <vt_param_get>:
0: 89 d0 mov %edx,%eax
2: 0f b6 97 24 05 00 00 movzbl 0x524(%rdi),%edx
9: 48 39 f2 cmp %rsi,%rdx
c: 77 02 ja 10 <vt_param_get+0x10>
e: c3 ret
f: 90 nop
10: 48 8d 14 f6 lea (%rsi,%rsi,8),%rdx
14: 8b 94 d7 a4 00 00 00 mov 0xa4(%rdi,%rdx,8),%edx
1b: 85 d2 test %edx,%edx
1d: 0f 45 c2 cmovne %edx,%eax
20: c3 ret
after:
0000000000000000 <vt_param_get>:
0: 89 d0 mov %edx,%eax
2: 0f b6 97 24 05 00 00 movzbl 0x524(%rdi),%edx
9: 48 39 f2 cmp %rsi,%rdx
c: 77 02 ja 10 <vt_param_get+0x10>
e: c3 ret
f: 90 nop
10: 48 8d 14 f6 lea (%rsi,%rsi,8),%rdx
14: 8b 94 d7 a4 00 00 00 mov 0xa4(%rdi,%rdx,8),%edx
1b: 81 e2 ff ff ff 7f and 0ドルx7fffffff,%edx
21: 0f 45 c2 cmovne %edx,%eax
24: c3 ret
i.e. the and from the mask replaces a test.
43ed983ce1
to 29971f5787
29971f5787
to 2412d78268
I'm not so sure if this branch really is "likely", even though the code does look a bit cleaner. 033円[K and 033円[m seem quite common in TUI programs.
You're right. And the benchmarks support it as well.
I'll run some benchmarks later today, but I think we wont see a difference.
I'm getting a ~2.5% slowdown on my workstation. It's not much, but it's pretty consistent. But I don't see any other realistic options.
@ -16,0 +19,4 @@
static_assert(INT_MAX >= 0x7fffffff, "POSIX requires INT_MAX >= 0x7fffffff");
const unsigned value_mask = 0x7fffffff;
if (likely(term->vt.params.idx > idx)) {
Did we misunderstand each other? When I benched this I didn't see any improvements at all, plus, I agree with you, sequences that rely on the default value is probably very common.
Oops. No, I was mid way through adding it when I saw your reply. I'll revert it.
Just saw your other comment, ignore this :)
f37bc86df0
to 2412d78268
@craigbarnes shall we merge this one?
@dnkl Sure. I've pushed it as 74f740c975. My habit of cherry-picking instead of merging got the better of me, so I guess codeberg won't recognize it as being merged. I'll try to avoid that in future.
After the latest gitea update, it's gotten much worse at recognizing manual merges in general.
There should be a "manual merge" button though, where you can fill in the merge commit hash manually. Let me see if that button reappears if I re-open the PR...
Let me see if that button reappears if I re-open the PR...
It did :)
My habit of cherry-picking instead of merging got the better of me, so I guess codeberg won't recognize it as being merged. I'll try to avoid that in future.
No worries, it's not the end of the world :)
No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?