* 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 -
This commit is contained in:
Jonas Maebe 2015-03-27 21:25:53 +00:00
parent 6ed273eec5
commit 419a97cce8
4 changed files with 42 additions and 34 deletions

View File

@ -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; function emit_ansistring_const(datalist: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding): tasmlabofs;
class function emit_unicodestring_const(list: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):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); result.lab:=startlab;
startlab:=result.lab;
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]; start_internal_data_builder(datalist,sec_rodata_norel,'',datatcb,startlab);
if NewSection then
include(options,tcalo_make_dead_strippable);
datatcb:=self.create(options);
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)))); finish_internal_data_builder(datatcb,startlab,ansistrrecdef,const_align(sizeof(pointer)));
datatcb.free;
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 } { allocate a separate label for the start of the data (see
current_asmdata.getglobaldatalabel(startlab); 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)))); finish_internal_data_builder(datatcb,startlab,datadef,const_align(sizeof(pint)));
datatcb.free;
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);

View File

@ -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));

View File

@ -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;

View File

@ -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);