RESOLVED FIXED 160282
StringView should have an explicit m_is8Bit field.
https://bugs.webkit.org/show_bug.cgi?id=160282
Summary StringView should have an explicit m_is8Bit field.
Mark Lam
Reported 2016-07-27 20:22:54 PDT
The current implementation reserves 1 bit in the m_length field as a is16Bit flag. As a result, a StringView is incapable of handling strings that have a length of a 32-bit in size. This results in a mismatch with the expectations of String, StringImpl, and JavaScriptCore's JSString.
Attachments
proposed patch. (10.08 KB, patch)
2016-07-27 20:44 PDT, Mark Lam
no flags
proposed patch: added rdar links to ChangeLogs. (10.15 KB, patch)
2016-07-27 21:06 PDT, Mark Lam
benjamin: review+
x86_64 benchmark results. (77.62 KB, text/plain)
2016-07-28 12:54 PDT, Mark Lam
no flags
x86 benchmark results. (77.72 KB, text/plain)
2016-07-28 12:55 PDT, Mark Lam
no flags
Mark Lam
Comment 1 2016-07-27 20:23:48 PDT
Mark Lam
Comment 2 2016-07-27 20:44:46 PDT
Created attachment 284754 [details] proposed patch.
Mark Lam
Comment 3 2016-07-27 21:06:14 PDT
Created attachment 284756 [details] proposed patch: added rdar links to ChangeLogs.
Benjamin Poulain
Comment 4 2016-07-27 21:13:41 PDT
Comment on attachment 284756 [details] proposed patch: added rdar links to ChangeLogs. Thanks for fixing this.
Geoffrey Garen
Comment 5 2016-07-28 10:42:22 PDT
Mark pointed out that, if we needed to save space, we could store the flag in the low bit of the characters pointer without losing information -- but StringView seems to be a temporary object whose size doesn't matter.
Anders Carlsson
Comment 6 2016-07-28 10:43:54 PDT
(In reply to comment #5) > Mark pointed out that, if we needed to save space, we could store the flag > in the low bit of the characters pointer without losing information -- but > StringView seems to be a temporary object whose size doesn't matter. This won't work, the pointer is byte aligned. The reason we store it in the upper bit is to make it possible to put the length + pointer in two registers.
Geoffrey Garen
Comment 7 2016-07-28 10:45:24 PDT
Anders explained on IRC that we originally used bit packing so we could pass StringView by value in two registers.
Saam Barati
Comment 8 2016-07-28 11:53:36 PDT
(In reply to comment #7) > Anders explained on IRC that we originally used bit packing so we could pass > StringView by value in two registers. Won't that still happen on 64-bit?
Geoffrey Garen
Comment 9 2016-07-28 12:05:05 PDT
> > Anders explained on IRC that we originally used bit packing so we could pass > > StringView by value in two registers. > > Won't that still happen on 64-bit? Yes.
Anders Carlsson
Comment 10 2016-07-28 12:14:24 PDT
(In reply to comment #9) > > > Anders explained on IRC that we originally used bit packing so we could pass > > > StringView by value in two registers. > > > > Won't that still happen on 64-bit? > > Yes. Did you verify this?
Geoffrey Garen
Comment 11 2016-07-28 12:25:38 PDT
> Did you verify this? http://agner.org/optimize/calling_conventions.pdf, page 20: "Entire object is transferred in integer registers and/or XMM registers if the size is no bigger than 128 bits... Examples: int and float: RDI." ~/scratch> cat scratch.cc struct Object { unsigned x; bool y; }; __attribute__((noinline)) void f(Object) { } int main() { Object o; f(o); } ~/scratch> clang++ -o scratch scratch.cc && otool -tvV scratch scratch: (__TEXT,__text) section __Z1f6Object: 0000000100000f60 pushq %rbp 0000000100000f61 movq %rsp, %rbp 0000000100000f64 movq %rdi, -0x8(%rbp) 0000000100000f68 popq %rbp 0000000100000f69 retq 0000000100000f6a nopw (%rax,%rax) _main: 0000000100000f70 pushq %rbp 0000000100000f71 movq %rsp, %rbp 0000000100000f74 subq $0x10, %rsp 0000000100000f78 movq -0x8(%rbp), %rax 0000000100000f7c movq %rax, -0x10(%rbp) 0000000100000f80 movq -0x10(%rbp), %rdi ## Hi Anders! 0000000100000f84 callq __Z1f6Object ## f(Object) 0000000100000f89 xorl %eax, %eax 0000000100000f8b addq $0x10, %rsp 0000000100000f8f popq %rbp 0000000100000f90 retq
Mark Lam
Comment 12 2016-07-28 12:54:59 PDT
Created attachment 284806 [details] x86_64 benchmark results.
Mark Lam
Comment 13 2016-07-28 12:55:29 PDT
Created attachment 284807 [details] x86 benchmark results.
Mark Lam
Comment 14 2016-07-28 12:56:03 PDT
Benchmark results show that perf is neutral in aggregate with this patch.
Geoffrey Garen
Comment 15 2016-07-28 13:25:09 PDT
Actually, StringView never passed in registers because it has non-trivial copy and move constructors -- and it still doesn't pass in registers :(.
Mark Lam
Comment 16 2016-07-28 13:30:32 PDT
Darin Adler
Comment 17 2016-07-28 14:56:23 PDT
(In reply to comment #15) > Actually, StringView never passed in registers because it has non-trivial > copy and move constructors -- and it still doesn't pass in registers :(. I think part of that statement wrong. I am almost sure that the original version did pass in registers. The work done in the copy and move constructors is only needed for debugging, so we should fix this so that in production builds it passes in registers again. I believe I caused this problem when adding the underlying string debugging mechanism. This should be easy to fix!
Mark Lam
Comment 18 2016-07-29 10:13:59 PDT
(In reply to comment #17) > (In reply to comment #15) > > Actually, StringView never passed in registers because it has non-trivial > > copy and move constructors -- and it still doesn't pass in registers :(. > > I think part of that statement wrong. > > I am almost sure that the original version did pass in registers. > > The work done in the copy and move constructors is only needed for > debugging, so we should fix this so that in production builds it passes in > registers again. I believe I caused this problem when adding the underlying > string debugging mechanism. > > This should be easy to fix! FYI, I'll address this in https://bugs.webkit.org/show_bug.cgi?id=160344.
Note You need to log in before you can comment on or make changes to this bug.