summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.cpp
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2025-07-22 13:50:10 +0200
committerMarc Mutz <marc.mutz@qt.io>2025-07-22 21:12:39 +0200
commitcadb4c231789e11dbae40e88e5539d75ee8be030 (patch)
treea67f8901dbde4349c996c4d17a6c6d6df2dae05d /src/corelib/kernel/qobject.cpp
parent569928b640c3c086c26fdb5a8a9c3379c9cd7fa5 (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