Browse Source

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 -

svenbarth 9 years ago
parent
commit
9857a27ad8
2 changed files with 24 additions and 5 deletions
  1. 14 3
      compiler/ncgmem.pas
  2. 10 2
      compiler/ncgvmt.pas

+ 14 - 3
compiler/ncgmem.pas

@@ -86,7 +86,7 @@ implementation
 
 
     uses
     uses
       systems,
       systems,
-      cutils,cclasses,verbose,globals,constexp,
+      cutils,cclasses,verbose,globals,constexp,fmodule,
       symconst,symbase,symdef,symsym,symcpu,symtable,defutil,paramgr,
       symconst,symbase,symdef,symsym,symcpu,symtable,defutil,paramgr,
       aasmbase,aasmtai,aasmdata,
       aasmbase,aasmtai,aasmdata,
       procinfo,pass_2,parabase,
       procinfo,pass_2,parabase,
@@ -106,7 +106,7 @@ implementation
         href    : treference;
         href    : treference;
         pool    : THashSet;
         pool    : THashSet;
         entry   : PHashSetItem;
         entry   : PHashSetItem;
-
+        indirect : boolean;
       begin
       begin
          location_reset(location,LOC_REGISTER,def_cgsize(voidpointertype));
          location_reset(location,LOC_REGISTER,def_cgsize(voidpointertype));
          if (left.nodetype=typen) then
          if (left.nodetype=typen) then
@@ -114,8 +114,19 @@ implementation
              location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
              location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
              if not is_objcclass(left.resultdef) then
              if not is_objcclass(left.resultdef) then
                begin
                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,
                  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);
                    voidpointertype.size);
                  hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,resultdef,href,location.register);
                  hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,resultdef,href,location.register);
                end
                end

+ 10 - 2
compiler/ncgvmt.pas

@@ -1032,9 +1032,7 @@ implementation
          methodnametable,intmessagetable,
          methodnametable,intmessagetable,
          strmessagetable,classnamelabel,
          strmessagetable,classnamelabel,
          fieldtablelabel : tasmlabel;
          fieldtablelabel : tasmlabel;
-{$ifdef vtentry}
          hs: string;
          hs: string;
-{$endif vtentry}
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
          dmtlabel : tasmlabel;
          dmtlabel : tasmlabel;
 {$endif WITHDMT}
 {$endif WITHDMT}
@@ -1228,6 +1226,16 @@ implementation
          current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));
          current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));
 {$endif vtentry}
 {$endif vtentry}
         symtablestack.pop(current_module.localsymtable);
         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;
       end;