fun run_separate_compiler(mainmodule: MModule, runtime_type_analysis: RapidTypeAnalysis)
do
var time0 = get_time
- self.toolcontext.info("*** COMPILING TO C ***", 1)
+ self.toolcontext.info("*** GENERATING C ***", 1)
var compiler = new SeparateCompiler(mainmodule, self, runtime_type_analysis)
compiler.compile_header
# compile class structures
+ self.toolcontext.info("Property coloring", 2)
compiler.new_file("{mainmodule.name}.classes")
compiler.do_property_coloring
for m in mainmodule.in_importation.greaters do
# compile methods
for m in mainmodule.in_importation.greaters do
+ self.toolcontext.info("Generate C for module {m}", 2)
compiler.new_file("{m.name}.sep")
compiler.compile_module_to_c(m)
end
# compile live & cast type structures
+ self.toolcontext.info("Type coloring", 2)
compiler.new_file("{mainmodule.name}.types")
var mtypes = compiler.do_type_coloring
for t in mtypes do
compiler.display_stats
+ var time1 = get_time
+ self.toolcontext.info("*** END GENERATING C: {time1-time0} ***", 2)
write_and_make(compiler)
end
end
# 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
- method_layout_builder = new MMethodColorer(self.mainmodule)
- attribute_layout_builder = new MAttributeColorer(self.mainmodule)
- end
+ #FIXME PH and BM layouts too slow for large programs
+ #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_layout = method_layout_builder.build_layout(mclasses)
end
for mtype in mtypes do
- retieve_live_partial_types(mtype)
+ retrieve_partial_types(mtype)
end
mtypes.add_all(self.partial_types)
return tables
end
- fun retieve_live_partial_types(mtype: MType) do
+ fun retrieve_partial_types(mtype: MType) do
# add formal types arguments to mtypes
if mtype isa MGenericType then
for ft in mtype.arguments do
abort
end
self.partial_types.add(ft)
- retieve_live_partial_types(ft)
+ retrieve_partial_types(ft)
end
end
var mclass_type: MClassType
for pd in cd.mpropdefs do
if not pd isa MMethodDef then continue
#print "compile {pd} @ {cd} @ {mmodule}"
- var r = new SeparateRuntimeFunction(pd)
+ var r = pd.separate_runtime_function
r.compile_to_c(self)
- if true or cd.bound_mtype.ctype != "val*" then
- var r2 = new VirtualRuntimeFunction(pd)
- r2.compile_to_c(self)
- end
+ var r2 = pd.virtual_runtime_function
+ r2.compile_to_c(self)
end
end
self.mainmodule = old_module
if mpropdef == null then
v.add_decl("NULL, /* empty */")
else
- if true or mpropdef.mclassdef.bound_mtype.ctype != "val*" then
- v.require_declaration("VIRTUAL_{mpropdef.c_name}")
- v.add_decl("(nitmethod_t)VIRTUAL_{mpropdef.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
- else
- v.require_declaration("{mpropdef.c_name}")
- v.add_decl("(nitmethod_t){mpropdef.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
- end
+ assert mpropdef isa MMethodDef
+ var rf = mpropdef.virtual_runtime_function
+ v.require_declaration(rf.c_name)
+ v.add_decl("(nitmethod_t){rf.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
end
end
v.add_decl("\}")
self.header.add_decl("val* BOX_{c_name}({mtype.ctype});")
v.add_decl("/* allocate {mtype} */")
v.add_decl("val* BOX_{mtype.c_name}({mtype.ctype} value) \{")
- v.add("struct instance_{c_name}*res = GC_MALLOC(sizeof(struct instance_{c_name}));")
+ v.add("struct instance_{c_name}*res = nit_alloc(sizeof(struct instance_{c_name}));")
v.require_declaration("type_{c_name}")
v.add("res->type = &type_{c_name};")
v.require_declaration("class_{c_name}")
var res = v.new_named_var(mtype, "self")
res.is_exact = true
var mtype_elt = mtype.arguments.first
- v.add("{res} = GC_MALLOC(sizeof(struct instance_{c_name}) + length*sizeof({mtype_elt.ctype}));")
+ v.add("{res} = nit_alloc(sizeof(struct instance_{c_name}) + length*sizeof({mtype_elt.ctype}));")
v.add("{res}->type = type;")
hardening_live_type(v, "type")
v.require_declaration("class_{c_name}")
v.add_decl("{mtype.ctype} NEW_{c_name}(const struct type* type) \{")
var res = v.new_named_var(mtype, "self")
res.is_exact = true
- v.add("{res} = GC_MALLOC(sizeof(struct instance) + {attrs.length}*sizeof(nitattribute_t));")
+ v.add("{res} = nit_alloc(sizeof(struct instance) + {attrs.length}*sizeof(nitattribute_t));")
v.add("{res}->type = type;")
hardening_live_type(v, "type")
v.require_declaration("class_{c_name}")
redef fun send(mmethod, arguments)
do
if arguments.first.mcasttype.ctype != "val*" then
- return self.monomorphic_send(mmethod, arguments.first.mcasttype, arguments)
+ # In order to shortcut the primitive, we need to find the most specific method
+ # Howverr, because of performance (no flattening), we always work on the realmainmodule
+ var m = self.compiler.mainmodule
+ self.compiler.mainmodule = self.compiler.realmainmodule
+ var res = self.monomorphic_send(mmethod, arguments.first.mcasttype, arguments)
+ self.compiler.mainmodule = m
+ return res
end
var res: nullable RuntimeVariable
end
end
+redef class MMethodDef
+ fun separate_runtime_function: AbstractRuntimeFunction
+ do
+ var res = self.separate_runtime_function_cache
+ if res == null then
+ res = new SeparateRuntimeFunction(self)
+ self.separate_runtime_function_cache = res
+ end
+ return res
+ end
+ private var separate_runtime_function_cache: nullable SeparateRuntimeFunction
+
+ fun virtual_runtime_function: AbstractRuntimeFunction
+ do
+ var res = self.virtual_runtime_function_cache
+ if res == null then
+ res = new VirtualRuntimeFunction(self)
+ self.virtual_runtime_function_cache = res
+ end
+ return res
+ end
+ private var virtual_runtime_function_cache: nullable VirtualRuntimeFunction
+end
+
# The C function associated to a methoddef separately compiled
class SeparateRuntimeFunction
super AbstractRuntimeFunction
end
frame.returnlabel = v.get_name("RET_LABEL")
- if recv != arguments.first.mtype then
- #print "{self} {recv} {arguments.first}"
+ var subret = v.call(mmethoddef, recv, arguments)
+ if ret != null then
+ assert subret != null
+ v.assign(frame.returnvar.as(not null), subret)
end
- mmethoddef.compile_inside_to_c(v, arguments)
v.add("{frame.returnlabel.as(not null)}:;")
if ret != null then