<div dir="ltr">Hi Denis,<div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 22, 2016 at 11:59 AM, Denis Kudriashov <span dir="ltr"><<a href="mailto:dionisiydk@gmail.com" target="_blank">dionisiydk@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <br><div dir="ltr"><div class="gmail_extra">Hi Eliot.</div><div class="gmail_extra"><br><div class="gmail_quote">2016-11-21 18:49 GMT+01:00 Eliot Miranda <span dir="ltr"><<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">You can measure the cost of a normal MNU in the stack vm which doesn't have PUCs and so can't optimise MNU</blockquote></div><br>Thank's for details. I understand now. But can't find how PUC is decrypted. Could you describe?</div></div></blockquote><div><br></div><div>A PIC is just a table of up to 6 register load, class (index) comparison pairs.  The entry code gets the class of the receiver into a temp reg and then jumps to the sequence of load, class (index) comparisons.  Whenever there's a match the comparison jumps to the entry point of the method.  For an MNU case, instead of jumping to a method entry point, it jumps to an abort call at the start of the PIC, before the PIC's entry code.  The abort call creates the method and tests the value loaded into the register.  If the value loaded is that of a method it jumps to the entry point of that method.  The method loaded is the MNU method for the class.</div><div><br></div><div>Here are the gory details for Spur on the x86_64:</div><div><br></div><div>Constants beginning with $0xbada55 are the MNU method loads into %r9.</div><div>Constants beginning with $0xbabe1f16 are the class indexes</div><div><br></div><div><div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>nArgs: ??<span class="gmail-Apple-tab-span" style="white-space:pre">     </span>type: 4</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>blksiz: 16rD0</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>selctr: ??</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>cPICNumCases: ??<span class="gmail-Apple-tab-span" style="white-space:pre">      </span>cpicHasMNUCase: ??</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>28 xorq %rcx, %rcx : 48 31 C9 </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>2B call .-0xFF0 (0xa50=cePICAbort0Args)</div><div>entry:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>30 movq %rdx, %rax<span style="white-space:pre">           # the receiver is passed in %rdx; this sequence loads either the tags (for an immediate) or the class index (for a non-immediate) into %rax</span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>33 andq $0x7, %rax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>37 jnz .+0x9 (.+0042)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>39 movq (%rdx), %rax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>3C andq $0x3fffff, %rax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>42 cmpq %rcx, %rax<span class="gmail-Apple-tab-span" style="white-space:pre">            # the value for the first entry is the class (index) at the send site, which is stored in %rcx</span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>45 jnz .+0x68 (.+00AF)<span style="white-space:pre">               # this comparison jumps to case 4 if it misses.  It is adjusted to jump to case 3 on extension, case 2 on the next extension, etc</span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>47 movq $0x0, %r9</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>51 nop (*)</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>52 jmp .+0xF2A1 (0x10d08)<span style="white-space:pre">    # this is the jump to the target for the first case</span></div><div>ClosedPICCase0:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>57 movq $0xbada551, %r9<span style="white-space:pre">      # this is a load of an MNU method if there is an MNU case</span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>61 nop</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>62 cmpl $0xbabe1f16, %eax<span style="white-space:pre">    # since class indices are 22 bits we use a 32-bit comparison to save space</span></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>67 jz .+0xF29B (0x10d18)</div><div>ClosedPICCase1:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>6D movq $0xbada552, %r9</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>77 nop</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>78 cmpl $0xbabe1f17, %eax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>7D jz .+0xF295 (0x10d28)</div><div>ClosedPICCase2:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>83 movq $0xbada553, %r9</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>8D nop</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>8E cmpl $0xbabe1f18, %eax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>93 jz .+0xF28F (0x10d38)</div><div>ClosedPICCase3:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>99 movq $0xbada554, %r9</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>A3 nop</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>A4 cmpl $0xbabe1f19, %eax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>A9 jz .+0xF289 (0x10d48)</div><div>ClosedPICCase4:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>AF movq $0xbada555, %r9</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>B9 nop  : 90 </div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>BA cmpl $0xbabe1f1a, %eax</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">      </span>BF jz .+0xF283 (0x10d58)</div><div>ClosedPICCase5:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>C5 leaq 0xffffffffffffff34(%rip), %rcx<span style="white-space:pre">               # this loads the address of the PIC into %rcx so that </span>cePICMiss??Args can find the PIC and either extend it or relink the send site to an open PIC when the PIC is full</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>CC jmp .-0xDD1 (0xd10=cePICMiss??Args)</div></div></div><div><br></div><div>(*) The nops are details of the x86_64 code generator, allowing the system to distinguish move constant from push constant, needed when scanning machine code looking for object references to update, e.g. on garbage collection.</div><div><br></div></div><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>