+ Initialize/finalize variants using dedicated helpers, produces both smaller (no RTTI loading necessary) and faster (direct path taken) code.

git-svn-id: trunk@19442 -
This commit is contained in:
sergei 2011-10-09 20:34:58 +00:00
parent 04b5c342d2
commit 6e23565edf
4 changed files with 43 additions and 6 deletions

View File

@ -3627,18 +3627,27 @@ implementation
begin
cgpara1.init;
cgpara2.init;
paramanager.getintparaloc(pocall_default,1,cgpara1);
paramanager.getintparaloc(pocall_default,2,cgpara2);
if is_ansistring(t) or
is_widestring(t) or
is_unicodestring(t) or
is_interfacecom_or_dispinterface(t) or
is_dynamic_array(t) then
a_load_const_ref(list,OS_ADDR,0,ref)
else if t.typ=variantdef then
begin
paramanager.getintparaloc(pocall_default,1,cgpara1);
a_loadaddr_ref_cgpara(list,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
allocallcpuregisters(list);
a_call_name(list,'FPC_VARIANT_INIT',false);
deallocallcpuregisters(list);
end
else
begin
if is_open_array(t) then
InternalError(201103052);
paramanager.getintparaloc(pocall_default,1,cgpara1);
paramanager.getintparaloc(pocall_default,2,cgpara2);
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
a_loadaddr_ref_cgpara(list,href,cgpara2);
a_loadaddr_ref_cgpara(list,ref,cgpara1);
@ -3660,8 +3669,6 @@ implementation
begin
cgpara1.init;
cgpara2.init;
paramanager.getintparaloc(pocall_default,1,cgpara1);
paramanager.getintparaloc(pocall_default,2,cgpara2);
if is_ansistring(t) or
is_widestring(t) or
is_unicodestring(t) or
@ -3670,10 +3677,21 @@ implementation
g_decrrefcount(list,t,ref);
a_load_const_ref(list,OS_ADDR,0,ref);
end
else if t.typ=variantdef then
begin
paramanager.getintparaloc(pocall_default,1,cgpara1);
a_loadaddr_ref_cgpara(list,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
allocallcpuregisters(list);
a_call_name(list,'FPC_VARIANT_CLEAR',false);
deallocallcpuregisters(list);
end
else
begin
if is_open_array(t) then
InternalError(201103051);
paramanager.getintparaloc(pocall_default,1,cgpara1);
paramanager.getintparaloc(pocall_default,2,cgpara2);
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
a_loadaddr_ref_cgpara(list,href,cgpara2);
a_loadaddr_ref_cgpara(list,ref,cgpara1);

View File

@ -602,6 +602,13 @@ implementation
cnilnode.create
);
end
else if (p.resultdef.typ=variantdef) then
begin
result:=ccallnode.createintern('fpc_variant_init',
ccallparanode.create(
ctypeconvnode.create_internal(p,search_system_type('TVARDATA').typedef),
nil));
end
else
begin
result:=ccallnode.createintern('fpc_initialize',
@ -670,6 +677,13 @@ implementation
cnilnode.create
));
end
else if p.resultdef.typ=variantdef then
begin
result:=ccallnode.createintern('fpc_variant_clear',
ccallparanode.create(
ctypeconvnode.create_internal(p,search_system_type('TVARDATA').typedef),
nil));
end
else
result:=ccallnode.createintern('fpc_finalize',
ccallparanode.create(

View File

@ -546,6 +546,8 @@ function fpc_SetupReadStr_Widestr(const s: widestring): PText; compilerproc;
{$endif FPC_HAS_FEATURE_TEXTIO}
{$ifdef FPC_HAS_FEATURE_VARIANTS}
procedure fpc_variant_init(var v: tvardata);compilerproc;
procedure fpc_variant_clear(var v: tvardata);compilerproc;
procedure fpc_variant_copy(d,s : pointer);compilerproc;
procedure fpc_variant_copy_overwrite(source, dest : pointer);compilerproc;
procedure fpc_write_text_variant(Len : Longint;var f : Text;const v : variant); compilerproc;

View File

@ -21,7 +21,7 @@ var
Compiler helper routines.
---------------------------------------------------------------------}
procedure variant_init(var v : tvardata);[Public,Alias:'FPC_VARIANT_INIT'];
procedure fpc_variant_init(var v : tvardata);[Public,Alias:'FPC_VARIANT_INIT'];compilerproc;
begin
{ calling the variant manager here is a problem because the static/global variants
are initialized while the variant manager isn't assigned }
@ -29,12 +29,15 @@ procedure variant_init(var v : tvardata);[Public,Alias:'FPC_VARIANT_INIT'];
end;
procedure variant_clear(var v : tvardata);[Public,Alias:'FPC_VARIANT_CLEAR'];
procedure fpc_variant_clear(var v : tvardata);[Public,Alias:'FPC_VARIANT_CLEAR'];compilerproc;
begin
if assigned(VarClearProc) then
VarClearProc(v);
end;
{ declare aliases for local use }
procedure variant_init(var v: tvardata); external name 'FPC_VARIANT_INIT';
procedure variant_clear(var v: tvardata); external name 'FPC_VARIANT_CLEAR';
procedure variant_addref(var v : tvardata);[Public,Alias:'FPC_VARIANT_ADDREF'];
begin