Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2007-11

A bug with temp allocation?

2 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Sergei Gorelkin

Hello,

I have noticed a strange thing with FPC-generated assembler code. The Pascal code is very simple:

program test;
{$mode objfpc}{$h+}
type
   TObj = class(TObject)
   public
     destructor Destroy; override;
   end;
destructor TObj.Destroy;
begin
   writeln('TObj.Destroy');
end;
begin
end.

I compiled with 'fpc test.pp -a -AMASM -al -s -O1'.

The generated assembler code follows below. Look at the prologs/epilogs. When compiled with -O1, there are 16 bytes allocated at the stack, but location [ebp-12] is never used.
When compiled with -O2, however, allocation increases to 32 bytes, but still only three DWORDs (12 bytes) are used, remaining 20 bytes look just wasted.

Is this subject for a bug report?

Regards,
Sergei

-------------------------------------------------- // assembler code compiled with -O1
_CODE SEGMENT PARA PUBLIC USE32 'CODE'
ALIGN 16
PUBLIC P$TEST_TOBJ_$__DESTROY
P$TEST_TOBJ_$__DESTROY:
; Temps allocated between ebp-16 and ebp-8
; [25] begin
push ebp
mov ebp,esp
sub esp,16
mov dword ptr [ebp-16],ebx
; Var $vmt located at ebp-4
; Var $self located at ebp-8
mov dword ptr [ebp-8],eax
mov dword ptr [ebp-4],edx
mov eax,dword ptr [ebp-4]
test eax,eax
jng @@j48
mov eax,dword ptr [ebp-8]
mov edx,dword ptr [ebp-8]
mov edx,dword ptr [edx]
call dword ptr [edx+72]
@@j48:
; [26] writeln('TObj.Destroy');
call fpc_get_output
mov ebx,eax
push 11
push 1
mov ecx,offset _$TEST$_Ld2
mov edx,ebx
mov eax,0
call fpc_write_text_pchar_as_array
call FPC_IOCHECK
mov eax,ebx
call fpc_writeln_end
call FPC_IOCHECK
; [27] end;
mov eax,dword ptr [ebp-8]
test eax,eax
je @@j66
mov eax,dword ptr [ebp-4]
test eax,eax
je @@j66
mov eax,dword ptr [ebp-8]
mov edx,dword ptr [ebp-8]
mov edx,dword ptr [edx]
call dword ptr [edx+56]
@@j66:
mov ebx,dword ptr [ebp-16]
leave
ret
_CODE ENDS

-------------------------------------------------
// assembler code compiled with -O2
_CODE SEGMENT PARA PUBLIC USE32 'CODE'
ALIGN 16
PUBLIC P$TEST_TOBJ_$__DESTROY
P$TEST_TOBJ_$__DESTROY:
; Temps allocated between ebp-32 and ebp+0
; [25] begin
push ebp
mov ebp,esp
sub esp,32
; Var $vmt located in register ebx
; Var $self located in register edi
mov dword ptr [ebp-32],ebx
mov dword ptr [ebp-28],esi
mov dword ptr [ebp-24],edi
mov edi,eax
mov ebx,edx
test ebx,ebx
jng @@j48
mov eax,edi
mov edx,dword ptr [edi]
call dword ptr [edx+72]
@@j48:
; [26] writeln('TObj.Destroy');
call fpc_get_output
push 11
push 1
mov ecx,offset _$TEST$_Ld2
mov esi,eax
mov edx,esi
mov eax,0
call fpc_write_text_pchar_as_array
call FPC_IOCHECK
mov eax,esi
call fpc_writeln_end
call FPC_IOCHECK
; [27] end;
test edi,edi
je @@j66
test ebx,ebx
je @@j66
mov eax,edi
mov edx,dword ptr [edi]
call dword ptr [edx+56]
@@j66:
mov ebx,dword ptr [ebp-32]
mov esi,dword ptr [ebp-28]
mov edi,dword ptr [ebp-24]
leave
ret
_CODE ENDS

Reply by email

Peter Vreman
Show quoted text 31 lines
Hello, I have noticed a strange thing with FPC-generated assembler code. The Pascal code is very simple: program test; {$mode objfpc}{$h+} type TObj = class(TObject) public destructor Destroy; override; end; destructor TObj.Destroy; begin writeln('TObj.Destroy'); end; begin end. I compiled with 'fpc test.pp -a -AMASM -al -s -O1'. The generated assembler code follows below. Look at the prologs/epilogs. When compiled with -O1, there are 16 bytes allocated at the stack, but location [ebp-12] is never used. When compiled with -O2, however, allocation increases to 32 bytes, but still only three DWORDs (12 bytes) are used, remaining 20 bytes look just wasted. Is this subject for a bug report?

Fixed in r9293. There was a duplicate temp allocation.

That 16 bytes instead of 12 bytes are allocated comes from alignment.

Peter

Reply by email