March 30, 2014
Am 30.03.2014 01:57, schrieb deadalnix:
> All is in the title.
>
> This is becoming increasingly the norm in new languages. It is much
> better in term of performances (it avoid cascaded loads to call methods,
> which can be really costly on modern CPUs), make object themselves smaller.
>
> Would implementing them that way break D code ? What would be the extent
> of the breakage ?

As a nice side effect, debuggers could directly use the object pointer inside the fat interface pointer and don't have to reimplement D's casting routines.

Kind Regards
Benjamin Thaut
March 31, 2014
On 30 March 2014 11:42, Walter Bright <newshound2@digitalmars.com> wrote:

> On 3/29/2014 6:11 PM, deadalnix wrote:
>
>> I'm talking about interface here. The way they are implemented in most new
>> language is via a struct that contains:
>>   - pointer to the object
>>   - pointer to vtable
>>
>> That way to don't make object bigger when they implement an interface,
>>
>
> True, but why is this a problem?


The most annoying thing about a hidden vtable pointer is it breaks alignment. If there is any SIMD (vector, matrix, etc) or other aligned value in the class, you have to start worrying and compensating for the hidden member.

 and you don't need cascaded load to call methods.
>>
>
> True, but on the other hand, it takes up 2 registers rather than one, costing twice as much to copy around, store, pass/return to functions, etc.


2 registers are used anyway; it will just populate the second register when
it fetches the vtable pointer.
There is an additional register used when passing a class pointer to a
function, but I'd like to see statistics on function args that include a
class pointer. In my experience, functions that receive a class as an
argument are the sort of functions that rarely receive many arguments. I
notice that classes tend to EITHER receive a class pointer, or receive many
arguments to do some work (and not a class pointers). I don't imagine it
affecting the arg register availability significantly in practise. Slices
certainly have a much greater impact on arg register availability, and they
haven't shown to be a problem.


This is an interesting idea. Something I never thought of, and I think I like it!


March 31, 2014
Manu:

> The most annoying thing about a hidden vtable pointer is it breaks alignment.

D class instances have two hidden fields.

Bye,
bearophile
March 31, 2014
On 30 March 2014 13:39, Walter Bright <newshound2@digitalmars.com> wrote:

> On 3/29/2014 8:06 PM, deadalnix wrote:
>
>> On Sunday, 30 March 2014 at 01:42:24 UTC, Walter Bright wrote:
>>
>>> True, but why is this a problem?
>>>
>> Higher memory consumption, less objects fitting in cache, more scanning
>> to do
>> for the GC.
>>
>
> Debatable. All fields that are interface references would double in size.
>
>
>
>  and you don't need cascaded load to call methods.
>>>>
>>>
>>> True, but on the other hand, it takes up 2 registers rather than one,
>>> costing
>>> twice as much to copy around, store, pass/return to functions, etc.
>>>
>>
>> Two pointers structs are passed in register, which is fast. If that
>> spill, that
>> spill on stack, which is hot, and prefetcher friendly.
>>
>
> That underestimates how precious register real estate is on the x86.


This is only a concern when passing args. x86 has huge internal register
files and uses aggressive register renaming, for the last decade or so.
The only time when the number of named registers is significant these days
is the fastcall calling convention (standard on x64), since functions need
to expect it's arg in an explicitly named register.
x64 doubled the number of argument registers to help with this (still fewer
than other arch's).

 On the other hand, the double indirection is very cache unfriendly.
>>
>
> I suspect that the results of all this will be some use cases go faster, other use cases go slower, a decidedly mixed result.
>

The most interesting result of the change for me would be that it wouldn't
break alignment.
But wrt performance, in my experience, i'm frequently worried about the
indirection and potential cache miss. I can't imagine I'd often be so
concerned about using an additional arg register. And that's more easily
mitigated.


March 31, 2014
On 31 March 2014 11:39, bearophile <bearophileHUGS@lycos.com> wrote:

> Manu:
>
>
>  The most annoying thing about a hidden vtable pointer is it breaks
>> alignment.
>>
>
> D class instances have two hidden fields.
>

Oh yeah... well that loses a lot of appeal from me in that case ;)


March 31, 2014
On 3/30/2014 6:33 PM, Manu wrote:
> This is an interesting idea. Something I never thought of, and I think I like it!

Frankly, I don't know why you use classes at all. Just use structs.
March 31, 2014
On Sun, 30 Mar 2014 00:11:50 -0500, Walter Bright <newshound2@digitalmars.com> wrote:

> On 3/29/2014 8:38 PM, Daniel Murphy wrote:
>> "Walter Bright"  wrote in message news:lh83dr$6m1$1@digitalmars.com...
>>
>>> On 3/29/2014 8:26 PM, Daniel Murphy wrote:
>>> > It could, but we don't have a stable ABI
>>>
>>> ? The ABI for interfaces hasn't changed in many years. In fact I don't even
>>> remember changes in it.
>>
>> I meant stable in the sense that we _can't_ break it, not that we _haven't_
>> broken it recently.
>>
>> ie we don't guarantee binary compatibility across releases.
>
> ok.

Actually, there is one big thing that this would break; C++ interop. With the way interfaces currently work, you can define an interface with virtual methods, and you can call those methods on that interface, and, if you've properly overlayed it over a C++ class instance, you will be calling a virtual method defined on that C++ class. Fat interfaces would break this capability, and would actually break some of my existing code, due to the fact I use that exact capability. I do however mark my interfaces as extern(C++), so perhaps they would have to be an exception to the ABI if this change were made?
March 31, 2014
On 31 March 2014 12:21, Walter Bright <newshound2@digitalmars.com> wrote:

> On 3/30/2014 6:33 PM, Manu wrote:
>
>> This is an interesting idea. Something I never thought of, and I think I like it!
>>
>
> Frankly, I don't know why you use classes at all. Just use structs.
>

Reference types are very useful. Most programmers are familiar with this workflow, and it's a convenient way of modelling lots of problems.

I do find myself using a lot more struct's in D though, but that doesn't
void the traditional approach. And I also maintain that these things are
important particularly as a bridge for new D users.
I also feel quite dirty using pointers in D where there is a dedicated
reference type available. I don't want * and & to appear everywhere in my D
code.


March 31, 2014
"Orvid King"  wrote in message news:mailman.124.1396235867.25518.digitalmars-d@puremagic.com...

> Actually, there is one big thing that this would break; C++ interop. With the way interfaces currently work, you can define an interface with virtual methods, and you can call those methods on that interface, and, if you've properly overlayed it over a C++ class instance, you will be calling a virtual method defined on that C++ class. Fat interfaces would break this capability, and would actually break some of my existing code, due to the fact I use that exact capability. I do however mark my interfaces as extern(C++), so perhaps they would have to be an exception to the ABI if this change were made?

We wouldn't be changing the C++ ABI, just the D ABI.  Only D interfaces would be affected. 

March 31, 2014
On Monday, 31 March 2014 at 03:25:11 UTC, Manu wrote:
> I also feel quite dirty using pointers in D where there is a dedicated reference type available. I don't want * and & to appear everywhere in my D code.

structs can pretty easily be reference types too:

struct RefType {
   struct Impl {
        // put all the stuff in here
   }
   Impl* impl;
   alias impl this;

   // add ctors and stuff that new the impl
}