class SeparateErasureCompiler
super SeparateCompiler
- private var class_layout: nullable ClassLayout
- private var class_tables: Map[MClass, Array[nullable MClass]]
+ private var class_layout: nullable Layout[MClass]
+ protected var vt_layout: nullable Layout[MVirtualTypeProp]
init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis) do
super
var mclasses = new HashSet[MClass].from(mmbuilder.model.mclasses)
- var layout_builder: ClassLayoutBuilder
+ var layout_builder: TypingLayoutBuilder[MClass]
if modelbuilder.toolcontext.opt_phmod_typing.value then
- layout_builder = new PHClassLayoutBuilder(mainmodule, new PHModOperator)
- self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
+ layout_builder = new MClassHasher(new PHModOperator, mainmodule)
else if modelbuilder.toolcontext.opt_phand_typing.value then
- layout_builder = new PHClassLayoutBuilder(mainmodule, new PHAndOperator)
- self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
+ layout_builder = new MClassHasher(new PHAndOperator, mainmodule)
else if modelbuilder.toolcontext.opt_bm_typing.value then
- layout_builder = new BMClassLayoutBuilder(mainmodule)
+ layout_builder = new MClassBMizer(mainmodule)
else
- layout_builder = new CLClassLayoutBuilder(mainmodule)
+ layout_builder = new MClassColorer(mainmodule)
end
self.class_layout = layout_builder.build_layout(mclasses)
self.class_tables = self.build_class_typing_tables(mclasses)
+
+ # vt coloration
+ var vt_coloring = new MVirtualTypePropColorer(mainmodule)
+ var vt_layout = vt_coloring.build_layout(mclasses)
+ self.vt_tables = build_vt_tables(mclasses, vt_layout)
+ self.compile_color_consts(vt_layout.pos)
+ self.vt_layout = vt_layout
+ end
+
+ fun build_vt_tables(mclasses: Set[MClass], layout: Layout[MProperty]): Map[MClass, Array[nullable MPropDef]] do
+ var tables = new HashMap[MClass, Array[nullable MPropDef]]
+ for mclass in mclasses do
+ var table = new Array[nullable MPropDef]
+ # first, fill table from parents by reverse linearization order
+ var parents = self.mainmodule.super_mclasses(mclass)
+ var lin = self.mainmodule.reverse_linearize_mclasses(parents)
+ for parent in lin do
+ for mproperty in self.mainmodule.properties(parent) do
+ if not mproperty isa MVirtualTypeProp then continue
+ var color = layout.pos[mproperty]
+ if table.length <= color then
+ for i in [table.length .. color[ do
+ table[i] = null
+ end
+ end
+ for mpropdef in mproperty.mpropdefs do
+ if mpropdef.mclassdef.mclass == parent then
+ table[color] = mpropdef
+ end
+ end
+ end
+ end
+
+ # then override with local properties
+ for mproperty in self.mainmodule.properties(mclass) do
+ if not mproperty isa MVirtualTypeProp then continue
+ var color = layout.pos[mproperty]
+ if table.length <= color then
+ for i in [table.length .. color[ do
+ table[i] = null
+ end
+ end
+ for mpropdef in mproperty.mpropdefs do
+ if mpropdef.mclassdef.mclass == mclass then
+ table[color] = mpropdef
+ end
+ end
+ end
+ tables[mclass] = table
+ end
+ return tables
end
# Build class tables
supers.add(mclass)
for sup in supers do
var color: Int
- if layout isa PHClassLayout then
+ if layout isa PHLayout[MClass, MClass] then
color = layout.hashes[mclass][sup]
else
color = layout.pos[sup]
self.header.add_decl("struct type_table \{ int size; int table[1]; \}; /* colorized type table. */")
self.header.add_decl("struct vts_entry \{ short int is_nullable; struct class *class; \}; /* link (nullable or not) between the vts and is bound. */")
- if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then
+ if self.vt_layout isa PHLayout[MClass, MVirtualTypeProp] then
self.header.add_decl("struct vts_table \{ int mask; struct vts_entry vts[1]; \}; /* vts list of a C type representation. */")
else
self.header.add_decl("struct vts_table \{ struct vts_entry vts[1]; \}; /* vts list of a C type representation. */")
end
+ if modelbuilder.toolcontext.opt_phmod_typing.value then
+ self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
+ else if modelbuilder.toolcontext.opt_phand_typing.value then
+ self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
+ end
+
self.header.add_decl("typedef struct val \{ struct class *class; nitattribute_t attrs[1]; \} val; /* general C type representing a Nit instance. */")
end
var v = self.new_visitor
v.add_decl("/* runtime class {c_name} */")
- var idnum = classids.length
- var idname = "ID_" + c_name
- self.classids[mtype] = idname
- #self.header.add_decl("#define {idname} {idnum} /* {c_name} */")
self.header.add_decl("extern const struct class_{c_name} class_{c_name};")
self.header.add_decl("struct class_{c_name} \{")
v.add_decl("\"{mclass.name}\", /* class_name_string */")
v.add_decl("{self.box_kind_of(mclass)}, /* box_kind */")
var layout = self.class_layout
- if layout isa PHClassLayout then
+ if layout isa PHLayout[MClass, MClass] then
v.add_decl("{layout.masks[mclass]},")
else
v.add_decl("{layout.pos[mclass]},")
self.header.add_decl("extern const struct vts_table_{mclass.c_name} vts_table_{mclass.c_name};")
self.header.add_decl("struct vts_table_{mclass.c_name} \{")
- if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then
+ if self.vt_layout isa PHLayout[MClass, MVirtualTypeProp] then
self.header.add_decl("int mask;")
end
self.header.add_decl("struct vts_entry vts[{self.vt_tables[mclass].length}];")
var v = new_visitor
v.add_decl("const struct vts_table_{mclass.c_name} vts_table_{mclass.c_name} = \{")
- if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then
- v.add_decl("{vt_masks[mclass]},")
+ if self.vt_layout isa PHLayout[MClass, MVirtualTypeProp] then
+ #TODO redo this when PHPropertyLayoutBuilder will be implemented
+ #v.add_decl("{vt_masks[mclass]},")
end
v.add_decl("\{")
v.add_decl("\{-1, NULL\}, /* empty */")
else
var is_null = 0
- var bound = retrieve_vt_bound(mclass.intro.bound_mtype, vt.bound)
+ var bound = retrieve_vt_bound(mclass.intro.bound_mtype, vt.as(MVirtualTypeDef).bound)
while bound isa MNullableType do
bound = retrieve_vt_bound(mclass.intro.bound_mtype, bound.mtype)
is_null = 1
# Stats
+ private var class_tables: Map[MClass, Array[nullable MClass]]
+ private var vt_tables: Map[MClass, Array[nullable MPropDef]]
+
redef fun display_sizes
do
- print "# size of tables"
- print "\trs size\trs hole\tst size\tst hole"
- var rt_table = 0
- var rt_holes = 0
- var st_table = 0
- var st_holes = 0
- var rtables = vt_tables
- for unanch, table in rtables do
- rt_table += table.length
- for e in table do if e == null then rt_holes += 1
- end
-
- var ttables = class_tables
- for t, table in ttables do
- st_table += table.length
- for e in table do if e == null then st_holes += 1
- end
- print "\t{rt_table}\t{rt_holes}\t{st_table}\t{st_holes}"
+ print "# size of subtyping tables"
+ print "\ttotal \tholes"
+ var total = 0
+ var holes = 0
+ for t, table in class_tables do
+ total += table.length
+ for e in table do if e == null then holes += 1
+ end
+ print "\t{total}\t{holes}"
+
+ print "# size of resolution tables"
+ print "\ttotal \tholes"
+ total = 0
+ holes = 0
+ for t, table in vt_tables do
+ total += table.length
+ for e in table do if e == null then holes += 1
+ end
+ print "\t{total}\t{holes}"
+
+ print "# size of methods tables"
+ print "\ttotal \tholes"
+ total = 0
+ holes = 0
+ for t, table in method_tables do
+ total += table.length
+ for e in table do if e == null then holes += 1
+ end
+ print "\t{total}\t{holes}"
+
+ print "# size of attributes tables"
+ print "\ttotal \tholes"
+ total = 0
+ holes = 0
+ for t, table in attr_tables do
+ total += table.length
+ for e in table do if e == null then holes += 1
+ end
+ print "\t{total}\t{holes}"
end
end
end
var entry = self.get_name("entry")
self.add("struct vts_entry {entry};")
- if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then
+ if self.compiler.as(SeparateErasureCompiler).vt_layout isa PHLayout[MClass, MVirtualTypeProp] then
self.add("{entry} = {recv_ptr}vts_table->vts[HASH({recv_ptr}vts_table->mask, {mtype.mproperty.const_color})];")
else
self.add("{entry} = {recv_ptr}vts_table->vts[{mtype.mproperty.const_color}];")
self.add("{res} = {accept_null};")
self.add("\} else \{")
end
- if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then
+ if self.compiler.as(SeparateErasureCompiler).class_layout isa PHLayout[MClass, MClass] then
self.add("{cltype} = HASH({class_ptr}color, {idtype});")
end
self.add("if({cltype} >= {class_ptr}type_table->size) \{")