From 9857a27ad8cba9f22501ac2e1daff94bb8fda977 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Fri, 8 Apr 2016 14:21:51 +0000 Subject: [PATCH] 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 - --- compiler/ncgmem.pas | 17 ++++++++++++++--- compiler/ncgvmt.pas | 12 ++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index 5f78646d14..1486988630 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -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 diff --git a/compiler/ncgvmt.pas b/compiler/ncgvmt.pas index 9dff127af3..19e5f5f058 100644 --- a/compiler/ncgvmt.pas +++ b/compiler/ncgvmt.pas @@ -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;