[Vm-dev] Revising the map data for exotic sends

Eliot Miranda eliot.miranda at gmail.com
Fri Apr 3 18:18:52 UTC 2015


Hi Ryan, Hi Tim, Hi Clément, and anyone else interested in Cogit arcana,

   Sista needs a directed super send bytecode.  A normal super bytecode
takes the class above which to start the lookup implicitly from the method
class (the last literal in a method).  A directed super send takes
the class above which to start the lookup as an explicit parameter.  In
Ssta's case we're pushing the class association on the stack immediately
before the super send bytecode, and marking the super send bytecode as
directed using a flag bit in one of the extensions.

Compiling a directed super is trivial; simply make the literal variable
that was notionally pushed on the stack an argument of a new
ceSendDirectedSuper trampoline.  But this implies that when a linked
directed super send bytecode is unlinked (e.g. method redefinition or
method zone compaction) we can map back to this ceSendDirectedSuper
tramp[oline.

Up until now, the different send trampolines have been identified by
looking at the alignment of the linked call instruction; every different
kind of send needs a different entry point in the target method at a
different alignment.  This worked well when there were only self and super
sends.  It also meant that there was only a single method map type for
sends, which kept the method metadata small.  Now Newspeak has two more
send types; Sista will use three.  On x86 each alignment can be generated
by adding a 1 byte nop in the right place.  Methods themselves are aligned
on 8-byte boundaries, so the scheme would extend to 8 different send types
at a pinch on x86.  Of course on ARM this doesn't work well at all;
instructions are 4 bytes, and so 8 byte alignment gives only two different
alignments, and we were planning to extend the method alignment to e.g. 16
bytes.

But all this puts extra code in the entry sequence albeit only in the form
of nops.  But unlinking is extremely rare so we're letting the tail wag the
dog.  Instead, I'm going to revise the method metadata scheme so there's a
modifier byte we can use to further distinguish send types.  We can still
distinguish checked sends from unchecked sends based on alignment.  But we
can distinguish between the different checked sends and the different
unchecked send types by using one map code to code for a prefix.

A map byte has a 5 bit displacement (the distance in machine code units to
the next map byte's target), and a 3 bit code in the most significant
bits.  Here's the existing assignments:

IsSendCall := 7.
IsRelativeCall := 6.
HasBytecodePC := 5.
IsAbsPCReference := 4.
IsObjectReference := 3.
IsNSSendCall := NewspeakVM ifTrue: [2].
IsDisplacementX2N := 1.
IsDisplacement := 0.
AnnotationShift := 5.

So if we nuke IsNSSendCall we can do e.g.
AnnotationExtension := 2
interpret the displacement of an AnnotationExtension as 0, and use the
5-bit field to extend the type of the subsequent map byte. We then use two
map bytes for exotic sends, suddenly making lots of send types possible
without contortions.
--
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150403/db568ef6/attachment-0001.htm


More information about the Vm-dev mailing list