Open rakudrama opened 3 hours ago
Summary: This issue reports that the Dart VM's AOT compiler generates inefficient code for throwing ConcurrentModificationError
exceptions during list iteration. The user has experimented with different approaches to minimize code size, but the current implementation still results in large code size and unexpected inlining behavior.
I have been investigating the code size of
where
list
is the default system growable list.The loop is the same as
With recent improvements, AOT now generates relatively good code. The compiler fully inlines
ListIterator
. The local value that represents_index
is monotonic and compared against the current list length, allowing the bounds check to be removed.The part that is still lacking is the code size for throwing a
ConcurrentModificationError
if the list (length) changes during iteration. I copiedListIterator
and tried several variations onmoveNext()
that differ only at thethrow
expression:Variation 1
The default inlined loop has throw-sequence of 7 instructions and 25 bytes:
Variation 2
I tried calling a constructor (
CME.new2
) that is annotated withvm:never-inline
. The result is worse - 8 instruction / 30 bytes.The inlining boundary is unexpected - naively I would have thought that the pragma would have caused the whole constructor sequence, including the allocation, to be out-of-line.
Variation 3
Calls a static method
CME.new2
(never-inline) that calls the constructor. Using a static method as a 'constructor' gets the code size down to 4 instructions / 15 bytes.Variation 4
Call a helper function
throwCME
that throws. This by far the worst. The call itself is small (2 instructions, 8 bytes). The problem is that the rest of themoveNext
method is worse. The loop is optimized as though (1)throwCME
modifies the list and (2) then returns. The bounds check can no longer be eliminated. The block with the throwing call is in the middle if the loop instead of outside.Discussion
Variation 4 should have been the best for code size.
The compiler should treat functions that never return like it does
Throw
instructions. With sound null-safety, it is no longer possible for aNever
function to returnnull
. The call to the throw-helper should be block-scheduled outside the loop.dart2js automatically achieves something close to Version 3.
In dart2js model, each generative constructor has a generative constructor factory which contains the allocation and everything else. A
new
expression compiles to a call to the factory, which may or may not be inlined. One of the inlining heuristics dart2js uses is to only allow inlining in the expression of athrow
if the inlining is expected to reduce size (i.e. a location dependent reductive heuristic).If AOT adopted a similar generative constructor factor element in its model, a similar heuristic would work. As we can see from Variation 2, that would un unadvisable without the change in the element model.
Variation 4 has the disadvantage that the throw-helper changes the call stack.
I would like to see AOT automatically compile the original code more like a slow-path stub. This would be a combination of limited out-lining and a tail call.
It might work something like this:
During inlining we see the static call in this pattern:
A lot of information is available about the candidate. If the inlining heuristics would want to inline
constructor
, or otherwise can tell there are no errors, instead, generate a small methodconstructor_a1_a2_a3
with parametersa1
,a2
etc. Replace the three instructions withThe body of the synthesized method is constructed from the inlining candidate by inserting an allocation, and ending with a new instruction
There will be a different stub for each combination of optional arguments. In large programs most stubs will be used several times. There will need to be a way to deduplicate stubs.
Appendix
code.dart
```dart import 'dart:core'; import 'dart:core' as core; int _line = 0, _limit1 = 1, _limit2 = 10; @pragma('vm:never-inline') void print(Object? item) { _line++; if (_line >= 10) { if (_line != _limit1 * _limit2) return; if (_limit1 == 1) { _limit1 = 2; } else if (_limit1 == 2) { _limit1 = 5; } else if (_limit1 == 5) { _limit1 = 1; _limit2 *= 10; } } core.print('$_line\t$item'); } class ListIterator2Output
``` Specializing Platform getters for target OS linux. Generating AOT kernel dill. Compiling /usr/local/google/home/sra/play1/bug1a3j.dart to /usr/local/google/home/sra/Dart2/sdk/z5 using format Kind.exe: Generating AOT snapshot. /usr/local/google/home/sra/Dart2/sdk/out/ReleaseX64/dart-sdk/bin/utils/gen_snapshot [--disassemble-optimized, --code-comments, --print-flow-graph-filter=useL] Code for optimized function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList4' (RegularFunction) { ;; B0 ;; B1 ;; Enter frame ;; PrologueOffset = 0 ;; Inlined [ListIterator2.moveNext4] 0x7faa347b1390 55 push rbp 0x7faa347b1391 4889e5 movq rbp,rsp 0x7faa347b1394 4883ec20 subq rsp,0x20 ;; ParallelMove rax <- rdi, fp[-4] <- rdi ;; Inlined [ListIterator2.moveNext4] 0x7faa347b1398 4889f8 movq rax,rdi 0x7faa347b139b 48897de0 movq [rbp-0x20],rdi ;; CheckStackOverflow:8(stack=0, loop=0) ;; Inlined [ListIterator2.moveNext4] 0x7faa347b139f 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b13a3 0f868c000000 jna 0x00007faa347b1435 ;; v84 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13a9 488b480f movq rcx,[rax+0xf] ;; ParallelMove rcx <- rcx ;; v90 <- UnboxInt64([non-speculative], v84 T{_Smi}) [v84, v84] int64 ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13ad 48d1f9 sarq rcx,1 ;; ParallelMove fp[-3] <- rcx ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13b0 48894de8 movq [rbp-0x18],rcx ;; ParallelMove rbx <- C goto:30 B5 ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13b4 33db xorl rbx,rbx ;; B5 ;; Loop 0 ;; Loop Header ;; ParallelMove fp[-2] <- rbx ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13b6 48895df0 movq [rbp-0x10],rbx ;; CheckStackOverflow:34(stack=0, loop=1) ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13ba 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b13be 0f867d000000 jna 0x00007faa347b1441 ;; v79 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13c4 488b500f movq rdx,[rax+0xf] ;; ParallelMove rdx <- rdx ;; v92 <- UnboxInt64([non-speculative], v79 T{_Smi}) [v79, v79] int64 ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13c8 48d1fa sarq rdx,1 ;; ParallelMove fp[-1] <- rdx ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13cb 488955f8 movq [rbp-0x8],rdx ;; Branch if EqualityCompare(v90 T{_Smi} != v92 T{_Smi}) T{bool} goto (13, 14) ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13cf 483bca cmpq rcx,rdx 0x7faa347b13d2 0f8408000000 jz 0x00007faa347b13e0 ;; B13 ;; Loop 0 ;; ParallelMove rdi <- rax ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13d8 4889c7 movq rdi,rax ;; StaticCall:26( throwCME<0> v2) ;; Inlined [ListIterator2.moveNext4] 0x7faa347b13db e8fbffffff call 0x00007faa347b13db ;; ParallelMove goto:32 B15 ;; B14 ;; B15 ;; Loop 0 0x7faa347b13e0 488b45f8 movq rax,[rbp-0x8] 0x7faa347b13e4 488b4df0 movq rcx,[rbp-0x10] ;; Branch if RelationalOp(>=, [non-speculative], v97 T{int}, v92 T{_Smi}) T{bool} goto (4, 10) 0x7faa347b13e8 483bc8 cmpq rcx,rax 0x7faa347b13eb 0f8d3b000000 jge 0x00007faa347b142c ;; B10 ;; Loop 0 ;; ParallelMove rdx <- fp[-4] 0x7faa347b13f1 488b55e0 movq rdx,[rbp-0x20] ;; v54 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b13f5 488b420f movq rax,[rdx+0xf] ;; ParallelMove rax <- rax ;; v93 <- UnboxInt64([non-speculative], v54) [v54, v54] int64 0x7faa347b13f9 48d1f8 sarq rax,1 ;; ParallelMove rax <- rax, rbx <- rcx 0x7faa347b13fc 4889cb movq rbx,rcx ;; GenericCheckBound:10(v93 T{_Smi}, v97 T{int}) [0, v92-1] int64 0x7faa347b13ff 483bd8 cmpq rbx,rax 0x7faa347b1402 0f8345000000 jnc 0x00007faa347b144d ;; v56 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.data) T{_List} 0x7faa347b1408 488b4217 movq rax,[rdx+0x17] ;; v100 <- LoadIndexed:10([_List] v56, v97 T{int}) T{X0?} 0x7faa347b140c 488b7cc817 movq rdi,[rax+rcx*8+0x17] ;; ParallelMove rcx <- rcx ;; v32 <- BinaryInt64Op(+ [tr], v97 T{int}, v101 T{_Smi}) [1, v92] int64 0x7faa347b1411 4883c101 addq rcx,1 ;; ParallelMove rdi <- rdi, fp[-1] <- rcx 0x7faa347b1415 48894df8 movq [rbp-0x8],rcx ;; StaticCall:26( print<0> v100 T{X0?}) 0x7faa347b1419 e8fbffffff call 0x00007faa347b1419 ;; ParallelMove rbx <- fp[-1], rax <- fp[-4], rcx <- fp[-3] goto:32 B5 0x7faa347b141e 488b5df8 movq rbx,[rbp-0x8] 0x7faa347b1422 488b45e0 movq rax,[rbp-0x20] 0x7faa347b1426 488b4de8 movq rcx,[rbp-0x18] 0x7faa347b142a eb8a jmp 0x00007faa347b13b6 ;; B4 ;; ParallelMove rax <- C 0x7faa347b142c 498b4670 movq rax,[thr+0x70] null ;; DartReturn:36(v0) 0x7faa347b1430 4889ec movq rsp,rbp 0x7faa347b1433 5d pop rbp 0x7faa347b1434 c3 ret ;; CheckStackOverflowSlowPath 0x7faa347b1435 41ff9630020000 call [thr+0x230] 0x7faa347b143c e968ffffff jmp 0x00007faa347b13a9 ;; CheckStackOverflowSlowPath 0x7faa347b1441 41ff9630020000 call [thr+0x230] 0x7faa347b1448 e977ffffff jmp 0x00007faa347b13c4 ;; slow path check bound operation 0x7faa347b144d e8fbffffff call 0x00007faa347b144d } Source positions for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList4' { 7faa347b1390-7faa347b13df: Function 'useList4': static.@145Function 'moveNext4':.@85 7faa347b13e0-7faa347b141d: Function 'useList4': static.@145 7faa347b141e-7faa347b143b: Function 'useList4': static.@142 7faa347b143c-7faa347b1447: Function 'useList4': static.@145 7faa347b1448-7faa347b1451: Function 'useList4': static.@NoSource } StackMaps for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList4' { 0x7faa347b13e0: 000 0x7faa347b141e: 000 0x7faa347b143c: 000000000000001 0x7faa347b1448: 000000000000001 0x7faa347b1452: 000000000000100 } Catch entry moves for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList4' { } Entry points for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList4' { [code+0x07] 7faa347b1390 kNormal [code+0x0f] 7faa347b1390 kMonomorphic [code+0x17] 7faa347b1390 kUnchecked [code+0x1f] 7faa347b1390 kMonomorphicUnchecked } Static call target functions { 0x7faa347b13e0: file:///usr/local/google/home/sra/play1/bug1a3j.dart_CME_throwCME, (pc-relative-call) 0x7faa347b141e: file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_print, (pc-relative-call) 0x7faa347b1452: [Stub] _iso_stub_RangeErrorSharedWithoutFPURegsStub, (pc-relative-call) } Code for optimized function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList3' (RegularFunction) { ;; B0 ;; B1 ;; Enter frame ;; PrologueOffset = 0 0x7faa347b1730 55 push rbp 0x7faa347b1731 4889e5 movq rbp,rsp 0x7faa347b1734 4883ec18 subq rsp,0x18 ;; ParallelMove rax <- rdi, fp[-3] <- rdi 0x7faa347b1738 4889f8 movq rax,rdi 0x7faa347b173b 48897de8 movq [rbp-0x18],rdi ;; CheckStackOverflow:8(stack=0, loop=0) 0x7faa347b173f 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b1743 0f866c000000 jna 0x00007faa347b17b5 ;; v85 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b1749 488b480f movq rcx,[rax+0xf] ;; ParallelMove rcx <- rcx ;; v91 <- UnboxInt64([non-speculative], v85 T{_Smi}) [v85, v85] int64 0x7faa347b174d 48d1f9 sarq rcx,1 ;; ParallelMove fp[-2] <- rcx 0x7faa347b1750 48894df0 movq [rbp-0x10],rcx ;; ParallelMove rdx <- C goto:30 B5 0x7faa347b1754 33d2 xorl rdx,rdx ;; B5 ;; Loop 0 ;; Loop Header ;; CheckStackOverflow:34(stack=0, loop=1) 0x7faa347b1756 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b175a 0f865e000000 jna 0x00007faa347b17be ;; v80 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b1760 488b580f movq rbx,[rax+0xf] ;; ParallelMove rbx <- rbx ;; v93 <- UnboxInt64([non-speculative], v80 T{_Smi}) [v80, v80] int64 0x7faa347b1764 48d1fb sarq rbx,1 ;; Branch if EqualityCompare(v91 T{_Smi} != v93 T{_Smi}) T{bool} goto (13, 14) 0x7faa347b1767 483bcb cmpq rcx,rbx 0x7faa347b176a 0f8536000000 jnz 0x00007faa347b17a6 ;; B14 ;; Loop 0 ;; Branch if RelationalOp(>=, [non-speculative], v98 T{int}, v93 T{_Smi}) T{bool} goto (4, 10) 0x7faa347b1770 483bd3 cmpq rdx,rbx 0x7faa347b1773 0f8d24000000 jge 0x00007faa347b179d ;; B10 ;; Loop 0 ;; v57 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.data) T{_List} 0x7faa347b1779 488b5817 movq rbx,[rax+0x17] ;; v101 <- LoadIndexed:10([_List] v57, v98 T{int}) T{X0?} 0x7faa347b177d 488b7cd317 movq rdi,[rbx+rdx*8+0x17] ;; ParallelMove rdx <- rdx ;; v32 <- BinaryInt64Op(+ [tr], v98 T{int}, v102 T{_Smi}) [1, v93] int64 0x7faa347b1782 4883c201 addq rdx,1 ;; ParallelMove rdi <- rdi, fp[-1] <- rdx 0x7faa347b1786 488955f8 movq [rbp-0x8],rdx ;; StaticCall:26( print<0> v101 T{X0?}) 0x7faa347b178a e8fbffffff call 0x00007faa347b178a ;; ParallelMove rdx <- fp[-1], rax <- fp[-3], rcx <- fp[-2] goto:32 B5 ;; Inlined [ListIterator2.moveNext3] 0x7faa347b178f 488b55f8 movq rdx,[rbp-0x8] 0x7faa347b1793 488b45e8 movq rax,[rbp-0x18] 0x7faa347b1797 488b4df0 movq rcx,[rbp-0x10] 0x7faa347b179b ebb9 jmp 0x00007faa347b1756 ;; B4 ;; ParallelMove rax <- C ;; Inlined [ListIterator2.moveNext3] 0x7faa347b179d 498b4670 movq rax,[thr+0x70] null ;; DartReturn:36(v0) ;; Inlined [ListIterator2.moveNext3] 0x7faa347b17a1 4889ec movq rsp,rbp 0x7faa347b17a4 5d pop rbp 0x7faa347b17a5 c3 ret ;; B13 ;; ParallelMove rdi <- fp[-3] ;; Inlined [ListIterator2.moveNext3] 0x7faa347b17a6 488b7de8 movq rdi,[rbp-0x18] ;; v35 <- StaticCall:26( new3<0> v2) T{CME} ;; Inlined [ListIterator2.moveNext3] 0x7faa347b17aa e8fbffffff call 0x00007faa347b17aa ;; ParallelMove rax <- rax ;; Throw:28(v35) ;; Inlined [ListIterator2.moveNext3] 0x7faa347b17af e8fbffffff call 0x00007faa347b17af 0x7faa347b17b4 cc int3 ;; CheckStackOverflowSlowPath 0x7faa347b17b5 41ff9630020000 call [thr+0x230] 0x7faa347b17bc eb8b jmp 0x00007faa347b1749 ;; CheckStackOverflowSlowPath 0x7faa347b17be 41ff9630020000 call [thr+0x230] 0x7faa347b17c5 eb99 jmp 0x00007faa347b1760 } Source positions for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList3' { 7faa347b1730-7faa347b178e: Function 'useList3': static.@139 7faa347b178f-7faa347b17ae: Function 'useList3': static.@139Function 'moveNext3':.@70 7faa347b17af-7faa347b17b3: Function 'useList3': static.@139Function 'moveNext3':.@70 7faa347b17b4-7faa347b17bb: Function 'useList3': static.@136 7faa347b17bc-7faa347b17c4: Function 'useList3': static.@139 } StackMaps for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList3' { 0x7faa347b178f: 00 0x7faa347b17af: 000 0x7faa347b17b4: 000 0x7faa347b17bc: 00000000000001 0x7faa347b17c5: 00000000000001 } Catch entry moves for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList3' { } Entry points for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList3' { [code+0x07] 7faa347b1730 kNormal [code+0x0f] 7faa347b1730 kMonomorphic [code+0x17] 7faa347b1730 kUnchecked [code+0x1f] 7faa347b1730 kMonomorphicUnchecked } Static call target functions { 0x7faa347b178f: file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_print, (pc-relative-call) 0x7faa347b17af: file:///usr/local/google/home/sra/play1/bug1a3j.dart_CME_new3, (pc-relative-call) 0x7faa347b17b4: [Stub] _iso_stub_ThrowStub, (pc-relative-call) } Code for optimized function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList2' (RegularFunction) { ;; B0 ;; B1 ;; Enter frame ;; PrologueOffset = 0 0x7faa347b1810 55 push rbp 0x7faa347b1811 4889e5 movq rbp,rsp 0x7faa347b1814 4883ec18 subq rsp,0x18 ;; ParallelMove rsi <- rdi, fp[-3] <- rdi 0x7faa347b1818 4889fe movq rsi,rdi 0x7faa347b181b 48897de8 movq [rbp-0x18],rdi ;; CheckStackOverflow:8(stack=0, loop=0) 0x7faa347b181f 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b1823 0f867c000000 jna 0x00007faa347b18a5 ;; v85 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b1829 488b460f movq rax,[rsi+0xf] ;; ParallelMove rax <- rax ;; v91 <- UnboxInt64([non-speculative], v85 T{_Smi}) [v85, v85] int64 0x7faa347b182d 48d1f8 sarq rax,1 ;; ParallelMove fp[-2] <- rax 0x7faa347b1830 488945f0 movq [rbp-0x10],rax ;; ParallelMove rcx <- C goto:30 B5 0x7faa347b1834 33c9 xorl rcx,rcx ;; B5 ;; Loop 0 ;; Loop Header ;; CheckStackOverflow:34(stack=0, loop=1) 0x7faa347b1836 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b183a 0f8671000000 jna 0x00007faa347b18b1 ;; v80 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b1840 488b560f movq rdx,[rsi+0xf] ;; ParallelMove rdx <- rdx ;; v93 <- UnboxInt64([non-speculative], v80 T{_Smi}) [v80, v80] int64 0x7faa347b1844 48d1fa sarq rdx,1 ;; Branch if EqualityCompare(v91 T{_Smi} != v93 T{_Smi}) T{bool} goto (13, 14) 0x7faa347b1847 483bc2 cmpq rax,rdx 0x7faa347b184a 0f8536000000 jnz 0x00007faa347b1886 ;; B14 ;; Loop 0 ;; Branch if RelationalOp(>=, [non-speculative], v98 T{int}, v93 T{_Smi}) T{bool} goto (4, 10) 0x7faa347b1850 483bca cmpq rcx,rdx 0x7faa347b1853 0f8d24000000 jge 0x00007faa347b187d ;; B10 ;; Loop 0 ;; v57 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.data) T{_List} 0x7faa347b1859 488b5617 movq rdx,[rsi+0x17] ;; v101 <- LoadIndexed:10([_List] v57, v98 T{int}) T{X0?} 0x7faa347b185d 488b7cca17 movq rdi,[rdx+rcx*8+0x17] ;; ParallelMove rcx <- rcx ;; v32 <- BinaryInt64Op(+ [tr], v98 T{int}, v102 T{_Smi}) [1, v93] int64 0x7faa347b1862 4883c101 addq rcx,1 ;; ParallelMove rdi <- rdi, fp[-1] <- rcx 0x7faa347b1866 48894df8 movq [rbp-0x8],rcx ;; StaticCall:26( print<0> v101 T{X0?}) 0x7faa347b186a e8fbffffff call 0x00007faa347b186a ;; ParallelMove rcx <- fp[-1], rsi <- fp[-3], rax <- fp[-2] goto:32 B5 ;; Inlined [ListIterator2.moveNext2] 0x7faa347b186f 488b4df8 movq rcx,[rbp-0x8] 0x7faa347b1873 488b75e8 movq rsi,[rbp-0x18] 0x7faa347b1877 488b45f0 movq rax,[rbp-0x10] 0x7faa347b187b ebb9 jmp 0x00007faa347b1836 ;; B4 ;; ParallelMove rax <- C ;; Inlined [ListIterator2.moveNext2] 0x7faa347b187d 498b4670 movq rax,[thr+0x70] null ;; DartReturn:36(v0) ;; Inlined [ListIterator2.moveNext2] 0x7faa347b1881 4889ec movq rsp,rbp 0x7faa347b1884 5d pop rbp 0x7faa347b1885 c3 ret ;; B13 ;; v34 <- AllocateObject:24(cls=CME) T{CME} ;; Inlined [ListIterator2.moveNext2] 0x7faa347b1886 e8fbffffff call 0x00007faa347b1886 ;; ParallelMove rdi <- rax, rsi <- fp[-3], rax <- rax ;; Inlined [ListIterator2.moveNext2] 0x7faa347b188b 4889c7 movq rdi,rax 0x7faa347b188e 488b75e8 movq rsi,[rbp-0x18] ;; ParallelMove fp[-3] <- rax ;; Inlined [ListIterator2.moveNext2] 0x7faa347b1892 488945e8 movq [rbp-0x18],rax ;; StaticCall:28( CME.new2<0> v34, v2) ;; Inlined [ListIterator2.moveNext2] 0x7faa347b1896 e8fbffffff call 0x00007faa347b1896 ;; ParallelMove rax <- fp[-3] ;; Inlined [ListIterator2.moveNext2] 0x7faa347b189b 488b45e8 movq rax,[rbp-0x18] ;; Throw:30(v34) ;; Inlined [ListIterator2.moveNext2] 0x7faa347b189f e8fbffffff call 0x00007faa347b189f 0x7faa347b18a4 cc int3 ;; CheckStackOverflowSlowPath 0x7faa347b18a5 41ff9630020000 call [thr+0x230] 0x7faa347b18ac e978ffffff jmp 0x00007faa347b1829 ;; CheckStackOverflowSlowPath 0x7faa347b18b1 41ff9630020000 call [thr+0x230] 0x7faa347b18b8 eb86 jmp 0x00007faa347b1840 } Source positions for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList2' { 7faa347b1810-7faa347b186e: Function 'useList2': static.@133 7faa347b186f-7faa347b188a: Function 'useList2': static.@133Function 'moveNext2':.@55 7faa347b188b-7faa347b189a: Function 'useList2': static.@133Function 'moveNext2':.@55 7faa347b189b-7faa347b18a3: Function 'useList2': static.@133Function 'moveNext2':.@55 7faa347b18a4-7faa347b18ab: Function 'useList2': static.@130 7faa347b18ac-7faa347b18b7: Function 'useList2': static.@133 } StackMaps for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList2' { 0x7faa347b186f: 00 0x7faa347b188b: 00 0x7faa347b189b: 00 0x7faa347b18a4: 000 0x7faa347b18ac: 00000000010000 0x7faa347b18b8: 00000000010000 } Catch entry moves for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList2' { } Entry points for function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList2' { [code+0x07] 7faa347b1810 kNormal [code+0x0f] 7faa347b1810 kMonomorphic [code+0x17] 7faa347b1810 kUnchecked [code+0x1f] 7faa347b1810 kMonomorphicUnchecked } Static call target functions { 0x7faa347b186f: file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_print, (pc-relative-call) 0x7faa347b188b: allocation stub for Library:'file:///usr/local/google/home/sra/play1/bug1a3j.dart' Class: CME, (pc-relative-call) 0x7faa347b189b: file:///usr/local/google/home/sra/play1/bug1a3j.dart_CME_CME.new2, (pc-relative-call) 0x7faa347b18a4: [Stub] _iso_stub_ThrowStub, (pc-relative-call) } Code for optimized function 'file:///usr/local/google/home/sra/play1/bug1a3j.dart_::_useList1' (RegularFunction) { ;; B0 ;; B1 ;; Enter frame ;; PrologueOffset = 0 0x7faa347b1910 55 push rbp 0x7faa347b1911 4889e5 movq rbp,rsp 0x7faa347b1914 4883ec18 subq rsp,0x18 ;; ParallelMove rax <- rdi, fp[-3] <- rdi 0x7faa347b1918 4889f8 movq rax,rdi 0x7faa347b191b 48897de8 movq [rbp-0x18],rdi ;; CheckStackOverflow:8(stack=0, loop=0) 0x7faa347b191f 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b1923 0f8676000000 jna 0x00007faa347b199f ;; v91 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b1929 488b480f movq rcx,[rax+0xf] ;; ParallelMove rcx <- rcx ;; v101 <- UnboxInt64([non-speculative], v91 T{_Smi}) [v91, v91] int64 0x7faa347b192d 48d1f9 sarq rcx,1 ;; ParallelMove fp[-2] <- rcx 0x7faa347b1930 48894df0 movq [rbp-0x10],rcx ;; ParallelMove rdx <- C goto:30 B5 0x7faa347b1934 33d2 xorl rdx,rdx ;; B5 ;; Loop 0 ;; Loop Header ;; CheckStackOverflow:34(stack=0, loop=1) 0x7faa347b1936 493b6638 cmpq rsp,[thr+0x38] 0x7faa347b193a 0f8668000000 jna 0x00007faa347b19a8 ;; v86 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.length) [0, 576460752303423487] T{_Smi} 0x7faa347b1940 488b580f movq rbx,[rax+0xf] ;; ParallelMove rbx <- rbx ;; v103 <- UnboxInt64([non-speculative], v86 T{_Smi}) [v86, v86] int64 0x7faa347b1944 48d1fb sarq rbx,1 ;; Branch if EqualityCompare(v101 T{_Smi} != v103 T{_Smi}) T{bool} goto (13, 14) 0x7faa347b1947 483bcb cmpq rcx,rbx 0x7faa347b194a 0f8536000000 jnz 0x00007faa347b1986 ;; B14 ;; Loop 0 ;; Branch if RelationalOp(>=, [non-speculative], v108 T{int}, v103 T{_Smi}) T{bool} goto (4, 10) 0x7faa347b1950 483bd3 cmpq rdx,rbx 0x7faa347b1953 0f8d24000000 jge 0x00007faa347b197d ;; B10 ;; Loop 0 ;; v57 <- LoadField(v2 T{_GrowableList} . GrowableObjectArray.data) T{_List} 0x7faa347b1959 488b5817 movq rbx,[rax+0x17] ;; v111 <- LoadIndexed:10([_List] v57, v108 T{int}) T{X0?} 0x7faa347b195d 488b7cd317 movq rdi,[rbx+rdx*8+0x17] ;; ParallelMove rdx <- rdx ;; v32 <- BinaryInt64Op(+ [tr], v108 T{int}, v112 T{_Smi}) [1, v103] int64 0x7faa347b1962 4883c201 addq rdx,1 ;; ParallelMove rdi <- rdi, fp[-1] <- rdx 0x7faa347b1966 488955f8 movq [rbp-0x8],rdx ;; StaticCall:26( print<0> v111 T{X0?}) 0x7faa347b196a e8fbffffff call 0x00007faa347b196a ;; ParallelMove rdx <- fp[-1], rax <- fp[-3], rcx <- fp[-2] goto:32 B5 ;; Inlined [ListIterator2.moveNext] 0x7faa347b196f 488b55f8 movq rdx,[rbp-0x8] 0x7faa347b1973 488b45e8 movq rax,[rbp-0x18] 0x7faa347b1977 488b4df0 movq rcx,[rbp-0x10] 0x7faa347b197b ebb9 jmp 0x00007faa347b1936 ;; B4 ;; ParallelMove rax <- C ;; Inlined [ListIterator2.moveNext] 0x7faa347b197d 498b4670 movq rax,[thr+0x70] null ;; DartReturn:36(v0) ;; Inlined [ListIterator2.moveNext] 0x7faa347b1981 4889ec movq rsp,rbp 0x7faa347b1984 5d pop rbp 0x7faa347b1985 c3 ret ;; B13 ;; v34 <- AllocateObject:24(cls=CME,