Thread overview
ABI and exception handling
Feb 28, 2006
Lionello Lunesu
Feb 28, 2006
Don Clugston
Feb 28, 2006
Lionello Lunesu
Feb 28, 2006
Sean Kelly
Feb 28, 2006
Oskar Linde
February 28, 2006
I came across an interesting article:

http://blogs.msdn.com/freik/archive/2005/03/17/398200.aspx

and I was wondering if it would be possible to use a calling convention similar to x64's "__fastcall" for D programs? Apparently there should be a speed-up, especially when using exception handling (or those new on_scope_xxx constructs).

Or is D "obliged" to use the C calling convention? I wouldn't think so, since what's the point of "extern(C)" in that case, for the decoration?

L.


February 28, 2006
Lionello Lunesu wrote:
> I came across an interesting article:
> 
> http://blogs.msdn.com/freik/archive/2005/03/17/398200.aspx
> 
> and I was wondering if it would be possible to use a calling convention similar to x64's "__fastcall" for D programs? Apparently there should be a speed-up, especially when using exception handling (or those new on_scope_xxx constructs).
> Or is D "obliged" to use the C calling convention? I wouldn't think so,
> since what's the point of "extern(C)" in that case, for the decoration?

It doesn't really work for x86, where there are fewer registers.
D uses the D calling convention. But, you still need to be able to call C functions. x86 calling conventions are intrinsically a complete mess.

The x64 __fastcall may not be fully compatible with D. Note:

"Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference. The x87 register stack is unused. It may be used, but must be considered volatile across function calls."

Sounds like yet another savage attack on 80-bit reals; it seems their ABI will not allow you to generate efficient x87 code.
I'm also a little unclear about whether the scheme is compatible with nested functions, which as I understand it, manipulate ESP but not EBP.
February 28, 2006
> The x64 __fastcall may not be fully compatible with D. Note:

Yes, probably, but they need not be.

> "Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference. The x87 register stack is unused. It may be used, but must be considered volatile across function calls."
>
> Sounds like yet another savage attack on 80-bit reals; it seems their ABI
> will not allow you to generate efficient x87 code.
> I'm also a little unclear about whether the scheme is compatible with
> nested functions, which as I understand it, manipulate ESP but not EBP.

I was not talking about adopting the x64 calling convention in D : ) but was interested in the new way of stack unwinding. I must say, it's not really clear to me (way over my head), but making the "try" fast and the "catch" slow (which seems to be O(1) now) makes a lot of sense, and I was wondering if it were _in theory_ possible to use a different unwind mechanism for D code.

I suppose we can't expect D code to handle exception thrown in a C lib, can we? : )

L.


February 28, 2006
Lionello Lunesu skrev:
> I came across an interesting article:
> 
> http://blogs.msdn.com/freik/archive/2005/03/17/398200.aspx
> 
> and I was wondering if it would be possible to use a calling convention similar to x64's "__fastcall" for D programs? Apparently there should be a speed-up, especially when using exception handling (or those new on_scope_xxx constructs).
> 
> Or is D "obliged" to use the C calling convention? I wouldn't think so, since what's the point of "extern(C)" in that case, for the decoration?

For D on x86_64 (x64) it would also be interesting to consider out and inout passed in registers instead of as pointers (in registers).

Example: The x86_64 C ABI specifies that argument 1 is passed in %rdi, argument 2 is passed in %rsi, etc... Calling void func(out int x) would just mean that %rdi got assigned in the function. No address would be sent to func.

A D function would skip passing anything at all on out parameters that would be assigned to registers.

/Oskar
February 28, 2006
Lionello Lunesu wrote:
>> The x64 __fastcall may not be fully compatible with D. Note:
> 
> Yes, probably, but they need not be.
> 
>> "Any argument that doesn’t fit in 8 bytes, or is not 1, 2, 4, or 8 bytes, must be passed by reference. The x87 register stack is unused. It may be used, but must be considered volatile across function calls."
>>
>> Sounds like yet another savage attack on 80-bit reals; it seems their ABI will not allow you to generate efficient x87 code.
>> I'm also a little unclear about whether the scheme is compatible with nested functions, which as I understand it, manipulate ESP but not EBP.
> 
> I was not talking about adopting the x64 calling convention in D : ) but was interested in the new way of stack unwinding. I must say, it's not really clear to me (way over my head), but making the "try" fast and the "catch" slow (which seems to be O(1) now) makes a lot of sense, and I was wondering if it were _in theory_ possible to use a different unwind mechanism for D code.

The spec doesn't impose any requirements on how exception handling is implemented, so I'd assume you could do it any way you want.  The most common approach in C++ is for no-cost try blocks and correspondingly higher cost throws, but this isn't the only approach.  This technical report on C++ performance goes into the costs of various exception handling approaches if anyone is interested:

http://public.research.att.com/~bs/performanceTR.pdf


Sean