X-Git-Url: http://nitlanguage.org diff --git a/src/separate_erasure_compiler.nit b/src/separate_erasure_compiler.nit index 3cce9f9..1442af0 100644 --- a/src/separate_erasure_compiler.nit +++ b/src/separate_erasure_compiler.nit @@ -67,8 +67,8 @@ end class SeparateErasureCompiler super SeparateCompiler - private var class_layout: nullable TypingLayout[MClass] - 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 @@ -77,18 +77,67 @@ class SeparateErasureCompiler 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 @@ -102,7 +151,7 @@ class SeparateErasureCompiler supers.add(mclass) for sup in supers do var color: Int - if layout isa PHTypingLayout[MClass] then + if layout isa PHLayout[MClass, MClass] then color = layout.hashes[mclass][sup] else color = layout.pos[sup] @@ -126,12 +175,18 @@ class SeparateErasureCompiler 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 @@ -146,10 +201,6 @@ class SeparateErasureCompiler 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} \{") @@ -168,7 +219,7 @@ class SeparateErasureCompiler 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 PHTypingLayout[MClass] then + if layout isa PHLayout[MClass, MClass] then v.add_decl("{layout.masks[mclass]},") else v.add_decl("{layout.pos[mclass]},") @@ -279,7 +330,7 @@ class SeparateErasureCompiler 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}];") @@ -287,8 +338,9 @@ class SeparateErasureCompiler 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("\{") @@ -297,7 +349,7 @@ class SeparateErasureCompiler 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 @@ -328,26 +380,50 @@ class SeparateErasureCompiler # 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 @@ -437,7 +513,7 @@ class SeparateErasureCompilerVisitor 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}];") @@ -465,7 +541,7 @@ class SeparateErasureCompilerVisitor 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) \{")