X-Git-Url: http://nitlanguage.org diff --git a/src/vm.nit b/src/vm.nit index 4dc29e9..3807ab7 100644 --- a/src/vm.nit +++ b/src/vm.nit @@ -17,7 +17,7 @@ # Implementation of the Nit virtual machine module vm -intrude import naive_interpreter +import interpreter::naive_interpreter import model_utils import perfect_hashing @@ -28,7 +28,7 @@ redef class ModelBuilder self.toolcontext.info("*** NITVM STARTING ***", 1) var interpreter = new VirtualMachine(self, mainmodule, arguments) - init_naive_interpreter(interpreter, mainmodule) + interpreter.start(mainmodule) var time1 = get_time self.toolcontext.info("*** NITVM STOPPING : {time1-time0} ***", 2) @@ -44,6 +44,16 @@ class VirtualMachine super NaiveInterpreter # Handles memory and garbage collection var memory_manager: MemoryManager = new MemoryManager + # The unique instance of the `MInit` value + var initialization_value: Instance + + init(modelbuilder: ModelBuilder, mainmodule: MModule, arguments: Array[String]) + do + super + var init_type = new MInitType(mainmodule.model) + initialization_value = new MutableInstance(init_type) + end + # Subtyping test for the virtual machine redef fun is_subtype(sub, sup: MType): Bool do @@ -96,7 +106,6 @@ class VirtualMachine super NaiveInterpreter # Sub can be discovered inside a Generic type during the subtyping test if not sub.mclass.loaded then create_class(sub.mclass) - if anchor == null then anchor = sub if sup isa MGenericType then var sub2 = sub.supertype_to(mainmodule, anchor, sup.mclass) assert sub2.mclass == sup.mclass @@ -138,28 +147,29 @@ class VirtualMachine super NaiveInterpreter assert(recv isa MutableInstance) - recv.internal_attributes = init_internal_attributes(null_instance, recv.mtype.as(MClassType).mclass.all_mattributes(mainmodule, none_visibility).length) + recv.internal_attributes = init_internal_attributes(initialization_value, recv.mtype.as(MClassType).mclass.all_mattributes(mainmodule, none_visibility).length) super end # Initialize the internal representation of an object (its attribute values) - private fun init_internal_attributes(null_instance: Instance, size: Int): Pointer + # `init_instance` is the initial value of attributes + private fun init_internal_attributes(init_instance: Instance, size: Int): Pointer import Array[Instance].length, Array[Instance].[] `{ Instance* attributes = malloc(sizeof(Instance) * size); int i; for(i=0; i 1 then + # Starting at self + var ordering = self.dfs(v, res) + + return ordering + else + # There is no super-class, self is Object + return superclasses + end + end + + # A kind of Depth-First-Search for superclasses ordering + # `v` : the current executed instance of VirtualMachine + # `res` : Result Array, ie current superclasses ordering + private fun dfs(v: VirtualMachine, res: Array[MClass]): Array[MClass] + do + # Add this class at the beginning + res.insert(self, 0) + + var direct_parents = self.in_hierarchy(v.mainmodule).direct_greaters.to_a + + if direct_parents.length > 1 then + # Prefix represents the class which has the most properties + # we try to choose it in first to reduce the number of potential recompilations + var prefix = null + var max = -1 + for cl in direct_parents do + # If we never have visited this class + if not res.has(cl) then + var properties_length = cl.all_mproperties(v.mainmodule, none_visibility).length + if properties_length > max then + max = properties_length + prefix = cl + end + end + end + + if prefix != null then + # Add the prefix class ordering at the beginning of our sequence + var prefix_res = new Array[MClass] + prefix_res = prefix.dfs(v, prefix_res) + + # Then we recurse on other classes + for cl in direct_parents do + if cl != prefix then + res = new Array[MClass] + res = cl.dfs(v, res) + + for cl_res in res do + if not prefix_res.has(cl_res) then prefix_res.push(cl_res) + end + end + end + res = prefix_res + end + + res.push(self) + else + if direct_parents.length > 0 then + res = direct_parents.first.dfs(v, res) + end + end + + if not res.has(self) then res.push(self) + + return res + end + + # Update positions of self class in `parent` + # `attributes_offset`: absolute offset of introduced attributes + # `methods_offset`: absolute offset of introduced methods private fun update_positions(attributes_offsets: Int, methods_offset:Int, parent: MClass) do parent.positions_attributes[self] = attributes_offsets @@ -383,6 +489,29 @@ redef class MutableInstance var internal_attributes: Pointer end +# Is the type of the initial value inside attributes +class MInitType + super MType + + redef var model: Model + protected init(model: Model) + do + self.model = model + end + + redef fun to_s do return "InitType" + redef fun as_nullable do return self + redef fun need_anchor do return false + redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do return self + redef fun can_resolve_for(mtype, anchor, mmodule) do return true + + redef fun collect_mclassdefs(mmodule) do return new HashSet[MClassDef] + + redef fun collect_mclasses(mmodule) do return new HashSet[MClass] + + redef fun collect_mtypes(mmodule) do return new HashSet[MClassType] +end + # A VTable contains the virtual method table for the dispatch # and informations to perform subtyping tests class VTable