[fpc-devel] Considerations about observer [was: Free Pascal 2.6.2 rc1]
michael.vancanneyt at wisa.be
michael.vancanneyt at wisa.be
Wed Nov 28 17:07:18 CET 2012
On Wed, 28 Nov 2012, luiz americo pereira camara wrote:
> 2012/11/28 Graeme Geldenhuys <graeme at geldenhuys.co.uk>:
>> On 2012-11-27 16:19, Michael Van Canneyt wrote:
>>>
>
>> If you haven't made other changes to those LCL Mediators since the code
>> you emailed me, I could take a look at updating the code for Lazarus too.
>>
>> That's a perfect example of the FPC Observers support being fully
>> functional as-is.
>>
>
> I don't discuss being fully functional as is. But you must agree that,
> if an architeture works in a scenario does not mean it's good or at
> least could not be improved.
Correct.
But the design should also not try to cover all possible use cases at any cost.
Till now, I have not seen a common use case that will not work.
> I just proposed a change that will give more flexibility for the
> programmer when designing his application interface. As a plus with
> less typecasts, so less overhead.
If we assume for a second that the internal change to store the interface
instead of the instance is done:
There are not less typecasts executed, they are in a different place simply.
You must always type the typecast before calling AttachObserver, I do it
inside AttachObserver.
My code is therefore simpler to read, generates less code and hence is preferable.
I'm not speaking idly about less code generated. Interfaces generate
some overhead. COM interfaces generate even quite some overhead.
Compare this (not meant to be runnable):
-----------------------------------------------------------------------
{$mode objfpc}
uses classes;
Procedure DoI(I : IInterface);
begin
I._addref;
end;
Var
C : TComponent;
begin
DoI(C as IInterface);
end.
-----------------------------------------------------------------------
With this:
-----------------------------------------------------------------------
{$mode objfpc}
uses classes;
Procedure DoI(C : TComponent);
begin
(C as IInterface)._addref;
end;
Var
C : TComponent;
begin
DoI(C);
end.
-----------------------------------------------------------------------
The latter (no interface passed on) generates the following assembler
for the main program:
movq U_$P$PROGRAM_$$_C,%rdi
call P$PROGRAM_$$_DOI$TCOMPONENT
The former (pass an interface) generates for the main program the following assembler:
movq $0,-104(%rbp)
leaq -24(%rbp),%rdx
leaq -88(%rbp),%rsi
movq $1,%rdi
call FPC_PUSHEXCEPTADDR
movq %rax,%rdi
call FPC_SETJMP
movq %rax,-96(%rbp)
testl %eax,%eax
jne .Lj10
movq _$PROGRAM$_Ld1,%rdx
movq _$PROGRAM$_Ld1+8,%rcx
movq U_$P$PROGRAM_$$_C,%rsi
leaq -104(%rbp),%rdi
call fpc_class_as_intf
movq -104(%rbp),%rdi
call P$PROGRAM_$$_DOI$IUNKNOWN
.Lj10:
call FPC_POPADDRSTACK
leaq -104(%rbp),%rdi
call fpc_intf_decr_ref
movq -96(%rbp),%rax
testq %rax,%rax
je .Lj11
call FPC_RERAISE
.Lj11:
If you use corba interfaces, then the interface version of the main program is reduced to
movq $_$PROGRAM$_Ld1,%rsi
movq U_$P$PROGRAM_$$_C,%rdi
call fpc_class_as_corbaintf
movq %rax,%rdi
call P$PROGRAM_$$_DOI$MYI
This kind of code you will generate for each call to AttachObserver/DetachObserver.
So, not requiring the interface to be passed on saves code if you use corba interfaces.
Using COM classes would generate even more code for each invokation.
Just to show why I prefer to avoid COM interfaces and the whole 'as' when possible.
If it had been possible to implement the whole observer thing without using
interfaces, I would have done it, but alas...
Michael.
More information about the fpc-devel
mailing list