Jamie McCracken wrote:

Marco van de Voort wrote:


The best solution I can think for this is to reference count non-component classes. This should be safe for TObjects but obviously not for Tcomponent descendants (cf circular reference problem) so a protected variable could be added to TObject to specify whether to ref count it or not (with TComponent turning it off).



This is impossible. 90% of the language wouldn't work anymore as it does now, and besides, it would be dog slow. Could be that it gets slower than Boehm GC even.



Thats very pessimistic!

Why wouldn't existing code work with this? If you call free on an object it would ignore the ref count and free it - so it wont alter how existing code works so it certainly should not break anything. You can always create a new dialect that has this if you're worried about existing code (I take it most of the existing code is using FPC mode dialect).

Is'nt the overhead for reference counting negligible compared to having try..finally blocks which the programmer would have to add anyway if we didn't refcount them?

(there also pointers for cases where you dont need try..finally)


Ref. counting creates an huge amount of implicit try .. finally blocks which have a heavy impact on speed.

Consider

function f1(myobject : tobject) : tobject;
  begin
  end;

function f2(myobject : iunknown) : iunknown;
  begin
  end;

var
  o : tobject;
  i : iunknown;

begin
  f1(o);
  f2(i);
end.

lets have a look at the ouput (IUnknown is ref. counted):

# [2] begin
.globl  P$PROGRAM_F1$TOBJECT$$TOBJECT
P$PROGRAM_F1$TOBJECT$$TOBJECT:
# Temps allocated between ebp+0 and ebp+0
        pushl   %ebp
        movl    %esp,%ebp
# Var myobject located in register
# Var $result located in register
        movl    %eax,%edx
# [3] result:=myobject;
        movl    %edx,%ecx
# [4] end;
        movl    %ecx,%eax
        leave
        ret

.section .text
        .balign 4
        .balign 4
# [7] begin
.globl  P$PROGRAM_F2$IUNKNOWN$$IUNKNOWN
P$PROGRAM_F2$IUNKNOWN$$IUNKNOWN:
# Temps allocated between ebp-48 and ebp-4
        pushl   %ebp
        movl    %esp,%ebp
        subl    $48,%esp
        movl    %ebx,-48(%ebp)
# Var myobject located in register
# Var $result located at ebp-4
        movl    %eax,%ebx
        movl    $0,-4(%ebp)
        leal    -16(%ebp),%eax
        movl    %eax,%ecx
        leal    -40(%ebp),%eax
        movl    %eax,%edx
        movl    $1,%eax
        call    FPC_PUSHEXCEPTADDR
        call    FPC_SETJMP
        pushl   %eax
        testl   %eax,%eax
        jne     .L15
# [8] result:=myobject;
        movl    %ebx,%edx
        leal    -4(%ebp),%eax
        call    fpc_intf_assign
.L15:
        call    FPC_POPADDRSTACK
        popl    %eax
        testl   %eax,%eax
        je      .L16
# [9] end;
        movl    $INIT__SYSTEM_IUNKNOWN,%edx
        leal    -4(%ebp),%eax
        call    fpc_finalize
        call    FPC_RERAISE
.L16:
        movl    -4(%ebp),%eax
        movl    -48(%ebp),%ebx
        leave
        ret

[...]

# [16] f1(o);
        movl    %esi,%eax
        call    P$PROGRAM_F1$TOBJECT$$TOBJECT
# [17] f2(i);
        leal    -44(%ebp),%edx
        movl    %edx,%eax
        call    FPC_INTF_DECR_REF
        movl    %ebx,%eax
        call    P$PROGRAM_F2$IUNKNOWN$$IUNKNOWN
        movl    %eax,-44(%ebp)
        leal    -44(%ebp),%edx
        movl    %edx,%eax
        call    FPC_INTF_DECR_REF
        movl    $0,-44(%ebp)



So if you look at this, you know why classes aren't ref. counted. And there is no chance to avoid the code generated for the interface.


_______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to