diff options
| author | Marc Mutz <marc.mutz@qt.io> | 2025-07-22 13:50:10 +0200 |
|---|---|---|
| committer | Marc Mutz <marc.mutz@qt.io> | 2025-07-22 21:12:39 +0200 |
| commit | cadb4c231789e11dbae40e88e5539d75ee8be030 (patch) | |
| tree | a67f8901dbde4349c996c4d17a6c6d6df2dae05d /src/corelib/kernel/qobject.cpp | |
| parent | 569928b640c3c086c26fdb5a8a9c3379c9cd7fa5 (diff) | |
QAnyStringView: add a new private operation decreaseSize()
The setSize() function has the problem that it works on the absolute
value of m_size, including the tag, causing machine-word-sized
immediate loads to be inserted into the executable code.
Use it in chop() and sliced(pos).
The new operation works on a relative basis, so, one would expect, can
be implemented without those huge immediate value loads, and, indeed,
for these two functions:
QAnyStringView foo(QAnyStringView s, qsizetype n)
{
return s.sliced(n);
}
One immediate load gets removed per function:
After | Before
-------------------------------------------------------------------------------
foo(QAnyStringView, long long): |foo(QAnyStringView, long long):
movabsq $-4611686018427387904, %rax | movabsq $-4611686018427387904, %r8
movq %rdx, %r8 | xorl %ecx, %ecx
xorl %ecx, %ecx | movq %rdx, %r9
movabsq $-9223372036854775808, %rdx | movabsq $-9223372036854775808, %rax
andq %rsi, %rax | andq %rsi, %r8
cmpq %rdx, %rax | cmpq %rax, %r8
sete %cl | sete %cl
subq %r8, %rsi | addq $1, %rcx
addq $1, %rcx | imulq %rdx, %rcx
movq %rsi, %rdx | movabsq $4611686018427387903, %rdx
imulq %r8, %rcx | andq %rsi, %rdx
leaq (%rdi,%rcx), %rax | subq %r9, %rdx
ret | leaq (%rdi,%rcx), %rax
| orq %r8, %rdx
| ret
And a loop over slice() (the current way to iterate a QAnyStringView
by code-point):
extern void use(QChar) noexcept;
void loop(QAnyStringView s)
{
while (!s.isEmpty()) {
use(s.front());
s.slice(1);
}
}
Needs one register less:
After | Before
-------------------------------------------------------------------------------
loop(QAnyStringView): |loop(QAnyStringView):
| pushq %r15
pushq %r14 | pushq %r14
pushq %r13 | pushq %r13
pushq %r12 | pushq %r12
movabsq $4611686018427387903, %r12 | movabsq $4611686018427387903, %r12
pushq %rbp | pushq %rbp
pushq %rbx | movq %rsi, %rbp
testq %r12, %rsi | pushq %rbx
je .L1929 | subq $8, %rsp
movabsq $-4611686018427387904, %r14 | andq %r12, %rbp
movq %rdi, %rbp | je .L1929
movq %rsi, %rbx | movabsq $-4611686018427387904, %r14
movabsq $-9223372036854775808, %r13 | movq %rdi, %r15
jmp .L1930 | movabsq $-9223372036854775808, %r13
.L1931: | jmp .L1930
movzbl 0(%rbp), %edi |.L1931:
subq $1, %rbx | movzbl (%r15), %edi
call use(QChar)@PLT | call use(QChar)@PLT
movl $1, %eax | movl $1, %eax
addq %rax, %rbp |.L1932:
testq %r12, %rbx | subq $1, %rbp
je .L1929 | addq %rax, %r15
.L1930: | movq %rbp, %rsi
movq %rbx, %rax | orq %rbx, %rsi
andq %r14, %rax | movq %rsi, %rbp
cmpq %r13, %rax | andq %r12, %rbp
jne .L1931 | je .L1929
movzwl 0(%rbp), %edi |.L1930:
subq $1, %rbx | movq %rsi, %rbx
call use(QChar)@PLT | andq %r14, %rbx
movl $2, %eax | cmpq %r13, %rbx
addq %rax, %rbp | jne .L1931
testq %r12, %rbx | movzwl (%r15), %edi
jne .L1930 | call use(QChar)@PLT
.L1929: | movl $2, %eax
popq %rbx | jmp .L1932
popq %rbp |.L1929:
popq %r12 | addq $8, %rsp
popq %r13 | popq %rbx
popq %r14 | popq %rbp
ret | popq %r12
| popq %r13
| popq %r14
| popq %r15
| ret
(all compiled with GCC 11 and -O2 -exeptions, but without the security
stuff we add these days)
Amends 41a994db063e4dc7796c0a33d3f1baf2c30366f6.
Pick-to: 6.10 6.9 6.8 6.5
Change-Id: Ia76cd2273596202d7a433cb6bec53382532087d2
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
0 files changed, 0 insertions, 0 deletions
