X-Git-Url: http://nitlanguage.org diff --git a/src/vm.nit b/src/vm.nit index 53a99fa..b253533 100644 --- a/src/vm.nit +++ b/src/vm.nit @@ -18,11 +18,10 @@ module vm import interpreter::naive_interpreter -import model_utils import perfect_hashing redef class ModelBuilder - redef fun run_naive_interpreter(mainmodule: MModule, arguments: Array[String]) + fun run_virtual_machine(mainmodule: MModule, arguments: Array[String]) do var time0 = get_time self.toolcontext.info("*** NITVM STARTING ***", 1) @@ -132,7 +131,10 @@ class VirtualMachine super NaiveInterpreter end # Subtyping test with perfect hashing - private fun inter_is_subtype_ph(id: Int, mask:Int, vtable: Pointer): Bool `{ + # * `id` is the identifier of the target class + # * `mask` is the perfect hashing mask of the receiver class + # * `vtable` is the pointer to the virtual table of the receiver class + fun inter_is_subtype_ph(id: Int, mask:Int, vtable: Pointer): Bool `{ // hv is the position in hashtable int hv = id & mask; @@ -144,7 +146,10 @@ class VirtualMachine super NaiveInterpreter `} # Subtyping test with Cohen test (direct access) - private fun inter_is_subtype_sst(id: Int, position: Int, vtable: Pointer): Bool `{ + # * `id` is the identifier of the target class + # * `mask` is the absolute position of the target identifier in the virtual table + # * `vtable` is the pointer to the virtual table of the receiver class + fun inter_is_subtype_sst(id: Int, position: Int, vtable: Pointer): Bool `{ // Direct access to the position given in parameter int tableid = (long unsigned int)((long int *)vtable)[position]; @@ -160,7 +165,7 @@ class VirtualMachine super NaiveInterpreter assert recv isa MutableInstance - recv.internal_attributes = init_internal_attributes(initialization_value, recv.mtype.as(MClassType).mclass.all_mattributes(mainmodule, none_visibility).length) + recv.internal_attributes = init_internal_attributes(initialization_value, recv.mtype.as(MClassType).mclass.mattributes.length) super end @@ -225,8 +230,12 @@ class VirtualMachine super NaiveInterpreter end end - # Execute a method dispatch with perfect hashing - private fun method_dispatch_ph(vtable: Pointer, mask: Int, id: Int, offset: Int): MMethodDef `{ + # Execute a method dispatch with perfect hashing and return the appropriate `MMethodDef` + # * `vtable` Pointer to the internal virtual table of the class + # * `mask` Perfect hashing mask of the receiver class + # * `id` Identifier of the class which introduce the method + # * `offset` Relative offset of the method from the beginning of the block + fun method_dispatch_ph(vtable: Pointer, mask: Int, id: Int, offset: Int): MMethodDef `{ // Perfect hashing position int hv = mask & id; long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]); @@ -239,9 +248,9 @@ class VirtualMachine super NaiveInterpreter `} # Execute a method dispatch with direct access and return the appropriate `MMethodDef` - # `vtable` : Pointer to the internal pointer of the class - # `absolute_offset` : Absolute offset from the beginning of the virtual table - private fun method_dispatch_sst(vtable: Pointer, absolute_offset: Int): MMethodDef `{ + # * `vtable` Pointer to the internal virtual table of the class + # * `absolute_offset` Absolute offset from the beginning of the virtual table + fun method_dispatch_sst(vtable: Pointer, absolute_offset: Int): MMethodDef `{ // pointer+2 is the position where methods are // Add the offset of property and get the method implementation MMethodDef propdef = (MMethodDef)((long int *)vtable)[absolute_offset]; @@ -282,7 +291,7 @@ class VirtualMachine super NaiveInterpreter # * `mask` is the perfect hashing mask of the class # * `id` is the identifier of the class # * `offset` is the relative offset of this attribute - private fun read_attribute_ph(instance: Pointer, vtable: Pointer, mask: Int, id: Int, offset: Int): Instance `{ + fun read_attribute_ph(instance: Pointer, vtable: Pointer, mask: Int, id: Int, offset: Int): Instance `{ // Perfect hashing position int hv = mask & id; long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]); @@ -298,7 +307,7 @@ class VirtualMachine super NaiveInterpreter # Return the attribute value in `instance` with a direct access (SST) # * `instance` is the attributes array of the receiver # * `offset` is the absolute offset of this attribute - private fun read_attribute_sst(instance: Pointer, offset: Int): Instance `{ + fun read_attribute_sst(instance: Pointer, offset: Int): Instance `{ /* We can make a direct access to the attribute value because this attribute is always at the same position for the class of this receiver */ @@ -332,7 +341,7 @@ class VirtualMachine super NaiveInterpreter # * `id` is the identifier of the class # * `offset` is the relative offset of this attribute # * `value` is the new value for this attribute - private fun write_attribute_ph(instance: Pointer, vtable: Pointer, mask: Int, id: Int, offset: Int, value: Instance) `{ + fun write_attribute_ph(instance: Pointer, vtable: Pointer, mask: Int, id: Int, offset: Int, value: Instance) `{ // Perfect hashing position int hv = mask & id; long unsigned int *pointer = (long unsigned int*)(((long int *)vtable)[-hv]); @@ -348,7 +357,7 @@ class VirtualMachine super NaiveInterpreter # * `instance` is the attributes array of the receiver # * `offset` is the absolute offset of this attribute # * `value` is the new value for this attribute - private fun write_attribute_sst(instance: Pointer, offset: Int, value: Instance) `{ + fun write_attribute_sst(instance: Pointer, offset: Int, value: Instance) `{ // Direct access to the position with the absolute offset ((Instance *)instance)[offset] = value; Instance_incr_ref(value); @@ -389,6 +398,18 @@ redef class MClass # introduced by self class in the vtable var positions_methods: HashMap[MClass, Int] = new HashMap[MClass, Int] + # The `MAttribute` this class introduced + var intro_mattributes = new Array[MAttribute] + + # The `MMethod` this class introduced + var intro_mmethods = new Array[MMethod] + + # All `MAttribute` this class contains + var mattributes = new Array[MAttribute] + + # All `MMethod` this class contains + var mmethods = new Array[MMethod] + # Allocates a VTable for this class and gives it an id private fun make_vt(v: VirtualMachine) do @@ -418,13 +439,12 @@ redef class MClass if not parent.loaded then parent.make_vt(v) # Get the number of introduced methods and attributes for this class - var methods = 0 - var attributes = 0 + var methods = parent.intro_mmethods.length + var attributes = parent.intro_mattributes.length - for p in parent.intro_mproperties(none_visibility) do - if p isa MMethod then methods += 1 - if p isa MAttribute then attributes += 1 - end + # Updates `mmethods` and `mattributes` + mmethods.add_all(parent.intro_mmethods) + mattributes.add_all(parent.intro_mattributes) ids.push(parent.vtable.id) nb_methods.push(methods) @@ -490,21 +510,36 @@ redef class MClass # Fixing offsets for self attributes and methods var relative_offset_attr = 0 var relative_offset_meth = 0 - for p in intro_mproperties(none_visibility) do - if p isa MMethod then - self_methods += 1 - p.offset = relative_offset_meth - p.absolute_offset = offset_methods + relative_offset_meth - relative_offset_meth += 1 - end - if p isa MAttribute then - nb_introduced_attributes += 1 - p.offset = relative_offset_attr - p.absolute_offset = offset_attributes + relative_offset_attr - relative_offset_attr += 1 + + # Update `intro_mmethods` and `intro_mattributes` + # For each MClassdef this MClass has + for classdef in mclassdefs do + # For each property this MClassdef introduce + for p in classdef.intro_mproperties do + # Collect properties and fixing offsets + if p isa MMethod then + self_methods += 1 + p.offset = relative_offset_meth + p.absolute_offset = offset_methods + relative_offset_meth + relative_offset_meth += 1 + + intro_mmethods.add(p) + end + if p isa MAttribute then + nb_introduced_attributes += 1 + p.offset = relative_offset_attr + p.absolute_offset = offset_attributes + relative_offset_attr + relative_offset_attr += 1 + + intro_mattributes.add(p) + end end end + # Updates caches with introduced attributes of `self` class + mattributes.add_all(intro_mattributes) + mmethods.add_all(intro_mmethods) + nb_methods_total.add_all(nb_methods) nb_methods_total.push(self_methods) @@ -525,12 +560,10 @@ redef class MClass private fun fill_vtable(v:VirtualMachine, table: VTable, cl: MClass) do var methods = new Array[MMethodDef] - for m in cl.intro_mproperties(none_visibility) do - if m isa MMethod then - # `propdef` is the most specific implementation for this MMethod - var propdef = m.lookup_first_definition(v.mainmodule, self.intro.bound_mtype) - methods.push(propdef) - end + for m in cl.intro_mmethods do + # `propdef` is the most specific implementation for this MMethod + var propdef = m.lookup_first_definition(v.mainmodule, self.intro.bound_mtype) + methods.push(propdef) end # Call a method in C to put propdefs of self methods in the vtables @@ -593,7 +626,7 @@ redef class MClass 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 + var properties_length = cl.mmethods.length + cl.mattributes.length if properties_length > max then max = properties_length prefix = cl