sdk
sdk copied to clipboard
Identical on ints is worse than equals on ints
Using == on two ints I get code like this:
754839 v11 <- LoadField(v10 . kind {final}) [-9223372036854775808, 9223372036854775807] int64
0x00000000005838a3 <+19>: mov 0x17(%rax),%rcx
754840 v5 <- EqualityCompare(v11 T{_Smi} == v13 T{_Smi}) T{bool}
0x00000000005838a7 <+23>: cmp $0x61,%rcx
0x00000000005838ab <+27>: je 0x5838b6 <StringTokenImpl.isIdentifier+38>
0x00000000005838ad <+29>: mov 0x80(%r14),%rax
0x00000000005838b4 <+36>: jmp 0x5838ba <StringTokenImpl.isIdentifier+42>
0x00000000005838b6 <+38>: mov 0x78(%r14),%rax
754841 ParallelMove rax <- rax
754842 DartReturn:14(v5)
0x00000000005838ba <+42>: mov %rbp,%rsp
0x00000000005838bd <+45>: pop %rbp
0x00000000005838be <+46>: ret
(from StringTokenImpl.isIdentifier with @pragma("vm:never-inline") on it).
While I don't understand the 0x80 vs 0x78 and mov %rbp,%rsp and pop %rbp part, it loads the field, compares it to 0x61 (97 aka $a aka IDENTIFIER_TOKEN in the dart code) and returns.
Using identical instead I get this:
754852 v11 <- LoadField(v10 . kind {final}) [-9223372036854775808, 9223372036854775807] int64
0x00000000005838db <+19>: mov 0x17(%rax),%rcx
754853 v12 <- BoxInt64(v11 T{int}) [-9223372036854775808, 9223372036854775807] T{int}
0x00000000005838df <+23>: mov %rcx,%rax
0x00000000005838e2 <+26>: add %rax,%rax
0x00000000005838e5 <+29>: jno 0x5838f4 <StringTokenImpl.isIdentifier+44>
0x00000000005838eb <+35>: call 0x6de61c <stub _iso_stub_AllocateMintSharedWithoutFPURegsStub>
0x00000000005838f0 <+40>: mov %rcx,0x7(%rax)
754854 ParallelMove rax <- rax
754855 v5 <- StrictCompare:12(===, v12 T{int}, v4) T{bool}
0x00000000005838f4 <+44>: cmp $0xc2,%rax
0x00000000005838fa <+50>: je 0x583905 <StringTokenImpl.isIdentifier+61>
0x00000000005838fc <+52>: mov 0x80(%r14),%rcx
0x0000000000583903 <+59>: jmp 0x583909 <StringTokenImpl.isIdentifier+65>
0x0000000000583905 <+61>: mov 0x78(%r14),%rcx
754856 ParallelMove rax <- rcx
0x0000000000583909 <+65>: mov %rcx,%rax
754857 DartReturn:14(v5)
0x000000000058390c <+68>: mov %rbp,%rsp
0x000000000058390f <+71>: pop %rbp
0x0000000000583910 <+72>: ret
where it has added boxing into the mix, doubling the int to box it, checking (I think) if it is now so big it should do other stuff, then comparing to 0xc2 (aka 194 aka boxed 97).
Changing the scanner/parser from using identical to using == (23f0c0b27b3e797f9f7918735ad3461c34847b11) improved the runtime of the CFE compiling itself by ~0.5-0.6% --- but maybe the VM could just skip the boxing?
/cc @mraleph
Summary: The user reports that using identical on two integers is slower than using == because identical involves boxing the integers, which adds overhead. The user suggests that the VM could skip the boxing step for identical on integers to improve performance.
While I don't understand the 0x80 vs 0x78 and
mov %rbp,%rspandpop %rbppart
I find the code a bit easier to understand if I have the compiler dump the disassembly instead of various tools.
dart compile exe \
--extra-gen-snapshot-options --disassemble-optimized \
--extra-gen-snapshot-options --code-comments \
-v foo.dart --output=z.exe 1>z.exe.log 2>&1
This includes inlining information and some of the magic values, so instead of
0x00000000005838b6 <+38>: mov 0x78(%r14),%rax
you get something like
;; Inlined [_Timer@[email protected]]
0x7ffa5892b93a 498b5678 movq rdx,[thr+0x78] true
which tells you the value is true.