forgive me. I managed to find the energy to fix the duff's device code. I did so by a) making sayer that the image you supplied worked for the case of the 11 slot SqNumberParser that gets instantiated many times, and b) by using the following to look at all the cases:
Clément, you should be able to run the method and get an Array of classes here's the code its generating. I especially like that register allocation is working nicely with the results only being spilled once needed to do another allocation.
00001861: movl %ds:0x8001c=#freeStart, %esi allocate the object to %esi
00001867: movl $0x01001b9f, %eax
0000186c: movl %eax, %ds:(%esi) store least significant half of header
0000186e: movl $0x09000000, %eax
00001873: movl %eax, %ds:0x4(%esi) store most significant half of header
00001876: leal %ds:0x30(%esi), %eax
00001879: movl %eax, %ds:0x8001c=#freeStart update freeStart to point to the start of the next object
0000187e: movl $0x00100000=nil, %edi
00001883: subl $0x00000014, %esi offset result for entry into the last instruction of loop
00001886: subl $0x00000004, %eax
00001889: jmp .+0x00000014 (0x0000189f=instantiate@9F)
0000188b: movl %edi, %ds:(%esi)
0000188d: movl %edi, %ds:0x4(%esi)
00001890: movl %edi, %ds:0x8(%esi)
00001893: movl %edi, %ds:0xc(%esi)
00001896: movl %edi, %ds:0x10(%esi)
00001899: movl %edi, %ds:0x14(%esi)
0000189c: movl %edi, %ds:0x18(%esi)
=>00189f: movl %edi, %ds:0x1c(%esi)
000018a2: addl $0x00000020, %esi increment result for next iteration of loop
000018a5: cmpl %eax, %esi
000018a7: jb .+0xffffffe2 (0x0000188b=instantiate@8B) jump to beginning of loop if not done
000018a9: subl $0x0000002c, %esi offset updated result to point back to start of object
000018ac: movl %ds:0x8001c=#freeStart, %ebx
000018b2: movl $0x01001ba3, %eax
000018b7: movl %eax, %ds:(%ebx)
000018b9: movl $0x0a000000, %eax
000018be: movl %eax, %ds:0x4(%ebx)
000018c1: leal %ds:0x30(%ebx), %eax
000018c4: movl %eax, %ds:0x8001c=#freeStart
000018c9: movl $0x00100000=nil, %edi
000018ce: subl $0x00000010, %ebx
000018d1: jmp .+0x00000011 (0x000018e4=instantiate@E4)
000018d3: movl %edi, %ds:(%ebx)
000018d5: movl %edi, %ds:0x4(%ebx)
000018d8: movl %edi, %ds:0x8(%ebx)
000018db: movl %edi, %ds:0xc(%ebx)
000018de: movl %edi, %ds:0x10(%ebx)
000018e1: movl %edi, %ds:0x14(%ebx)
000018e4: movl %edi, %ds:0x18(%ebx)
000018e7: movl %edi, %ds:0x1c(%ebx)
000018ea: addl $0x00000020, %ebx
000018ed: cmpl %eax, %ebx
000018ef: jb .+0xffffffe2 (0x000018d3=instantiate@D3)
000018f1: subl $0x00000030, %ebx
000018f4: movl %ds:0x8001c=#freeStart, %ecx
000018fa: movl $0x01001b9e, %eax
000018ff: movl %eax, %ds:(%ecx)
00001901: movl $0x0b000000, %eax
00001906: movl %eax, %ds:0x4(%ecx)
00001909: leal %ds:0x38(%ecx), %eax
0000190c: movl %eax, %ds:0x8001c=#freeStart
00001911: movl $0x00100000=nil, %edi
00001916: subl $0x0000000c, %ecx
00001919: subl $0x00000004, %eax
0000191c: jmp .+0x0000000e (0x0000192c=instantiate@12C)
0000191e: movl %edi, %ds:(%ecx)
00001920: movl %edi, %ds:0x4(%ecx)
00001923: movl %edi, %ds:0x8(%ecx)
00001926: movl %edi, %ds:0xc(%ecx)
00001929: movl %edi, %ds:0x10(%ecx)
0000192c: movl %edi, %ds:0x14(%ecx)
0000192f: movl %edi, %ds:0x18(%ecx)
00001932: movl %edi, %ds:0x1c(%ecx)
00001935: addl $0x00000020, %ecx
00001938: cmpl %eax, %ecx
0000193a: jb .+0xffffffe2 (0x0000191e=instantiate@11E)
0000193c: subl $0x00000034, %ecx
0000193f: movl %ds:0x8001c=#freeStart, %edx
00001945: movl $0x0100179a, %eax
0000194a: movl %eax, %ds:(%edx)
0000194c: movl $0x0c000000, %eax
00001951: movl %eax, %ds:0x4(%edx)
00001954: leal %ds:0x38(%edx), %eax
00001957: movl %eax, %ds:0x8001c=#freeStart
0000195c: movl $0x00100000=nil, %edi
00001961: subl $0x00000008, %edx
00001964: jmp .+0x0000000b (0x00001971=instantiate@171)
00001966: movl %edi, %ds:(%edx)
00001968: movl %edi, %ds:0x4(%edx)
0000196b: movl %edi, %ds:0x8(%edx)
0000196e: movl %edi, %ds:0xc(%edx)
00001971: movl %edi, %ds:0x10(%edx)
00001974: movl %edi, %ds:0x14(%edx)
00001977: movl %edi, %ds:0x18(%edx)
0000197a: movl %edi, %ds:0x1c(%edx)
0000197d: addl $0x00000020, %edx
00001980: cmpl %eax, %edx
00001982: jb .+0xffffffe2 (0x00001966=instantiate@166)
00001984: subl $0x00000038, %edx
00001987: pushl %esi
00001988: movl %ds:0x8001c=#freeStart, %esi
0000198e: movl $0x0100155c, %eax
00001993: movl %eax, %ds:(%esi)
00001995: movl $0x0d000000, %eax
0000199a: movl %eax, %ds:0x4(%esi)
0000199d: leal %ds:0x40(%esi), %eax
000019a0: movl %eax, %ds:0x8001c=#freeStart
000019a5: movl $0x00100000=nil, %edi
000019aa: subl $0x00000004, %esi
000019ad: subl $0x00000004, %eax
000019b0: jmp .+0x00000008 (0x000019ba=instantiate@1BA)
000019b2: movl %edi, %ds:(%esi)
000019b4: movl %edi, %ds:0x4(%esi)
000019b7: movl %edi, %ds:0x8(%esi)
000019ba: movl %edi, %ds:0xc(%esi)
000019bd: movl %edi, %ds:0x10(%esi)
000019c0: movl %edi, %ds:0x14(%esi)
000019c3: movl %edi, %ds:0x18(%esi)
000019c6: movl %edi, %ds:0x1c(%esi)
000019c9: addl $0x00000020, %esi
000019cc: cmpl %eax, %esi
000019ce: jb .+0xffffffe2 (0x000019b2=instantiate@1B2)
000019d0: subl $0x0000003c, %esi
000019d3: pushl %ebx
000019d4: movl %ds:0x8001c=#freeStart, %ebx
000019da: movl $0x01000668, %eax
000019df: movl %eax, %ds:(%ebx)
000019e1: movl $0x0e000000, %eax
000019e6: movl %eax, %ds:0x4(%ebx)
000019e9: leal %ds:0x40(%ebx), %eax
000019ec: movl %eax, %ds:0x8001c=#freeStart
000019f1: movl $0x00100000=nil, %edi
000019f6: jmp .+0x00000005 (0x000019fd=instantiate@1FD)
000019f8: movl %edi, %ds:(%ebx)
000019fa: movl %edi, %ds:0x4(%ebx)
000019fd: movl %edi, %ds:0x8(%ebx)
00001a00: movl %edi, %ds:0xc(%ebx)
00001a03: movl %edi, %ds:0x10(%ebx)
00001a06: movl %edi, %ds:0x14(%ebx)
00001a09: movl %edi, %ds:0x18(%ebx)
00001a0c: movl %edi, %ds:0x1c(%ebx)
00001a0f: addl $0x00000020, %ebx
00001a12: cmpl %eax, %ebx
00001a14: jb .+0xffffffe2 (0x000019f8=instantiate@1F8)
00001a16: subl $0x00000040, %ebx
00001a19: pushl %ecx
00001a1a: movl %ds:0x8001c=#freeStart, %ecx
00001a20: movl $0x01001bd3, %eax
00001a25: movl %eax, %ds:(%ecx)
00001a27: movl $0x0f000000, %eax
00001a2c: movl %eax, %ds:0x4(%ecx)
00001a2f: leal %ds:0x48(%ecx), %eax
00001a32: movl %eax, %ds:0x8001c=#freeStart
00001a37: movl $0x00100000=nil, %edi
00001a3c: addl $0x00000004, %ecx
00001a3f: subl $0x00000004, %eax
00001a42: jmp .+0x00000002 (0x00001a46=instantiate@246)
00001a44: movl %edi, %ds:(%ecx)
00001a46: movl %edi, %ds:0x4(%ecx)
00001a49: movl %edi, %ds:0x8(%ecx)
00001a4c: movl %edi, %ds:0xc(%ecx)
00001a4f: movl %edi, %ds:0x10(%ecx)
00001a52: movl %edi, %ds:0x14(%ecx)
00001a55: movl %edi, %ds:0x18(%ecx)
00001a58: movl %edi, %ds:0x1c(%ecx)
00001a5b: addl $0x00000020, %ecx
00001a5e: cmpl %eax, %ecx
00001a60: jb .+0xffffffe2 (0x00001a44=instantiate@244)
00001a62: subl $0x00000044, %ecx
00001a65: pushl %edx
The final case is a 16 slot object, making 2 trips through the 8-element loop
00001a66: movl %ds:0x8001c=#freeStart, %edx
00001a6c: movl $0x01001bd0, %eax
00001a71: movl %eax, %ds:(%edx)
00001a73: movl $0x10000000, %eax
00001a78: movl %eax, %ds:0x4(%edx)
00001a7b: leal %ds:0x48(%edx), %eax
00001a7e: movl %eax, %ds:0x8001c=#freeStart
00001a83: movl $0x00100000=nil, %edi
00001a88: addl $0x00000008, %edx offset result to skip header
00001a8b: movl %edi, %ds:(%edx)
00001a8d: movl %edi, %ds:0x4(%edx)
00001a90: movl %edi, %ds:0x8(%edx)
00001a93: movl %edi, %ds:0xc(%edx)
00001a96: movl %edi, %ds:0x10(%edx)
00001a99: movl %edi, %ds:0x14(%edx)
00001a9c: movl %edi, %ds:0x18(%edx)
00001a9f: movl %edi, %ds:0x1c(%edx)
00001aa2: addl $0x00000020, %edx
00001aa5: cmpl %eax, %edx
00001aa7: jb .+0xffffffe2 (0x00001a8b=instantiate@28B)
00001aa9: subl $0x00000048, %edx offset updated result to point back to start of object
And this pushes the remaining results and cones an 8 element array with the results
00001aac: pushl %esi
00001aad: pushl %ebx
00001aae: pushl %ecx
00001aaf: pushl %edx
00001ab0: movl %ds:0x8001c=#freeStart, %edx
00001ab6: movl $0x02000033, %eax
00001abb: movl %eax, %ds:(%edx)
00001abd: movl $0x08000000, %eax
00001ac2: movl %eax, %ds:0x4(%edx)
00001ac5: leal %ds:0x28(%edx), %eax
00001ac8: movl %eax, %ds:0x8001c=#freeStart
00001acd: cmpl $0x00060000='scavengeThreshold', %eax
00001ad2: jb .+0x00000005 (0x00001ad9=instantiate@2D9)
00001ad4: call .+0xfffff1df (0x00000cb8=ceScheduleScavengeTrampoline)
IsRelativeCall:
00001ad9: popl %eax
00001ada: movl %eax, %ds:0x24(%edx)
00001add: popl %eax
00001ade: movl %eax, %ds:0x20(%edx)
00001ae1: popl %eax
00001ae2: movl %eax, %ds:0x1c(%edx)
00001ae5: popl %eax
00001ae6: movl %eax, %ds:0x18(%edx)
00001ae9: popl %eax
00001aea: movl %eax, %ds:0x14(%edx)
00001aed: popl %eax
00001aee: movl %eax, %ds:0x10(%edx)
00001af1: popl %eax
00001af2: movl %eax, %ds:0xc(%edx)
00001af5: popl %eax
00001af6: movl %eax, %ds:0x8(%edx)
00001af9: movl %ebp, %esp
00001afb: popl %ebp
00001afc: ret $0x0004