Generate and use an indirect symbol for VMTs.

Note: the merged code has been adjusted to a) use the typed constant builder and b) to not use the indirect symbol when its not necessary (non-Windows or same unit)

Merged revision(s) 28340, 28350 from branches/svenbarth/packages:
Generate an indirect VMT symbol for each generated VMT.

ncgvmt.pas, TVMTWriter:
  * writevmt: write a symbol with the indirect VMT name that references the direct VMT symbol
........
Load the VMT using the indirect symbol if the target supports packages.

ncgmem.pas, tcgloadvmtaddrnode:
  * pass_generate_code: if tf_supports_packages is set in target_info.flags we load the VMT using the indirect symbol, otherwise we load it using the direct symbol

........

git-svn-id: trunk@33448 -
This commit is contained in:
svenbarth 2016-04-08 14:21:51 +00:00
parent 140f5b5f94
commit 9857a27ad8
2 changed files with 24 additions and 5 deletions

View File

@ -86,7 +86,7 @@ implementation
uses
systems,
cutils,cclasses,verbose,globals,constexp,
cutils,cclasses,verbose,globals,constexp,fmodule,
symconst,symbase,symdef,symsym,symcpu,symtable,defutil,paramgr,
aasmbase,aasmtai,aasmdata,
procinfo,pass_2,parabase,
@ -106,7 +106,7 @@ implementation
href : treference;
pool : THashSet;
entry : PHashSetItem;
indirect : boolean;
begin
location_reset(location,LOC_REGISTER,def_cgsize(voidpointertype));
if (left.nodetype=typen) then
@ -114,8 +114,19 @@ implementation
location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
if not is_objcclass(left.resultdef) then
begin
{ we are using a direct reference if any of the following is true:
- the target does not support packages
- the target does not use indirect references
- the class is located inside the same unit }
indirect:=(tf_supports_packages in target_info.flags) and
(target_info.system in systems_indirect_var_imports) and
not sym_is_owned_by(left.resultdef.typesym,current_module.globalsymtable) and
(
(current_module.globalsymtable=current_module.localsymtable) or
not sym_is_owned_by(left.resultdef.typesym,current_module.localsymtable)
);
reference_reset_symbol(href,
current_asmdata.RefAsmSymbol(tobjectdef(tclassrefdef(resultdef).pointeddef).vmt_mangledname,AT_DATA),0,
current_asmdata.RefAsmSymbol(tobjectdef(tclassrefdef(resultdef).pointeddef).vmt_mangledname,AT_DATA,indirect),0,
voidpointertype.size);
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,resultdef,href,location.register);
end

View File

@ -1032,9 +1032,7 @@ implementation
methodnametable,intmessagetable,
strmessagetable,classnamelabel,
fieldtablelabel : tasmlabel;
{$ifdef vtentry}
hs: string;
{$endif vtentry}
{$ifdef WITHDMT}
dmtlabel : tasmlabel;
{$endif WITHDMT}
@ -1228,6 +1226,16 @@ implementation
current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));
{$endif vtentry}
symtablestack.pop(current_module.localsymtable);
{ write indirect symbol }
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]);
hs:=_class.vmt_mangledname;
tcb.emit_tai(Tai_const.Createname(hs,AT_DATA,0),voidpointertype);
current_asmdata.AsmLists[al_globals].concatList(
tcb.get_final_asmlist(
current_asmdata.DefineAsmSymbol(hs,AB_INDIRECT,AT_DATA),
voidpointertype,sec_rodata,hs,const_align(sizeof(pint))));
tcb.free;
end;