module separate_compiler
import abstract_compiler
-import coloring
+intrude import coloring
+import rapid_type_analysis
# Add separate compiler specific options
redef class ToolContext
private var undead_types: Set[MType] = new HashSet[MType]
private var partial_types: Set[MType] = new HashSet[MType]
- protected var typeids: HashMap[MType, Int] protected writable = new HashMap[MType, Int]
- private var type_colors: Map[MType, Int] = typeids
+ private var type_layout_builder: TypeLayoutBuilder
+ private var type_layout: nullable TypeLayout
private var type_tables: nullable Map[MType, Array[nullable MType]] = null
private var live_unanchored_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
private var unanchored_types_tables: nullable Map[MClassType, Array[nullable MType]]
private var unanchored_types_masks: nullable Map[MClassType, Int]
- protected var class_coloring: ClassColoring
-
protected var method_colors: Map[MMethod, Int]
protected var method_tables: Map[MClass, Array[nullable MMethodDef]]
init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis) do
super
self.header = new_visitor
+ self.init_layout_builders
self.runtime_type_analysis = runtime_type_analysis
self.do_property_coloring
self.compile_box_kinds
end
+ protected fun init_layout_builders do
+ # Typing Layout
+ if modelbuilder.toolcontext.opt_bm_typing.value then
+ self.type_layout_builder = new BMTypeLayoutBuilder(self.mainmodule)
+ else if modelbuilder.toolcontext.opt_phmod_typing.value then
+ self.type_layout_builder = new PHTypeLayoutBuilder(self.mainmodule, new PHModOperator)
+ self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
+ else if modelbuilder.toolcontext.opt_phand_typing.value then
+ self.type_layout_builder = new PHTypeLayoutBuilder(self.mainmodule, new PHAndOperator)
+ self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
+ else
+ self.type_layout_builder = new CLTypeLayoutBuilder(self.mainmodule)
+ end
+ end
+
redef fun compile_header_structs do
self.header.add_decl("typedef void(*nitmethod_t)(void); /* general C type representing a Nit method. */")
self.compile_header_attribute_structs
# classes coloration
var mclasses = new HashSet[MClass].from(modelbuilder.model.mclasses)
- self.class_coloring = new ClassColoring(mainmodule)
+ var class_coloring = new ClassColoring(mainmodule)
class_coloring.colorize(mclasses)
# methods coloration
- var method_coloring = new MethodColoring(self.class_coloring)
+ var method_coloring = new MethodColoring(class_coloring)
self.method_colors = method_coloring.colorize
self.method_tables = method_coloring.build_property_tables
self.compile_color_consts(self.method_colors)
# attributes coloration
- var attribute_coloring = new AttributeColoring(self.class_coloring)
+ var attribute_coloring = new AttributeColoring(class_coloring)
self.attr_colors = attribute_coloring.colorize
self.attr_tables = attribute_coloring.build_property_tables
self.compile_color_consts(self.attr_colors)
- if modelbuilder.toolcontext.opt_bm_typing.value then
- self.class_coloring = new NaiveClassColoring(mainmodule)
- self.class_coloring.colorize(mclasses)
- end
-
# vt coloration
if modelbuilder.toolcontext.opt_bm_typing.value then
- var vt_coloring = new NaiveVTColoring(self.class_coloring)
+ var vt_coloring = new NaiveVTColoring(class_coloring)
self.vt_colors = vt_coloring.colorize
self.vt_tables = vt_coloring.build_property_tables
else if modelbuilder.toolcontext.opt_phmod_typing.value then
- var vt_coloring = new VTModPerfectHashing(self.class_coloring)
+ var vt_coloring = new VTModPerfectHashing(class_coloring)
self.vt_colors = vt_coloring.colorize
self.vt_masks = vt_coloring.compute_masks
self.vt_tables = vt_coloring.build_property_tables
else if modelbuilder.toolcontext.opt_phand_typing.value then
- var vt_coloring = new VTAndPerfectHashing(self.class_coloring)
+ var vt_coloring = new VTAndPerfectHashing(class_coloring)
self.vt_colors = vt_coloring.colorize
self.vt_masks = vt_coloring.compute_masks
self.vt_tables = vt_coloring.build_property_tables
else
- var vt_coloring = new VTColoring(self.class_coloring)
+ var vt_coloring = new VTColoring(class_coloring)
self.vt_colors = vt_coloring.colorize
self.vt_tables = vt_coloring.build_property_tables
end
end
mtypes.add_all(self.partial_types)
- # set type unique id
- if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then
- var sorted_mtypes = new Array[MType].from(mtypes)
- var sorter = new ReverseTypeSorter(self.mainmodule)
- sorter.sort(sorted_mtypes)
- for mtype in sorted_mtypes do
- self.typeids[mtype] = self.typeids.length + 1
- end
- else
- for mtype in mtypes do
- self.typeids[mtype] = self.typeids.length
- end
- end
-
# VT and FT are stored with other unresolved types in the big unanchored_tables
self.compile_unanchored_tables(mtypes)
# colorize types
- if modelbuilder.toolcontext.opt_bm_typing.value then
- var type_coloring = new NaiveTypeColoring(self.mainmodule)
- self.type_colors = type_coloring.colorize(mtypes)
- self.type_tables = type_coloring.build_type_tables(mtypes, type_colors)
- else if modelbuilder.toolcontext.opt_phmod_typing.value then
- var type_coloring = new TypeModPerfectHashing(self.mainmodule)
- self.type_colors = type_coloring.compute_masks(mtypes, typeids)
- self.type_tables = type_coloring.hash_type_tables(mtypes, typeids, type_colors)
- self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
- else if modelbuilder.toolcontext.opt_phand_typing.value then
- var type_coloring = new TypeAndPerfectHashing(self.mainmodule)
- self.type_colors = type_coloring.compute_masks(mtypes, typeids)
- self.type_tables = type_coloring.hash_type_tables(mtypes, typeids, type_colors)
- self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
- else
- var type_coloring = new TypeColoring(self.mainmodule)
- self.type_colors = type_coloring.colorize(mtypes)
- self.type_tables = type_coloring.build_type_tables(mtypes, type_colors)
- end
-
-
+ self.type_layout = self.type_layout_builder.build_layout(mtypes)
+ self.type_tables = self.build_type_tables(mtypes)
return mtypes
end
+ # Build type tables
+ fun build_type_tables(mtypes: Set[MType]): Map[MType, Array[nullable MType]] do
+ var tables = new HashMap[MType, Array[nullable MType]]
+ var layout = self.type_layout
+ for mtype in mtypes do
+ var table = new Array[nullable MType]
+ var supers = new HashSet[MType]
+ supers.add_all(self.mainmodule.super_mtypes(mtype, mtypes))
+ supers.add(mtype)
+ for sup in supers do
+ var color: Int
+ if layout isa PHTypeLayout then
+ color = layout.hashes[mtype][sup]
+ else
+ color = layout.pos[sup]
+ end
+ if table.length <= color then
+ for i in [table.length .. color[ do
+ table[i] = null
+ end
+ end
+ table[color] = sup
+ end
+ tables[mtype] = table
+ end
+ return tables
+ end
+
protected fun compile_unanchored_tables(mtypes: Set[MType]) do
# Unanchored_tables is used to perform a type resolution at runtime in O(1)
# const struct type_X
v.add_decl("const struct type_{c_name} type_{c_name} = \{")
- v.add_decl("{self.typeids[mtype]},")
+ v.add_decl("{self.type_layout.ids[mtype]},")
v.add_decl("\"{mtype}\", /* class_name_string */")
- v.add_decl("{self.type_colors[mtype]},")
+ var layout = self.type_layout
+ if layout isa PHTypeLayout then
+ v.add_decl("{layout.masks[mtype]},")
+ else
+ v.add_decl("{layout.pos[mtype]},")
+ end
if mtype isa MNullableType then
v.add_decl("1,")
else
if stype == null then
v.add_decl("-1, /* empty */")
else
- v.add_decl("{self.typeids[stype]}, /* {stype} */")
+ v.add_decl("{self.type_layout.ids[stype]}, /* {stype} */")
end
end
v.add_decl("\},")
else
ntype = ft.anchor_to(self.mainmodule, mclass_type)
end
- if self.typeids.has_key(ntype) then
+ if self.type_layout.ids.has_key(ntype) then
v.add_decl("(struct type*)&type_{ntype.c_name}, /* {ft} ({ntype}) */")
else
v.add_decl("NULL, /* empty ({ft} not a live type) */")
abort
end
- if self.typeids.has_key(bound) then
+ if self.type_layout.ids.has_key(bound) then
v.add_decl("(struct type*)&type_{is_nullable}{bound.c_name}, /* {bound} */")
else
v.add_decl("NULL, /* dead type {bound} */")
# the value stored is tv.
var tv = t.resolve_for(mclass_type, mclass_type, self.mainmodule, true)
# FIXME: What typeids means here? How can a tv not be live?
- if self.typeids.has_key(tv) then
+ if self.type_layout.ids.has_key(tv) then
v.add_decl("(struct type*)&type_{tv.c_name}, /* {t}: {tv} */")
else
v.add_decl("NULL, /* empty ({t}: {tv} not a live type) */")