* 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 -
This commit is contained in:
sergei 2012-02-13 18:49:48 +00:00
parent 8fc1fb5e15
commit 429af6f40b

View File

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