2
0
Эх сурвалжийг харах

* changed emit_ansistring_const() and emit_unicodestring_const() into
instance methods that make use of the internal data builder
functionality so they automatically place all string data in the
same section if possible

git-svn-id: branches/hlcgllvm@30342 -

Jonas Maebe 10 жил өмнө
parent
commit
419a97cce8

+ 21 - 22
compiler/aasmcnst.pas

@@ -260,7 +260,7 @@ type
      procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
      procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
 
 
     protected
     protected
-     function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; out startlab: tasmlabel):tasmlabofs;
+     function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel):tasmlabofs;
      procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      { when building an anonymous record, we cannot immediately insert the
      { when building an anonymous record, we cannot immediately insert the
@@ -274,8 +274,8 @@ type
      { class functions and an extra list parameter, because emitting the data
      { class functions and an extra list parameter, because emitting the data
        for the strings has to happen via a separate typed const builder (which
        for the strings has to happen via a separate typed const builder (which
        will be created/destroyed internally by these methods) }
        will be created/destroyed internally by these methods) }
-     class function emit_ansistring_const(list: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding; newsection: boolean): tasmlabofs;
-     class function emit_unicodestring_const(list: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):tasmlabofs;
+     function emit_ansistring_const(datalist: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding): tasmlabofs;
+     function emit_unicodestring_const(datalist: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):tasmlabofs;
      { emits a tasmlabofs as returned by emit_*string_const }
      { emits a tasmlabofs as returned by emit_*string_const }
      procedure emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);virtual;
      procedure emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);virtual;
 
 
@@ -972,14 +972,13 @@ implementation
      end;
      end;
 
 
 
 
-   function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; out startlab: tasmlabel): tasmlabofs;
+   function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel): tasmlabofs;
      var
      var
        string_symofs: asizeint;
        string_symofs: asizeint;
        charptrdef: tdef;
        charptrdef: tdef;
        elesize: word;
        elesize: word;
      begin
      begin
-       current_asmdata.getglobaldatalabel(result.lab);
-       startlab:=result.lab;
+       result.lab:=startlab;
        result.ofs:=0;
        result.ofs:=0;
        { pack the data, so that we don't add unnecessary null bytes after the
        { pack the data, so that we don't add unnecessary null bytes after the
          constant string }
          constant string }
@@ -1019,7 +1018,11 @@ implementation
            { results in slightly more efficient code }
            { results in slightly more efficient code }
            emit_tai(tai_label.create(result.lab),charptrdef);
            emit_tai(tai_label.create(result.lab),charptrdef);
            result.ofs:=0;
            result.ofs:=0;
-           current_asmdata.getglobaldatalabel(startlab);
+           { create new label of the same kind (including whether or not the
+             name starts with target_asm.labelprefix in case it's AB_LOCAL,
+             so we keep the difference depending on whether the original was
+             allocated via getstatic/getlocal/getglobal datalabel) }
+           startlab:=tasmlabel.create(current_asmdata.AsmSymbolDict,startlab.name+'$strlab',startlab.bind,startlab.typ);
          end;
          end;
        { sanity check }
        { sanity check }
        if result.ofs<>string_symofs then
        if result.ofs<>string_symofs then
@@ -1110,19 +1113,15 @@ implementation
      end;
      end;
 
 
 
 
-   class function ttai_typedconstbuilder.emit_ansistring_const(list: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding; newsection: boolean): tasmlabofs;
+   function ttai_typedconstbuilder.emit_ansistring_const(datalist: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding): tasmlabofs;
      var
      var
        s: PChar;
        s: PChar;
        startlab: tasmlabel;
        startlab: tasmlabel;
        ansistrrecdef: trecorddef;
        ansistrrecdef: trecorddef;
        datadef: tdef;
        datadef: tdef;
        datatcb: ttai_typedconstbuilder;
        datatcb: ttai_typedconstbuilder;
-       options: ttcasmlistoptions;
      begin
      begin
-       options:=[tcalo_is_lab];
-       if NewSection then
-         include(options,tcalo_make_dead_strippable);
-       datatcb:=self.create(options);
+       start_internal_data_builder(datalist,sec_rodata_norel,'',datatcb,startlab);
        result:=datatcb.emit_string_const_common(st_ansistring,len,encoding,startlab);
        result:=datatcb.emit_string_const_common(st_ansistring,len,encoding,startlab);
 
 
        getmem(s,len+1);
        getmem(s,len+1);
@@ -1134,12 +1133,11 @@ implementation
        datatcb.emit_tai(tai_string.create_pchar(s,len+1),datadef);
        datatcb.emit_tai(tai_string.create_pchar(s,len+1),datadef);
        datatcb.maybe_end_aggregate(datadef);
        datatcb.maybe_end_aggregate(datadef);
        ansistrrecdef:=datatcb.end_anonymous_record;
        ansistrrecdef:=datatcb.end_anonymous_record;
-       list.concatlist(datatcb.get_final_asmlist(startlab,ansistrrecdef,sec_rodata_norel,startlab.name,const_align(sizeof(pint))));
-       datatcb.free;
+       finish_internal_data_builder(datatcb,startlab,ansistrrecdef,const_align(sizeof(pointer)));
      end;
      end;
 
 
 
 
-   class function ttai_typedconstbuilder.emit_unicodestring_const(list: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):tasmlabofs;
+   function ttai_typedconstbuilder.emit_unicodestring_const(datalist: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):tasmlabofs;
      var
      var
        i, strlength: longint;
        i, strlength: longint;
        string_symofs: asizeint;
        string_symofs: asizeint;
@@ -1148,12 +1146,12 @@ implementation
        uniwidestrrecdef: trecorddef;
        uniwidestrrecdef: trecorddef;
        datatcb: ttai_typedconstbuilder;
        datatcb: ttai_typedconstbuilder;
      begin
      begin
-       datatcb:=self.create([tcalo_is_lab,tcalo_make_dead_strippable]);
+       start_internal_data_builder(datalist,sec_rodata_norel,'',datatcb,startlab);
        strlength:=getlengthwidestring(pcompilerwidestring(data));
        strlength:=getlengthwidestring(pcompilerwidestring(data));
        if winlike then
        if winlike then
          begin
          begin
+           result.lab:=startlab;
            datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),sizeof(pint));
            datatcb.begin_anonymous_record('$'+get_dynstring_rec_name(st_widestring,true,strlength),sizeof(pint));
-           current_asmdata.getglobaldatalabel(result.lab);
            datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
            datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
            { can we optimise by placing the string constant label at the
            { can we optimise by placing the string constant label at the
              required offset? }
              required offset? }
@@ -1162,8 +1160,9 @@ implementation
              begin
              begin
                { yes }
                { yes }
                datatcb.emit_tai(Tai_label.Create(result.lab),widecharpointertype);
                datatcb.emit_tai(Tai_label.Create(result.lab),widecharpointertype);
-               { allocate a separate label for the start of the data }
-               current_asmdata.getglobaldatalabel(startlab);
+               { allocate a separate label for the start of the data (see
+                 emit_string_const_common() for explanation) }
+               startlab:=tasmlabel.create(current_asmdata.AsmSymbolDict,startlab.name+'$strlab',startlab.bind,startlab.typ);
              end
              end
            else
            else
              internalerror(2015031502);
              internalerror(2015031502);
@@ -1187,10 +1186,10 @@ implementation
        else
        else
          { code generation for other sizes must be written }
          { code generation for other sizes must be written }
          internalerror(200904271);
          internalerror(200904271);
-       list.concatlist(datatcb.get_final_asmlist(startlab,uniwidestrrecdef,sec_rodata_norel,startlab.name,const_align(sizeof(pint))));
-       datatcb.free;
+       finish_internal_data_builder(datatcb,startlab,datadef,const_align(sizeof(pint)));
      end;
      end;
 
 
+
    procedure ttai_typedconstbuilder.emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);
    procedure ttai_typedconstbuilder.emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);
      begin
      begin
        emit_tai(Tai_const.Create_sym_offset(ll.lab,ll.ofs),charptrdef);
        emit_tai(Tai_const.Create_sym_offset(ll.lab,ll.ofs),charptrdef);

+ 7 - 3
compiler/cresstr.pas

@@ -136,10 +136,12 @@ uses
         resstrlab : tasmsymbol;
         resstrlab : tasmsymbol;
         endsymlab : tasmsymbol;
         endsymlab : tasmsymbol;
         R : TResourceStringItem;
         R : TResourceStringItem;
+        tcb : ttai_typedconstbuilder;
       begin
       begin
         { Put resourcestrings in a new objectfile. Putting it in multiple files
         { Put resourcestrings in a new objectfile. Putting it in multiple files
           makes the linking too dependent on the linker script requiring a SORT(*) for
           makes the linking too dependent on the linker script requiring a SORT(*) for
           the data sections }
           the data sections }
+        tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]);
         maybe_new_object_file(current_asmdata.asmlists[al_const]);
         maybe_new_object_file(current_asmdata.asmlists[al_const]);
         new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint));
         new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint));
 
 
@@ -149,7 +151,7 @@ uses
           make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
           make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
 
 
         { Write unitname entry }
         { Write unitname entry }
-        namelab:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),getansistringcodepage,False);
+        namelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),getansistringcodepage);
         current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(namelab.lab,namelab.ofs));
         current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(namelab.lab,namelab.ofs));
         current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
         current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
         current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
         current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
@@ -165,7 +167,7 @@ uses
             new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
             new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
             { Write default value }
             { Write default value }
             if assigned(R.value) and (R.len<>0) then
             if assigned(R.value) and (R.len<>0) then
-              valuelab:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage,False)
+              valuelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage)
             else
             else
               begin
               begin
                 valuelab.lab:=nil;
                 valuelab.lab:=nil;
@@ -173,7 +175,7 @@ uses
               end;
               end;
             { Append the name as a ansistring. }
             { Append the name as a ansistring. }
             current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
             current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
-            namelab:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),getansistringcodepage,False);
+            namelab:=tcb.emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),getansistringcodepage);
 
 
             {
             {
               Resourcestring index:
               Resourcestring index:
@@ -197,6 +199,8 @@ uses
             current_asmdata.asmlists[al_resourcestrings].concat(tai_symbol_end.create(resstrlab));
             current_asmdata.asmlists[al_resourcestrings].concat(tai_symbol_end.create(resstrlab));
             R:=TResourceStringItem(R.Next);
             R:=TResourceStringItem(R.Next);
           end;
           end;
+        { nothing has been emited to the tcb itself }
+        tcb.free;
         new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'3_END'),sizeof(pint));
         new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'3_END'),sizeof(pint));
         endsymlab:=current_asmdata.DefineAsmSymbol(make_mangledname('RESSTR',current_module.localsymtable,'END'),AB_GLOBAL,AT_DATA);
         endsymlab:=current_asmdata.DefineAsmSymbol(make_mangledname('RESSTR',current_module.localsymtable,'END'),AB_GLOBAL,AT_DATA);
         current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.create_global(endsymlab,0));
         current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.create_global(endsymlab,0));

+ 12 - 7
compiler/ncgcon.pas

@@ -325,6 +325,7 @@ implementation
               { :-(, we must generate a new entry }
               { :-(, we must generate a new entry }
               if not assigned(entry^.Data) then
               if not assigned(entry^.Data) then
                 begin
                 begin
+                  datatcb:=ctai_typedconstbuilder.create([tcalo_is_lab,tcalo_make_dead_strippable]);
                    case cst_type of
                    case cst_type of
                       cst_ansistring:
                       cst_ansistring:
                         begin
                         begin
@@ -332,12 +333,15 @@ implementation
                              InternalError(2008032301)   { empty string should be handled above }
                              InternalError(2008032301)   { empty string should be handled above }
                            else
                            else
                              begin
                              begin
-                               lastlabel:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len,tstringdef(resultdef).encoding,true);
+                               lastlabel:=datatcb.emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len,tstringdef(resultdef).encoding);
                                { because we hardcode the offset below due to it
                                { because we hardcode the offset below due to it
                                  not being stored in the hashset, check here }
                                  not being stored in the hashset, check here }
-                               if lastlabel.ofs<>ctai_typedconstbuilder.get_string_symofs(st_ansistring,false) then
+                               if lastlabel.ofs<>datatcb.get_string_symofs(st_ansistring,false) then
                                  internalerror(2012051703);
                                  internalerror(2012051703);
                              end;
                              end;
+                           { no contents of the datatcb itself to concatenate,
+                             as we will just return the address of the emitted
+                             ansistring constant record }
                         end;
                         end;
                       cst_unicodestring,
                       cst_unicodestring,
                       cst_widestring:
                       cst_widestring:
@@ -346,21 +350,23 @@ implementation
                              InternalError(2008032302)   { empty string should be handled above }
                              InternalError(2008032302)   { empty string should be handled above }
                            else
                            else
                              begin
                              begin
-                               lastlabel:=ctai_typedconstbuilder.emit_unicodestring_const(current_asmdata.AsmLists[al_typedconsts],
+                               lastlabel:=datatcb.emit_unicodestring_const(current_asmdata.AsmLists[al_typedconsts],
                                                value_str,
                                                value_str,
                                                tstringdef(resultdef).encoding,
                                                tstringdef(resultdef).encoding,
                                                winlikewidestring);
                                                winlikewidestring);
                                { because we hardcode the offset below due to it
                                { because we hardcode the offset below due to it
                                  not being stored in the hashset, check here }
                                  not being stored in the hashset, check here }
-                               if lastlabel.ofs<>ctai_typedconstbuilder.get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring) then
+                               if lastlabel.ofs<>datatcb.get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring) then
                                  internalerror(2012051704);
                                  internalerror(2012051704);
                              end;
                              end;
+                           { no contents of the datatcb itself to concatenate,
+                             as we will just return the address of the emitted
+                             unicode/widestring constant record }
                         end;
                         end;
                       cst_shortstring:
                       cst_shortstring:
                         begin
                         begin
                           current_asmdata.getglobaldatalabel(lastlabel.lab);
                           current_asmdata.getglobaldatalabel(lastlabel.lab);
 
 
-                          datatcb:=ctai_typedconstbuilder.create([tcalo_is_lab,tcalo_make_dead_strippable]);
                           { truncate strings larger than 255 chars }
                           { truncate strings larger than 255 chars }
                           if len>255 then
                           if len>255 then
                            l:=255
                            l:=255
@@ -378,7 +384,6 @@ implementation
                           current_asmdata.asmlists[al_typedconsts].concatList(
                           current_asmdata.asmlists[al_typedconsts].concatList(
                             datatcb.get_final_asmlist(lastlabel.lab,datadef,sec_rodata_norel,lastlabel.lab.name,const_align(sizeof(pint)))
                             datatcb.get_final_asmlist(lastlabel.lab,datadef,sec_rodata_norel,lastlabel.lab.name,const_align(sizeof(pint)))
                           );
                           );
-                          datatcb.free;
                         end;
                         end;
                       cst_conststring:
                       cst_conststring:
                         begin
                         begin
@@ -400,10 +405,10 @@ implementation
                           current_asmdata.asmlists[al_typedconsts].concatList(
                           current_asmdata.asmlists[al_typedconsts].concatList(
                             datatcb.get_final_asmlist(lastlabel.lab,datadef,sec_rodata_norel,lastlabel.lab.name,const_align(sizeof(pint)))
                             datatcb.get_final_asmlist(lastlabel.lab,datadef,sec_rodata_norel,lastlabel.lab.name,const_align(sizeof(pint)))
                           );
                           );
-                          datatcb.free;
                         end;
                         end;
                       else
                       else
                         internalerror(2013120103);
                         internalerror(2013120103);
+                      datatcb.free;
                    end;
                    end;
                    lab_str:=lastlabel.lab;
                    lab_str:=lastlabel.lab;
                    entry^.Data:=lastlabel.lab;
                    entry^.Data:=lastlabel.lab;

+ 2 - 2
compiler/ngtcon.pas

@@ -554,7 +554,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
                        ll.ofs:=0;
                        ll.ofs:=0;
                      end
                      end
                    else
                    else
-                     ll:=ctai_typedconstbuilder.emit_ansistring_const(fdatalist,strval,strlength,def.encoding,true);
+                     ll:=ftcb.emit_ansistring_const(fdatalist,strval,strlength,def.encoding);
                    ftcb.emit_string_offset(ll,strlength,def.stringtype,false,charpointertype);
                    ftcb.emit_string_offset(ll,strlength,def.stringtype,false,charpointertype);
                 end;
                 end;
               st_unicodestring,
               st_unicodestring,
@@ -570,7 +570,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
                    else
                    else
                      begin
                      begin
                        winlike:=(def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags);
                        winlike:=(def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags);
-                       ll:=ctai_typedconstbuilder.emit_unicodestring_const(fdatalist,
+                       ll:=ftcb.emit_unicodestring_const(fdatalist,
                               strval,
                               strval,
                               def.encoding,
                               def.encoding,
                               winlike);
                               winlike);