Sfoglia il codice sorgente

* nobj.pas, finished refactoring VMT generation code, now all child structures except RTTI are written to same data section with VMT itself and their labels are local (since child structures are accessible only through VMT, smartlinking them into different sections is useless).
* Reference GUID/string labels of implemented interfaces instead of duplicating them on every occurrence.

git-svn-id: trunk@20344 -

sergei 13 anni fa
parent
commit
429af6f40b
1 ha cambiato i file con 50 aggiunte e 77 eliminazioni
  1. 50 77
      compiler/nobj.pas

+ 50 - 77
compiler/nobj.pas

@@ -89,7 +89,7 @@ interface
         function  intf_get_vtbl_name(AImplIntf:TImplementedInterface): string;
         procedure intf_create_vtbl(rawdata: TAsmList;AImplIntf:TImplementedInterface);
         procedure intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface);
-        function  intf_write_table:TAsmLabel;
+        function  intf_write_table(list : TAsmList):TAsmLabel;
         { generates the message tables for a class }
         function  genstrmsgtab(list : TAsmList) : tasmlabel;
         function  genintmsgtab(list : TAsmList) : tasmlabel;
@@ -978,7 +978,7 @@ implementation
            writenames(list,root);
 
          { now start writing of the message string table }
-         current_asmdata.getdatalabel(result);
+         current_asmdata.getlabel(result,alt_data);
          list.concat(cai_align.create(const_align(sizeof(pint))));
          list.concat(Tai_label.Create(result));
          list.concat(cai_align.create(const_align(sizeof(longint))));
@@ -1019,7 +1019,7 @@ implementation
          _class.symtable.SymList.ForEachCall(@insertmsgint,@count);
 
          { now start writing of the message string table }
-         current_asmdata.getdatalabel(r);
+         current_asmdata.getlabel(r,alt_data);
          list.concat(cai_align.create(const_align(sizeof(pint))));
          list.concat(Tai_label.Create(r));
          genintmsgtab:=r;
@@ -1183,7 +1183,7 @@ implementation
            begin
               lists[0]:=list;
               lists[1]:=TAsmList.Create;
-              current_asmdata.getdatalabel(l);
+              current_asmdata.getlabel(l,alt_data);
               list.concat(cai_align.create(const_align(sizeof(pint))));
               list.concat(Tai_label.Create(l));
               list.concat(Tai_const.Create_32bit(count));
@@ -1227,11 +1227,10 @@ implementation
 
         if fieldcount>0 then
           begin
-            current_asmdata.getdatalabel(fieldtable);
-            current_asmdata.getdatalabel(classtable);
-            maybe_new_object_file(list);
-            new_section(list,sec_rodata,classtable.name,const_align(sizeof(pint)));
+            current_asmdata.getlabel(fieldtable,alt_data);
+            current_asmdata.getlabel(classtable,alt_data);
 
+            list.concat(cai_align.create(const_align(sizeof(pint))));
             { write fields }
             list.concat(Tai_label.Create(fieldtable));
             list.concat(Tai_const.Create_16bit(fieldcount));
@@ -1291,7 +1290,8 @@ implementation
         i  : longint;
       begin
         vtblstr:=intf_get_vtbl_name(AImplIntf);
-        section_symbol_start(rawdata,vtblstr,AT_DATA,true,sec_data,const_align(sizeof(pint)));
+        rawdata.concat(cai_align.create(const_align(sizeof(pint))));
+        rawdata.concat(tai_symbol.createname(vtblstr,AT_DATA,0));
         if assigned(AImplIntf.procdefs) then
           begin
             for i:=0 to AImplIntf.procdefs.count-1 do
@@ -1303,104 +1303,73 @@ implementation
                 rawdata.concat(Tai_const.Createname(hs,0));
               end;
            end;
-        section_symbol_end(rawdata,vtblstr);
+        rawdata.concat(tai_symbol_end.createname(vtblstr));
       end;
 
 
     procedure TVMTWriter.intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface);
       var
-        iidlabel,
-        guidlabel : tasmlabel;
-        i: longint;
         pd: tprocdef;
       begin
-        { GUID }
+        { GUID (or nil for Corba interfaces) }
         if AImplIntf.IntfDef.objecttype in [odt_interfacecom] then
-          begin
-            { label for GUID }
-            current_asmdata.getdatalabel(guidlabel);
-            rawdata.concat(cai_align.create(const_align(sizeof(pint))));
-            rawdata.concat(Tai_label.Create(guidlabel));
-            with AImplIntf.IntfDef.iidguid^ do
-              begin
-                rawdata.concat(Tai_const.Create_32bit(longint(D1)));
-                rawdata.concat(Tai_const.Create_16bit(D2));
-                rawdata.concat(Tai_const.Create_16bit(D3));
-                for i:=Low(D4) to High(D4) do
-                  rawdata.concat(Tai_const.Create_8bit(D4[i]));
-              end;
-            current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(guidlabel));
-          end
+          rawdata.concat(Tai_const.CreateName(
+            make_mangledname('IID',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^),0))
         else
-          begin
-            { nil for Corba interfaces }
-            current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil));
-          end;
+          rawdata.concat(Tai_const.Create_sym(nil));
+
         { VTable }
-        current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0));
+        rawdata.concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0));
         { IOffset field }
         case AImplIntf.VtblImplIntf.IType of
           etFieldValue, etFieldValueClass,
           etStandard:
-            current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset));
+            rawdata.concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset));
           etStaticMethodResult, etStaticMethodClass:
-            current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(
+            rawdata.concat(Tai_const.Createname(
               tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef).mangledname,
               0
             ));
           etVirtualMethodResult, etVirtualMethodClass:
             begin
               pd := tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef);
-              current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(tobjectdef(pd.struct).vmtmethodoffset(pd.extnumber)));
+              rawdata.concat(Tai_const.Create_pint(tobjectdef(pd.struct).vmtmethodoffset(pd.extnumber)));
             end;
           else
             internalerror(200802162);
         end;
 
         { IIDStr }
-        current_asmdata.getdatalabel(iidlabel);
-        rawdata.concat(cai_align.create(const_align(sizeof(pint))));
-        rawdata.concat(Tai_label.Create(iidlabel));
-        rawdata.concat(Tai_const.Create_8bit(length(AImplIntf.IntfDef.iidstr^)));
-        if AImplIntf.IntfDef.objecttype=odt_interfacecom then
-          rawdata.concat(Tai_string.Create(upper(AImplIntf.IntfDef.iidstr^)))
-        else
-          rawdata.concat(Tai_string.Create(AImplIntf.IntfDef.iidstr^));
-        current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(iidlabel));
+        rawdata.concat(Tai_const.CreateName(
+          make_mangledname('IIDSTR',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^),0));
         { IType }
-        current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(aint(AImplIntf.VtblImplIntf.IType)));
+        rawdata.concat(Tai_const.Create_pint(aint(AImplIntf.VtblImplIntf.IType)));
       end;
 
 
-    function TVMTWriter.intf_write_table:TAsmLabel;
+    function TVMTWriter.intf_write_table(list : TAsmList):TAsmLabel;
       var
-        rawdata  : TAsmList;
         i        : longint;
         ImplIntf : TImplementedInterface;
-        intftablelab : tasmlabel;
       begin
-        current_asmdata.getdatalabel(intftablelab);
-        current_asmdata.asmlists[al_globals].concat(cai_align.create(const_align(sizeof(pint))));
-        current_asmdata.asmlists[al_globals].concat(Tai_label.Create(intftablelab));
-        current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(_class.ImplementedInterfaces.count));
-        rawdata:=TAsmList.Create;
-        { Write vtbls }
+        current_asmdata.getlabel(result,alt_data);
+        list.concat(cai_align.create(const_align(sizeof(pint))));
+        list.concat(Tai_label.Create(result));
+        list.concat(Tai_const.Create_pint(_class.ImplementedInterfaces.count));
+        { Write vtbl references }
         for i:=0 to _class.ImplementedInterfaces.count-1 do
           begin
             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
-            if ImplIntf.VtblImplIntf=ImplIntf then
-              intf_create_vtbl(rawdata,ImplIntf);
+            intf_gen_intf_ref(list,ImplIntf);
           end;
-        { Write vtbl references }
+
+        { Write vtbls }
         for i:=0 to _class.ImplementedInterfaces.count-1 do
           begin
             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
-            intf_gen_intf_ref(rawdata,ImplIntf);
+            if ImplIntf.VtblImplIntf=ImplIntf then
+              intf_create_vtbl(list,ImplIntf);
           end;
-        { Write interface table }
-        current_asmdata.asmlists[al_globals].concatlist(rawdata);
-        rawdata.free;
-        result:=intftablelab;
       end;
 
 
@@ -1475,36 +1444,37 @@ implementation
          dmtlabel : tasmlabel;
 {$endif WITHDMT}
          interfacetable : tasmlabel;
+         templist : TAsmList;
       begin
 {$ifdef WITHDMT}
          dmtlabel:=gendmt;
 {$endif WITHDMT}
+         templist:=TAsmList.Create;
 
          { write tables for classes, this must be done before the actual
            class is written, because we need the labels defined }
          if is_class(_class) then
           begin
-            current_asmdata.getdatalabel(classnamelabel);
-            maybe_new_object_file(current_asmdata.asmlists[al_globals]);
-            new_section(current_asmdata.asmlists[al_globals],sec_rodata,classnamelabel.name,const_align(sizeof(pint)));
+            { write class name }
+            current_asmdata.getlabel(classnamelabel,alt_data);
+            templist.concat(cai_align.create(const_align(sizeof(pint))));
+            templist.concat(Tai_label.Create(classnamelabel));
+            hs:=_class.RttiName;
+            templist.concat(Tai_const.Create_8bit(length(hs)));
+            templist.concat(Tai_string.Create(hs));
 
             { interface table }
             if _class.ImplementedInterfaces.count>0 then
-              interfacetable:=intf_write_table;
+              interfacetable:=intf_write_table(templist);
 
-            methodnametable:=genpublishedmethodstable(current_asmdata.asmlists[al_globals]);
-            fieldtablelabel:=generate_field_table(current_asmdata.asmlists[al_rtti]);
-            { write class name }
-            current_asmdata.asmlists[al_globals].concat(Tai_label.Create(classnamelabel));
-            hs:=_class.RttiName;
-            current_asmdata.asmlists[al_globals].concat(Tai_const.Create_8bit(length(hs)));
-            current_asmdata.asmlists[al_globals].concat(Tai_string.Create(hs));
+            methodnametable:=genpublishedmethodstable(templist);
+            fieldtablelabel:=generate_field_table(templist);
 
             { generate message and dynamic tables }
             if (oo_has_msgstr in _class.objectoptions) then
-              strmessagetable:=genstrmsgtab(current_asmdata.asmlists[al_globals]);
+              strmessagetable:=genstrmsgtab(templist);
             if (oo_has_msgint in _class.objectoptions) then
-              intmessagetable:=genintmsgtab(current_asmdata.asmlists[al_globals]);
+              intmessagetable:=genintmsgtab(templist);
           end;
 
         { write debug info }
@@ -1585,6 +1555,9 @@ implementation
            hs:=hs+_class.vmt_mangledname;
          current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));
 {$endif vtentry}
+         if is_class(_class) then
+           current_asmdata.asmlists[al_globals].concatlist(templist);
+        templist.Free;
       end;