[Vm-dev] [VM-dev] Does doesNotUnderstand:/cannotInterprer: jitted?

Eliot Miranda eliot.miranda at gmail.com
Tue Nov 22 23:47:59 UTC 2016

Hi Denis,

On Tue, Nov 22, 2016 at 11:59 AM, Denis Kudriashov <dionisiydk at gmail.com>

> Hi Eliot.
> 2016-11-21 18:49 GMT+01:00 Eliot Miranda <eliot.miranda at gmail.com>:
>> You can measure the cost of a normal MNU in the stack vm which doesn't
>> have PUCs and so can't optimise MNU
> Thank's for details. I understand now. But can't find how PUC is
> decrypted. Could you describe?

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.

Here are the gory details for Spur on the x86_64:

Constants beginning with $0xbada55 are the MNU method loads into %r9.
Constants beginning with $0xbabe1f16 are the class indexes

nArgs: ?? type: 4
blksiz: 16rD0
selctr: ??
cPICNumCases: ?? cpicHasMNUCase: ??
28 xorq %rcx, %rcx : 48 31 C9
2B call .-0xFF0 (0xa50=cePICAbort0Args)
30 movq %rdx, %rax # 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
33 andq $0x7, %rax
37 jnz .+0x9 (.+0042)
39 movq (%rdx), %rax
3C andq $0x3fffff, %rax
42 cmpq %rcx, %rax # the value for the first entry is the class (index) at
the send site, which is stored in %rcx
45 jnz .+0x68 (.+00AF) # 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,
47 movq $0x0, %r9
51 nop (*)
52 jmp .+0xF2A1 (0x10d08) # this is the jump to the target for the first
57 movq $0xbada551, %r9 # this is a load of an MNU method if there is an
MNU case
61 nop
62 cmpl $0xbabe1f16, %eax # since class indices are 22 bits we use a 32-bit
comparison to save space
67 jz .+0xF29B (0x10d18)
6D movq $0xbada552, %r9
77 nop
78 cmpl $0xbabe1f17, %eax
7D jz .+0xF295 (0x10d28)
83 movq $0xbada553, %r9
8D nop
8E cmpl $0xbabe1f18, %eax
93 jz .+0xF28F (0x10d38)
99 movq $0xbada554, %r9
A3 nop
A4 cmpl $0xbabe1f19, %eax
A9 jz .+0xF289 (0x10d48)
AF movq $0xbada555, %r9
B9 nop  : 90
BA cmpl $0xbabe1f1a, %eax
BF jz .+0xF283 (0x10d58)
C5 leaq 0xffffffffffffff34(%rip), %rcx # this loads the address of the PIC
into %rcx so that cePICMiss??Args can find the PIC and either extend it or
relink the send site to an open PIC when the PIC is full
CC jmp .-0xDD1 (0xd10=cePICMiss??Args)

(*) 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

best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20161122/62aa8bd3/attachment.html>

More information about the Vm-dev mailing list