[Vm-dev] Re: x64 FFI plugin

Eliot Miranda eliot.miranda at gmail.com
Wed Feb 17 03:43:44 UTC 2016

On Tue, Feb 16, 2016 at 7:41 PM, Eliot Miranda <eliot.miranda at gmail.com>

> Hi ALl,
> On Mon, Feb 15, 2016 at 8:26 PM, Eliot Miranda <eliot.miranda at gmail.com>
> wrote:
>> Hi Esteban, Hi All,
>>     I thought I'd help by doing the ThreadedFFIPlugin subclass for x64.
>>  turns out that the System V x86-64 ABI and the Win64 x86-64 ABI are
>> sufficiently different that I'm splitting it across two classes.  But in
>> doing so I've had a moment of clarity (increasingly rare these days ;-) ).
>> I've finally realised that Andreas put the type information in the right
>> place, and that there is (I think) sufficient type information for structs
>> to be parsed correctly.
>> Andreas puts the type information in the first literal of the method
>> containing the FFI call.  (There is also an eval form where the function is
>> passed in).  The point here is that the type information is associated with
>> the function, and hence with the function's signature.  This is correct.
>> In VisualWorks a big mistake was made by putting the type information in
>> the actual parameter, so if one accidentally passes a parameter of the
>> wrong type (types are only checked in debug mode) then it can be marshalled
>> incorrectly.
>> This difference is really important with the System V x86-64 AB, because
>> the ABI uses register parameters, 6 integer register args and 8
>> floating-point register args, and will pass fields of a struct in available
>> registers of either type as available.  So if one passes just the following
>> structure:
>> struct foo { long a; double b; long c; double d; long e; double f; long
>> g; double h; long i; double j; long k; double l; long m; double n; long o;
>> double p; long q; double r; long s; double t; }
>> to a function declared as (long one, double two, struct foo), a,b,c,d & e
>> get passed in integer registers (along with one), and b,d,f,h,j,l & n get
>> passed in xmm registers (along with two), while g,i,k,m,n,o,p,q,r,s & t get
>> passed on the stack (strange but true).
> Well I'm horribly embarrassed.  I didn't read the spec carefully enough.
> It turns out that registers are only used for structs of size 4 eightbytes
> (e,g. version 0.99.6, http://www.x86-64.org/documentation/abi.pdf) or 2
> eightbytes (e.g. version 0.90, as used on Mac OS X x86_64,
> http://people.freebsd.org/~obrien/amd64-elf-abi.pdf).  But looking at
> linux x86_64 code tehre is no register passing for structures at all.
> Forgive the misinformation.  And it looks like life is much easier.  Nice
> to get rid of this baggage.

And again I've got this wrong.  Linux64 uses the same convention as Mac OS
X, structures of up to two eightbytes are passed in registers.

> I had thought that this implies we need to generate machine code specific
>> to each signature to efficiently marshall calls.  But because the type
>> information is flat, easily parsed and specific to each function rather
>> than (as in VW) to a particular set of actual parameters, the interpreted
>> approach we're currently using should at least be correct.  So any
>> marshalling code generation can be left as an optimization exercise, rather
>> than an explicit requirement to achieve correctness.
>> I hope to have the ThreadedX64SysVFFIPlugin written and tested before the
>> end of the month.
>> _,,,^..^,,,_
>> best, Eliot
> _,,,^..^,,,_
> best, Eliot

best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160216/8116e218/attachment.htm

More information about the Vm-dev mailing list