[Development] Feature Freeze Exception: QStringView
Marc Mutz
marc.mutz at kdab.com
Fri Feb 3 08:49:24 CET 2017
On Friday 03 February 2017 08:00:16 Philippe wrote:
> On Thu, 02 Feb 2017 23:52:26 +0100
>
> Kevin Kofler <kevin.kofler at chello.at> wrote:
> > > On Tuesday 31 January 2017 15:24:18 Philippe wrote:
> > >> I just want to highlight, that QStringView is not COW friendly. AFAIK.
> >
> > That alone makes it actually a pessimization.
>
> This is why Thiago commented with:
> >But we still have to have QString overloads in public functions,
> >otherwise creating full copies would now suddenly cost something.
Here's another reason to have a compile-time option to turn off QString
overloads: Many, many projects (incl. almost all of the Qt tests) pass
QLatin1String or (8-bit) C string literals to functions taking QString.
When the QString overload is replaced by a QStringView one, these calls become
errors. I don't mean to say that's a good thing going forward into Qt 6, but I
do say that having this option (and nothing more is being discussed atm) will
be very helpful in porting existing users of QL1S and C string literals to
QStringView:
- lb->setText("&OK"); // should probably use tr(), but assume it doesn't
+ lb->setText(u"&OK"); // should probably use tr(), but assume it doesn't
Done. Now the QStringView overload is chosen, and the QString creation is
hidden in an out-of-line function. You wanted to know what the effect is.
Brace yourself.
Test functions:
extern void setLabelQStringCRef(const QString &);
extern void setLabelQStringView(QStringView);
void callSetLabelQStringCRef() {
setLabelQStringCRef("&OK");
// pass by value is identical on call site, because the compiler
// cannot prove that the dtor is a no-op, but at run-time, there
// will be no manipulation of the atomic int ref count.
}
void callSetLabelQStringView() {
setLabelQStringView(u"&OK");
}
Results on GCC 6.1.1, compiled with the same settings as our tests:
_Z23callSetLabelQStringCRefv: |
_Z23callSetLabelQStringViewv:
pushq %rbp | subq $8, %rsp
pushq %rbx | xorl %edi,
%edi
leaq .LC8(%rip), %rdi | cmpw $0,
.LC9(%rip)
movl $3, %esi | je .L74
subq $24, %rsp | leaq
.LC9(%rip), %rax
call _ZN7QString16fromAscii_helperEPKci at PLT |.L75:
movq %rsp, %rdi | addq $1, %rdi
movq %rax, (%rsp) | cmpw $0,
(%rax,%rdi,2)
movq %rsp, %rbx | jne .L75
call _Z19setLabelQStringCRefRK7QString at PLT |.L74:
movq (%rsp), %rdi | leaq
.LC9(%rip), %rsi
movl (%rdi), %eax | call
_Z19setLabelQStringView11QStringView at PLT
testl %eax, %eax | addq $8, %rsp
je .L58 | ret
cmpl $-1, %eax |
je .L53 |
lock; subl $1, (%rdi) |
je .L62 |
.L53: |
addq $24, %rsp |
popq %rbx |
popq %rbp |
ret |
.L62: |
movq (%rsp), %rdi |
.L58: |
movl $8, %edx |
movl $2, %esi |
call _ZN10QArrayData10deallocateEPS_mm at PLT |
addq $24, %rsp |
popq %rbx |
popq %rbp |
ret |
.L60: |
movq %rax, %rbp |
movq %rbx, %rdi |
call _ZN7QStringD1Ev at PLT |
movq %rbp, %rdi |
call _Unwind_Resume at PLT |
.section .gcc_except_table |
.byte 0xff |
.byte 0xff |
.byte 0x1 |
.uleb128 .LLSDACSE7819-.LLSDACSB7819 |
.uleb128 .LEHB3-.LFB7819 |
.uleb128 .LEHE3-.LEHB3 |
.uleb128 0 |
.uleb128 0 |
.uleb128 .LEHB4-.LFB7819 |
.uleb128 .LEHE4-.LEHB4 |
.uleb128 .L60-.LFB7819 |
.uleb128 0 |
.uleb128 .LEHB5-.LFB7819 |
.uleb128 .LEHE5-.LEHB5 |
.uleb128 0 |
.uleb128 0 |
And with a bit of optimisation, we should be able to kill off the loop .L75,
which determines the length of the string literal, too, replacing it with a
compile-time constant.
Thanks,
Marc
--
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - The Qt, C++ and OpenGL Experts
More information about the Development
mailing list