X-Git-Url: http://nitlanguage.org diff --git a/src/separate_compiler.nit b/src/separate_compiler.nit index 639e6bc..3aee9b1 100644 --- a/src/separate_compiler.nit +++ b/src/separate_compiler.nit @@ -16,7 +16,7 @@ module separate_compiler import abstract_compiler -intrude import coloring +import layout_builders import rapid_type_analysis # Add separate compiler specific options @@ -37,8 +37,8 @@ redef class ToolContext var opt_phmod_typing: OptionBool = new OptionBool("Replace coloration by perfect hashing (with mod operator)", "--phmod-typing") # --use-and-perfect-hashing var opt_phand_typing: OptionBool = new OptionBool("Replace coloration by perfect hashing (with and operator)", "--phand-typing") - # --generic-resolution-tree - var opt_typing_table_metrics: OptionBool = new OptionBool("Enable static size measuring of tables used for typing and resolution", "--typing-table-metrics") + # --tables-metrics + var opt_tables_metrics: OptionBool = new OptionBool("Enable static size measuring of tables used for vft, typing and resolution", "--tables-metrics") redef init do @@ -51,7 +51,7 @@ redef class ToolContext self.option_context.add_option(self.opt_bm_typing) self.option_context.add_option(self.opt_phmod_typing) self.option_context.add_option(self.opt_phand_typing) - self.option_context.add_option(self.opt_typing_table_metrics) + self.option_context.add_option(self.opt_tables_metrics) end end @@ -98,66 +98,44 @@ end class SeparateCompiler super AbstractCompiler - # Cache for classid - protected var classids: HashMap[MClassType, String] = new HashMap[MClassType, String] - # The result of the RTA (used to know live types and methods) var runtime_type_analysis: RapidTypeAnalysis private var undead_types: Set[MType] = new HashSet[MType] private var partial_types: Set[MType] = new HashSet[MType] + private var live_unresolved_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]] - private var type_layout_builder: TypingLayoutBuilder[MType] - private var type_layout: nullable TypingLayout[MType] - 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 resolution_layout: nullable ResolutionLayout - private var resolution_tables: nullable Map[MClassType, Array[nullable MType]] - - protected var method_layout: nullable PropertyLayout[MMethod] - protected var method_tables: Map[MClass, Array[nullable MPropDef]] - - protected var attr_layout: nullable PropertyLayout[MAttribute] - protected var attr_tables: Map[MClass, Array[nullable MPropDef]] + private var type_layout: nullable Layout[MType] + private var resolution_layout: nullable Layout[MType] + protected var method_layout: nullable Layout[MMethod] + protected var attr_layout: nullable Layout[MAttribute] init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis) do - super + super(mainmodule, mmbuilder) 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 self.header.add_decl("struct class \{ int box_kind; nitmethod_t vft[1]; \}; /* general C type representing a Nit class. */") - # With unanchored_table, all live type resolution are stored in a big table: unanchored_table - self.header.add_decl("struct type \{ int id; const char *name; int color; short int is_nullable; struct types *unanchored_table; int table_size; int type_table[1]; \}; /* general C type representing a Nit type. */") + # With resolution_table_table, all live type resolution are stored in a big table: resolution_table + self.header.add_decl("struct type \{ int id; const char *name; int color; short int is_nullable; struct types *resolution_table; int table_size; int type_table[1]; \}; /* general C type representing a Nit type. */") if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then - self.header.add_decl("struct types \{ int mask; struct type *types[1]; \}; /* a list types (used for vts, fts and unanchored lists). */") + self.header.add_decl("struct types \{ int mask; struct type *types[1]; \}; /* a list types (used for vts, fts and unresolved lists). */") else - self.header.add_decl("struct types \{ struct type *types[1]; \}; /* a list types (used for vts, fts and unanchored lists). */") + self.header.add_decl("struct types \{ struct type *types[1]; \}; /* a list types (used for vts, fts and unresolved lists). */") + 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 \{ struct type *type; struct class *class; nitattribute_t attrs[1]; \} val; /* general C type representing a Nit instance. */") @@ -232,22 +210,37 @@ class SeparateCompiler fun do_property_coloring do var mclasses = new HashSet[MClass].from(modelbuilder.model.mclasses) + # Layouts + var method_layout_builder: PropertyLayoutBuilder[MMethod] + var attribute_layout_builder: PropertyLayoutBuilder[MAttribute] + if modelbuilder.toolcontext.opt_bm_typing.value then + method_layout_builder = new MMethodBMizer(self.mainmodule) + attribute_layout_builder = new MAttributeBMizer(self.mainmodule) + else if modelbuilder.toolcontext.opt_phmod_typing.value then + method_layout_builder = new MMethodHasher(new PHModOperator, self.mainmodule) + attribute_layout_builder = new MAttributeHasher(new PHModOperator, self.mainmodule) + else if modelbuilder.toolcontext.opt_phand_typing.value then + method_layout_builder = new MMethodHasher(new PHAndOperator, self.mainmodule) + attribute_layout_builder = new MAttributeHasher(new PHAndOperator, self.mainmodule) + else + method_layout_builder = new MMethodColorer(self.mainmodule) + attribute_layout_builder = new MAttributeColorer(self.mainmodule) + end + # methods coloration - var method_coloring = new CLPropertyLayoutBuilder[MMethod](mainmodule) - var method_layout = method_coloring.build_layout(mclasses) + var method_layout = method_layout_builder.build_layout(mclasses) self.method_tables = build_method_tables(mclasses, method_layout) self.compile_color_consts(method_layout.pos) self.method_layout = method_layout # attributes coloration - var attribute_coloring = new CLPropertyLayoutBuilder[MAttribute](mainmodule) - var attr_layout = attribute_coloring.build_layout(mclasses) + var attr_layout = attribute_layout_builder.build_layout(mclasses) self.attr_tables = build_attr_tables(mclasses, attr_layout) self.compile_color_consts(attr_layout.pos) self.attr_layout = attr_layout end - fun build_method_tables(mclasses: Set[MClass], layout: PropertyLayout[MProperty]): Map[MClass, Array[nullable MPropDef]] do + fun build_method_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] @@ -291,7 +284,7 @@ class SeparateCompiler return tables end - fun build_attr_tables(mclasses: Set[MClass], layout: PropertyLayout[MProperty]): Map[MClass, Array[nullable MPropDef]] do + fun build_attr_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] @@ -350,12 +343,24 @@ class SeparateCompiler end mtypes.add_all(self.partial_types) + # Typing Layout + var layout_builder: TypingLayoutBuilder[MType] + if modelbuilder.toolcontext.opt_bm_typing.value then + layout_builder = new MTypeBMizer(self.mainmodule) + else if modelbuilder.toolcontext.opt_phmod_typing.value then + layout_builder = new MTypeHasher(new PHModOperator, self.mainmodule) + else if modelbuilder.toolcontext.opt_phand_typing.value then + layout_builder = new MTypeHasher(new PHAndOperator, self.mainmodule) + else + layout_builder = new MTypeColorer(self.mainmodule) + end + # colorize types - self.type_layout = self.type_layout_builder.build_layout(mtypes) + self.type_layout = layout_builder.build_layout(mtypes) self.type_tables = self.build_type_tables(mtypes) - # VT and FT are stored with other unresolved types in the big unanchored_tables - self.compile_unanchored_tables(mtypes) + # VT and FT are stored with other unresolved types in the big resolution_tables + self.compile_resolution_tables(mtypes) return mtypes end @@ -371,7 +376,7 @@ class SeparateCompiler supers.add(mtype) for sup in supers do var color: Int - if layout isa PHTypingLayout[MType] then + if layout isa PHLayout[MType, MType] then color = layout.hashes[mtype][sup] else color = layout.pos[sup] @@ -388,57 +393,57 @@ class SeparateCompiler 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) + protected fun compile_resolution_tables(mtypes: Set[MType]) do + # resolution_tables is used to perform a type resolution at runtime in O(1) - # During the visit of the body of classes, live_unanchored_types are collected + # During the visit of the body of classes, live_unresolved_types are collected # and associated to - # Collect all live_unanchored_types (visited in the body of classes) + # Collect all live_unresolved_types (visited in the body of classes) # Determinate fo each livetype what are its possible requested anchored types - var mtype2unanchored = new HashMap[MClassType, Set[MType]] + var mtype2unresolved = new HashMap[MClassType, Set[MType]] for mtype in self.runtime_type_analysis.live_types do var set = new HashSet[MType] for cd in mtype.collect_mclassdefs(self.mainmodule) do - if self.live_unanchored_types.has_key(cd) then - set.add_all(self.live_unanchored_types[cd]) + if self.live_unresolved_types.has_key(cd) then + set.add_all(self.live_unresolved_types[cd]) end end - mtype2unanchored[mtype] = set + mtype2unresolved[mtype] = set end # Compute the table layout with the prefered method var resolution_builder: ResolutionLayoutBuilder if modelbuilder.toolcontext.opt_bm_typing.value then - resolution_builder = new BMResolutionLayoutBuilder + resolution_builder = new ResolutionBMizer else if modelbuilder.toolcontext.opt_phmod_typing.value then - resolution_builder = new PHResolutionLayoutBuilder(new PHModOperator) + resolution_builder = new ResolutionHasher(new PHModOperator) else if modelbuilder.toolcontext.opt_phand_typing.value then - resolution_builder = new PHResolutionLayoutBuilder(new PHAndOperator) + resolution_builder = new ResolutionHasher(new PHAndOperator) else - resolution_builder = new CLResolutionLayoutBuilder + resolution_builder = new ResolutionColorer end - self.resolution_layout = resolution_builder.build_layout(mtype2unanchored) - self.resolution_tables = self.build_resolution_tables(mtype2unanchored) + self.resolution_layout = resolution_builder.build_layout(mtype2unresolved) + self.resolution_tables = self.build_resolution_tables(mtype2unresolved) - # Compile a C constant for each collected unanchored type. - # Either to a color, or to -1 if the unanchored type is dead (no live receiver can require it) - var all_unanchored = new HashSet[MType] - for t in self.live_unanchored_types.values do - all_unanchored.add_all(t) + # Compile a C constant for each collected unresolved type. + # Either to a color, or to -1 if the unresolved type is dead (no live receiver can require it) + var all_unresolved = new HashSet[MType] + for t in self.live_unresolved_types.values do + all_unresolved.add_all(t) end - var all_unanchored_types_colors = new HashMap[MType, Int] - for t in all_unanchored do + var all_unresolved_types_colors = new HashMap[MType, Int] + for t in all_unresolved do if self.resolution_layout.pos.has_key(t) then - all_unanchored_types_colors[t] = self.resolution_layout.pos[t] + all_unresolved_types_colors[t] = self.resolution_layout.pos[t] else - all_unanchored_types_colors[t] = -1 + all_unresolved_types_colors[t] = -1 end end - self.compile_color_consts(all_unanchored_types_colors) + self.compile_color_consts(all_unresolved_types_colors) #print "tables" - #for k, v in unanchored_types_tables.as(not null) do + #for k, v in unresolved_types_tables.as(not null) do # print "{k}: {v.join(", ")}" #end #print "" @@ -451,7 +456,7 @@ class SeparateCompiler var table = new Array[nullable MType] for mtype in mtypes do var color: Int - if layout isa PHResolutionLayout then + if layout isa PHLayout[MClassType, MType] then color = layout.hashes[mclasstype][mtype] else color = layout.pos[mtype] @@ -530,7 +535,7 @@ class SeparateCompiler self.header.add_decl("const char *name;") self.header.add_decl("int color;") self.header.add_decl("short int is_nullable;") - self.header.add_decl("const struct types *unanchored_table;") + self.header.add_decl("const struct types *resolution_table;") self.header.add_decl("int table_size;") self.header.add_decl("int type_table[{self.type_tables[mtype].length}];") self.header.add_decl("\};") @@ -540,7 +545,7 @@ class SeparateCompiler v.add_decl("{self.type_layout.ids[mtype]},") v.add_decl("\"{mtype}\", /* class_name_string */") var layout = self.type_layout - if layout isa PHTypingLayout[MType] then + if layout isa PHLayout[MType, MType] then v.add_decl("{layout.masks[mtype]},") else v.add_decl("{layout.pos[mtype]},") @@ -550,8 +555,8 @@ class SeparateCompiler else v.add_decl("0,") end - if compile_type_unanchored_table(mtype) then - v.add_decl("(struct types*) &unanchored_table_{c_name},") + if compile_type_resolution_table(mtype) then + v.add_decl("(struct types*) &resolution_table_{c_name},") else v.add_decl("NULL,") end @@ -568,7 +573,7 @@ class SeparateCompiler v.add_decl("\};") end - fun compile_type_unanchored_table(mtype: MType): Bool do + fun compile_type_resolution_table(mtype: MType): Bool do var mclass_type: MClassType if mtype isa MNullableType then @@ -580,10 +585,10 @@ class SeparateCompiler var layout = self.resolution_layout - # extern const struct unanchored_table_X unanchored_table_X - self.header.add_decl("extern const struct unanchored_table_{mtype.c_name} unanchored_table_{mtype.c_name};") - self.header.add_decl("struct unanchored_table_{mtype.c_name} \{") - if layout isa PHResolutionLayout then + # extern const struct resolution_table_X resolution_table_X + self.header.add_decl("extern const struct resolution_table_{mtype.c_name} resolution_table_{mtype.c_name};") + self.header.add_decl("struct resolution_table_{mtype.c_name} \{") + if layout isa PHLayout[MClassType, MType] then self.header.add_decl("int mask;") end self.header.add_decl("struct type *types[{self.resolution_tables[mclass_type].length}];") @@ -591,8 +596,8 @@ class SeparateCompiler # const struct fts_table_X fts_table_X var v = new_visitor - v.add_decl("const struct unanchored_table_{mtype.c_name} unanchored_table_{mtype.c_name} = \{") - if layout isa PHResolutionLayout then + v.add_decl("const struct resolution_table_{mtype.c_name} resolution_table_{mtype.c_name} = \{") + if layout isa PHLayout[MClassType, MType] then v.add_decl("{layout.masks[mclass_type]},") end v.add_decl("\{") @@ -630,10 +635,6 @@ class SeparateCompiler var v = 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("struct class_{c_name} \{") self.header.add_decl("int box_kind;") @@ -720,7 +721,7 @@ class SeparateCompiler v.add("if(type == NULL) \{") v.add_abort("type null") v.add("\}") - v.add("if(type->unanchored_table == NULL) \{") + v.add("if(type->resolution_table == NULL) \{") v.add("fprintf(stderr, \"Insantiation of a dead type: %s\\n\", type->name);") v.add_abort("type dead") v.add("\}") @@ -752,38 +753,60 @@ class SeparateCompiler # Stats + private var type_tables: Map[MType, Array[nullable MType]] = new HashMap[MType, Array[nullable MType]] + private var resolution_tables: Map[MClassType, Array[nullable MType]] = new HashMap[MClassType, Array[nullable MType]] + protected var method_tables: Map[MClass, Array[nullable MPropDef]] = new HashMap[MClass, Array[nullable MPropDef]] + protected var attr_tables: Map[MClass, Array[nullable MPropDef]] = new HashMap[MClass, Array[nullable MPropDef]] + redef fun display_stats do super - if self.modelbuilder.toolcontext.opt_typing_table_metrics.value then + if self.modelbuilder.toolcontext.opt_tables_metrics.value then display_sizes end end 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 = resolution_tables - if rtables != null then - for unanch, table in rtables do - rt_table += table.length - for e in table do if e == null then rt_holes += 1 - end - end - - var ttables = type_tables - if ttables != null then - for t, table in ttables do - st_table += table.length - for e in table do if e == null then st_holes += 1 - end - 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 type_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 resolution_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 @@ -989,12 +1012,19 @@ class SeparateCompilerVisitor return res end + redef fun supercall(m: MMethodDef, recvtype: MClassType, args: Array[RuntimeVariable]): nullable RuntimeVariable + do + # FIXME implements a polymorphic access in tables + m = m.lookup_next_definition(m.mclassdef.mmodule, m.mclassdef.bound_mtype) + return self.call(m, recvtype, args) + end + redef fun vararg_instance(mpropdef, recv, varargs, elttype) do # A vararg must be stored into an new array # The trick is that the dymaic type of the array may depends on the receiver # of the method (ie recv) if the static type is unresolved - # This is more complex than usual because the unanchored type must not be resolved + # This is more complex than usual because the unresolved type must not be resolved # with the current receiver (ie self). # Therefore to isolate the resolution from self, a local Frame is created. # One can see this implementation as an inlined method of the receiver whose only @@ -1115,13 +1145,13 @@ class SeparateCompilerVisitor do var compiler = self.compiler if mtype isa MGenericType and mtype.need_anchor then - link_unanchored_type(self.frame.mpropdef.mclassdef, mtype) + link_unresolved_type(self.frame.mpropdef.mclassdef, mtype) var recv = self.frame.arguments.first var recv_type_info = self.type_info(recv) if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - return self.new_expr("NEW_{mtype.mclass.c_name}((struct type *) {recv_type_info}->unanchored_table->types[HASH({recv_type_info}->unanchored_table->mask, {mtype.const_color})])", mtype) + return self.new_expr("NEW_{mtype.mclass.c_name}((struct type *) {recv_type_info}->resolution_table->types[HASH({recv_type_info}->resolution_table->mask, {mtype.const_color})])", mtype) else - return self.new_expr("NEW_{mtype.mclass.c_name}((struct type *) {recv_type_info}->unanchored_table->types[{mtype.const_color}])", mtype) + return self.new_expr("NEW_{mtype.mclass.c_name}((struct type *) {recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype) end end compiler.undead_types.add(mtype) @@ -1170,12 +1200,12 @@ class SeparateCompilerVisitor var type_struct = self.get_name("type_struct") self.add_decl("struct type* {type_struct};") - # Either with unanchored_table with a direct resolution - link_unanchored_type(self.frame.mpropdef.mclassdef, ntype) + # Either with resolution_table with a direct resolution + link_unresolved_type(self.frame.mpropdef.mclassdef, ntype) if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - self.add("{type_struct} = {recv_type_info}->unanchored_table->types[HASH({recv_type_info}->unanchored_table->mask, {ntype.const_color})];") + self.add("{type_struct} = {recv_type_info}->resolution_table->types[HASH({recv_type_info}->resolution_table->mask, {ntype.const_color})];") else - self.add("{type_struct} = {recv_type_info}->unanchored_table->types[{ntype.const_color}];") + self.add("{type_struct} = {recv_type_info}->resolution_table->types[{ntype.const_color}];") end if compiler.modelbuilder.toolcontext.opt_typing_test_metrics.value then self.compiler.count_type_test_unresolved[tag] += 1 @@ -1388,13 +1418,13 @@ class SeparateCompilerVisitor assert mtype isa MGenericType var compiler = self.compiler if mtype.need_anchor then - link_unanchored_type(self.frame.mpropdef.mclassdef, mtype) + link_unresolved_type(self.frame.mpropdef.mclassdef, mtype) var recv = self.frame.arguments.first var recv_type_info = self.type_info(recv) if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - return self.new_expr("NEW_{mtype.mclass.c_name}({length}, (struct type *) {recv_type_info}->unanchored_table->types[HASH({recv_type_info}->unanchored_table->mask, {mtype.const_color})])", mtype) + return self.new_expr("NEW_{mtype.mclass.c_name}({length}, (struct type *) {recv_type_info}->resolution_table->types[HASH({recv_type_info}->resolution_table->mask, {mtype.const_color})])", mtype) else - return self.new_expr("NEW_{mtype.mclass.c_name}({length}, (struct type *) {recv_type_info}->unanchored_table->types[{mtype.const_color}])", mtype) + return self.new_expr("NEW_{mtype.mclass.c_name}({length}, (struct type *) {recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype) end end compiler.undead_types.add(mtype) @@ -1427,13 +1457,13 @@ class SeparateCompilerVisitor self.ret(res) end - fun link_unanchored_type(mclassdef: MClassDef, mtype: MType) do + fun link_unresolved_type(mclassdef: MClassDef, mtype: MType) do assert mtype.need_anchor var compiler = self.compiler - if not compiler.live_unanchored_types.has_key(self.frame.mpropdef.mclassdef) then - compiler.live_unanchored_types[self.frame.mpropdef.mclassdef] = new HashSet[MType] + if not compiler.live_unresolved_types.has_key(self.frame.mpropdef.mclassdef) then + compiler.live_unresolved_types[self.frame.mpropdef.mclassdef] = new HashSet[MType] end - compiler.live_unanchored_types[self.frame.mpropdef.mclassdef].add(mtype) + compiler.live_unresolved_types[self.frame.mpropdef.mclassdef].add(mtype) end end