rta: rename and document runtime_type.nit
authorJean Privat <jean@pryen.org>
Mon, 23 Apr 2012 14:06:48 +0000 (10:06 -0400)
committerJean Privat <jean@pryen.org>
Wed, 25 Apr 2012 21:32:03 +0000 (17:32 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/nitstats.nit
src/rapid_type_analysis.nit [moved from src/runtime_type.nit with 72% similarity]

index 5e0c5e5..357d8d1 100644 (file)
@@ -25,7 +25,7 @@ module nitstats
 
 import modelbuilder
 import exprbuilder
-import runtime_type
+import rapid_type_analysis
 
 # The job of this visitor is to resolve all types found
 class ATypeCounterVisitor
@@ -515,28 +515,17 @@ end
 
 fun runtime_type(modelbuilder: ModelBuilder, mainmodule: MModule)
 do
-       var analysis = modelbuilder.do_runtime_type(mainmodule)
+       var analysis = modelbuilder.do_rapid_type_analysis(mainmodule)
 
        print "--- Type Analysis ---"
        print "Number of live runtime types (instantied resolved type): {analysis.live_types.length}"
        if analysis.live_types.length < 8 then print "\t{analysis.live_types.join(" ")}"
-       print "Number of live polymorphic method: {analysis.polymorphic_methods.length}"
-       if analysis.polymorphic_methods.length < 8 then print "\t{analysis.polymorphic_methods.join(" ")}"
        print "Number of live method definitions: {analysis.live_methoddefs.length}"
        if analysis.live_methoddefs.length < 8 then print "\t{analysis.live_methoddefs.join(" ")}"
-       print "Number of live runtime method definitions (with customization): {analysis.runtime_methods.length}"
-       if analysis.runtime_methods.length < 8 then print "\t{analysis.runtime_methods.join(" ")}"
+       print "Number of live customized method definitions: {analysis.live_customized_methoddefs.length}"
+       if analysis.live_customized_methoddefs.length < 8 then print "\t{analysis.live_customized_methoddefs.join(" ")}"
        print "Number of live runtime cast types (ie used in as and isa): {analysis.live_cast_types.length}"
        if analysis.live_cast_types.length < 8 then print "\t{analysis.live_cast_types.join(" ")}"
-
-       for mprop in modelbuilder.model.mproperties do
-               if not mprop isa MMethod then continue
-               if analysis.polymorphic_methods.has(mprop) then continue
-               for methoddef in mprop.mpropdefs do
-                       if analysis.live_methoddefs.has(methoddef) then continue label l
-               end
-               #print "  {mprop.full_name} is dead"
-       end label l
 end
 
 # Create a tool context to handle options and paths
similarity index 72%
rename from src/runtime_type.nit
rename to src/rapid_type_analysis.nit
index 830a86d..3655ffd 100644 (file)
 # It is quite efficient but the type set is global and pollutes each call site.
 #
 # Heterogenous generics means that each intancied generic class is associated
-# to a distinct runtime type.
+# to a distinct rapid type.
 # Heterogenous generics has the advantage to resolve the formal generic
 # parameters types but increase the number of types.
-# More important, heterogenous generics cannot deal with infinite number of runtime
+# More important, heterogenous generics cannot deal with infinite number of rapid
 # types since the analyse tries to list them all (so some programs will be badly refused)
 #
-# Customization means that each method definition is analyzed one per runtime
+# Customization means that each method definition is analyzed one per rapid
 # type of receiver.
 # Customization have the following advantages:
 #  * `self' is monomorphic
 #  * virtual types are all resolved
 #  * live attributes can be determined on each class
-# But has the disadvantage to explode the number of runtime method: each method
-# definition for each runtime type that need it
-module runtime_type
+# But has the disadvantage to explode the number of rapid method: each method
+# definition for each rapid type that need it
+module rapid_type_analysis
 
 import model
 import modelbuilder
@@ -51,10 +51,10 @@ redef class MModule
 end
 
 redef class ModelBuilder
-       fun do_runtime_type(mainmodule: MModule): RuntimeTypeAnalysis
+       fun do_rapid_type_analysis(mainmodule: MModule): RapidTypeAnalysis
        do
                var model = self.model
-               var analysis = new RuntimeTypeAnalysis(self, mainmodule)
+               var analysis = new RapidTypeAnalysis(self, mainmodule)
                var nmodule = self.nmodules.first
                var mainclass = self.try_get_mclass_by_name(nmodule, mainmodule, "Sys")
                if mainclass == null then return analysis # No entry point
@@ -78,20 +78,47 @@ redef class ModelBuilder
        end
 end
 
-# RuntimeTypeAnalysis looks for alive runtime types in application.
+# RapidTypeAnalysis looks for alive rapid types in application.
 # The entry point of the analysis is the mainmodule of the application.
-class RuntimeTypeAnalysis
+class RapidTypeAnalysis
+       # The modelbuilder used to get the AST.
        var modelbuilder: ModelBuilder
+
+       # The main module of the analysis.
+       # Used to perform types operations.
        var mainmodule: MModule
+
+       # The pool to live types.
+       # During the analysis, new types are added and combined with
+       # live_send_sites to determine new customized_methoddefs to visit
        var live_types: HashSet[MClassType] = new HashSet[MClassType]
+
+       # The pool of types used to perform type checks (isa and as).
        var live_cast_types: HashSet[MClassType] = new HashSet[MClassType]
-       var polymorphic_methods: HashSet[MMethod] = new HashSet[MMethod]
+
+       # Live method definitions.
+       # These method definitions are:
+       #  * visited trough a add_send on an already known live_type
+       #  * visited trough a add_type for an already known live_send_sites
+       #  * visided by a add_monomorphic_send or a add_static_call
        var live_methoddefs: HashSet[MMethodDef] = new HashSet[MMethodDef]
-       var runtime_methods: HashSet[RuntimeMethod] = new HashSet[RuntimeMethod]
-       var live_send_site: HashSet[RuntimeSendSite] = new HashSet[RuntimeSendSite]
 
-       private var todo: List[RuntimeMethod] = new List[RuntimeMethod]
+       # The pool of live customized method definitions
+       var live_customized_methoddefs: HashSet[CustomizedMethodDef] = new HashSet[CustomizedMethodDef]
 
+       # The pool of live RTA send site
+       # During the analysis, new live_send_sites are added and combined with
+       # live_types to determine new live_customized_methoddefs to visit
+       var live_send_sites: HashSet[RTASendSite] = new HashSet[RTASendSite]
+
+       # The customized method definitions that remain to visit
+       private var todo: List[CustomizedMethodDef] = new List[CustomizedMethodDef]
+
+       # Add a live type to the pool
+       #
+       # If the types is already live, then do nothing.
+       #
+       # REQUIRE: not mtype.need_anchor
        fun add_type(mtype: MClassType)
        do
                if self.live_types.has(mtype) then return
@@ -107,13 +134,12 @@ class RuntimeTypeAnalysis
                                if not npropdef isa AAttrPropdef then continue
                                var nexpr = npropdef.n_expr
                                if nexpr == null then continue
-                               var v = new RuntimeTypeVisitor(self, nclassdef, npropdef.mpropdef.as(not null), mtype)
+                               var v = new RapidTypeVisitor(self, nclassdef, npropdef.mpropdef.as(not null), mtype)
                                v.enter_visit(nexpr)
                        end
                end
 
-
-               for rss in self.live_send_site do
+               for rss in self.live_send_sites do
                        if not mtype.is_subtype(self.mainmodule, null, rss.receiver) then continue
                        if mtype.has_mproperty(self.mainmodule, rss.mmethod) then
                                self.add_monomorphic_send(mtype, rss.mmethod)
@@ -121,13 +147,15 @@ class RuntimeTypeAnalysis
                end
        end
 
+       # Add a send site to the pool
+       #
+       # If the send site is already live, then do nothing.
        fun add_send(mtype: MClassType, mmethod: MMethod)
        do
-               var rss = new RuntimeSendSite(mmethod, mtype)
-               if self.live_send_site.has(rss) then return
+               var rss = new RTASendSite(mmethod, mtype)
+               if self.live_send_sites.has(rss) then return
 
-               self.live_send_site.add(rss)
-               self.polymorphic_methods.add(mmethod)
+               self.live_send_sites.add(rss)
 
                for mtype2 in self.live_types do
                        if not mtype2.is_subtype(self.mainmodule, null, mtype) then continue
@@ -137,6 +165,10 @@ class RuntimeTypeAnalysis
                end
        end
 
+       # Add a monomoprhic send.
+       # The send site is not added to the pool.
+       # The method just determine the associated method definition then
+       # performs a static_call
        fun add_monomorphic_send(mtype: MClassType, mmethod: MMethod)
        do
                assert self.live_types.has(mtype)
@@ -146,16 +178,19 @@ class RuntimeTypeAnalysis
                self.add_static_call(mtype, defs.first)
        end
 
+       # Add a customized_methoddefs to the pool
+       # Is the customized_methoddefs is already live, then do nothing
        fun add_static_call(mtype: MClassType, mmethoddef: MMethodDef)
        do
                assert self.live_types.has(mtype)
-               var rm = new RuntimeMethod(mmethoddef, mtype)
-               if self.runtime_methods.has(rm) then return
-               self.runtime_methods.add(rm)
+               var rm = new CustomizedMethodDef(mmethoddef, mtype)
+               if self.live_customized_methoddefs.has(rm) then return
+               self.live_customized_methoddefs.add(rm)
                self.todo.add(rm)
                self.live_methoddefs.add(mmethoddef)
        end
 
+       # Add mtype to the cast pool.
        fun add_cast_type(mtype: MClassType)
        do
                if self.live_cast_types.has(mtype) then return
@@ -164,7 +199,7 @@ class RuntimeTypeAnalysis
                self.live_cast_types.add(mtype)
        end
 
-       # Start the analysis.
+       # Run the analysis until all visitable method definitions are visited.
        fun run_analysis
        do
                # Force Bool
@@ -201,7 +236,7 @@ class RuntimeTypeAnalysis
                                                self.add_monomorphic_send(mr.receiver, auto_super_init)
                                        end
                                end
-                               var v = new RuntimeTypeVisitor(self, nclassdef, mmethoddef, mr.receiver)
+                               var v = new RapidTypeVisitor(self, nclassdef, mmethoddef, mr.receiver)
                                v.enter_visit(npropdef.n_block)
                        else if npropdef isa ADeferredMethPropdef then
                                # nothing to do (maybe add a waring?)
@@ -224,7 +259,8 @@ class RuntimeTypeAnalysis
        end
 end
 
-class RuntimeMethod
+# A method definitions customized to a specific receiver
+class CustomizedMethodDef
        var mmethoddef: MMethodDef
        var receiver: MClassType
 
@@ -235,7 +271,7 @@ class RuntimeMethod
 
        redef fun ==(o)
        do
-               return o isa RuntimeMethod and o.mmethoddef == self.mmethoddef and o.receiver == self.receiver
+               return o isa CustomizedMethodDef and o.mmethoddef == self.mmethoddef and o.receiver == self.receiver
        end
 
        redef fun hash
@@ -244,13 +280,14 @@ class RuntimeMethod
        end
 end
 
-class RuntimeSendSite
+# A method invokation site bounded by a specific receiver
+class RTASendSite
        var mmethod: MMethod
        var receiver: MClassType
 
        redef fun ==(o)
        do
-               return o isa RuntimeSendSite and o.mmethod == self.mmethod and o.receiver == self.receiver
+               return o isa RTASendSite and o.mmethod == self.mmethod and o.receiver == self.receiver
        end
 
        redef fun hash
@@ -259,10 +296,10 @@ class RuntimeSendSite
        end
 end
 
-private class RuntimeTypeVisitor
+private class RapidTypeVisitor
        super Visitor
 
-       var analysis: RuntimeTypeAnalysis
+       var analysis: RapidTypeAnalysis
 
        var nclassdef: AClassdef
 
@@ -270,7 +307,7 @@ private class RuntimeTypeVisitor
 
        var receiver: MClassType
 
-       init(analysis: RuntimeTypeAnalysis, nclassdef: AClassdef, mpropdef: MPropDef, receiver: MClassType)
+       init(analysis: RapidTypeAnalysis, nclassdef: AClassdef, mpropdef: MPropDef, receiver: MClassType)
        do
                self.analysis = analysis
                self.nclassdef = nclassdef
@@ -292,44 +329,44 @@ private class RuntimeTypeVisitor
 
        fun add_type(mtype: MType)
        do
-               var runtimetype = cleanup_type(mtype)
-               if runtimetype == null then return # we do not care about null
+               var rapidtype = cleanup_type(mtype)
+               if rapidtype == null then return # we do not care about null
 
-               self.analysis.add_type(runtimetype)
-               #self.current_node.debug("add_type {runtimetype}")
+               self.analysis.add_type(rapidtype)
+               #self.current_node.debug("add_type {rapidtype}")
        end
 
        fun add_send(mtype: MType, mproperty: MMethod)
        do
-               var runtimetype = cleanup_type(mtype)
-               if runtimetype == null then return # we do not care about null
+               var rapidtype = cleanup_type(mtype)
+               if rapidtype == null then return # we do not care about null
 
-               analysis.add_send(runtimetype, mproperty)
+               analysis.add_send(rapidtype, mproperty)
                #self.current_node.debug("add_send {mproperty}")
        end
 
        fun add_monomorphic_send(mtype: MType, mproperty: MMethod)
        do
-               var runtimetype = cleanup_type(mtype)
-               if runtimetype == null then return # we do not care about null
+               var rapidtype = cleanup_type(mtype)
+               if rapidtype == null then return # we do not care about null
 
-               self.analysis.add_monomorphic_send(runtimetype, mproperty)
-               #self.current_node.debug("add_static call {runtimetype} {mproperty}")
+               self.analysis.add_monomorphic_send(rapidtype, mproperty)
+               #self.current_node.debug("add_monomorphic_send {rapidtype} {mproperty}")
        end
 
        fun add_cast_type(mtype: MType)
        do
-               var runtimetype = cleanup_type(mtype)
-               if runtimetype == null then return # we do not care about null
+               var rapidtype = cleanup_type(mtype)
+               if rapidtype == null then return # we do not care about null
 
-               self.analysis.add_cast_type(runtimetype)
-               #self.current_node.debug("add_cast_type {runtimetype}")
+               self.analysis.add_cast_type(rapidtype)
+               #self.current_node.debug("add_cast_type {rapidtype}")
        end
 
        redef fun visit(node)
        do
                if node == null then return
-               node.accept_runtime_type_vistor(self)
+               node.accept_rapid_type_vistor(self)
                node.visit_all(self)
        end
 
@@ -354,19 +391,19 @@ private class RuntimeTypeVisitor
        # Force to get the primitive property named `name' in the instance `recv' or abort
        fun get_method(recv: MType, name: String): MMethod
        do
-               var runtimetype = cleanup_type(recv)
-               if runtimetype == null then abort
+               var rapidtype = cleanup_type(recv)
+               if rapidtype == null then abort
 
                var props = self.analysis.mainmodule.model.get_mproperties_by_name(name)
                if props == null then
-                       self.current_node.debug("Fatal Error: no primitive property {name} on {runtimetype}")
+                       self.current_node.debug("Fatal Error: no primitive property {name} on {rapidtype}")
                        abort
                end
                var res: nullable MMethod = null
                for mprop in props do
                        assert mprop isa MMethod
-                       if not runtimetype.has_mproperty(self.analysis.mainmodule, mprop) then continue
-                       if mprop.is_init and mprop.intro_mclassdef.mclass != runtimetype.mclass then continue
+                       if not rapidtype.has_mproperty(self.analysis.mainmodule, mprop) then continue
+                       if mprop.is_init and mprop.intro_mclassdef.mclass != rapidtype.mclass then continue
                        if res == null then
                                res = mprop
                        else
@@ -375,7 +412,7 @@ private class RuntimeTypeVisitor
                        end
                end
                if res == null then
-                       self.current_node.debug("Fatal Error: no primitive property {name} on {runtimetype}")
+                       self.current_node.debug("Fatal Error: no primitive property {name} on {rapidtype}")
                        abort
                end
                return res
@@ -385,34 +422,34 @@ end
 ###
 
 redef class ANode
-       private fun accept_runtime_type_vistor(v: RuntimeTypeVisitor)
+       private fun accept_rapid_type_vistor(v: RapidTypeVisitor)
        do
        end
 end
 
 redef class AIntExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_type(self.mtype.as(not null))
        end
 end
 
 redef class AFloatExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_type(self.mtype.as(not null))
        end
 end
 
 redef class ACharExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_type(self.mtype.as(not null))
        end
 end
 
 redef class AArrayExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var mtype = self.mtype.as(not null)
                v.add_type(mtype)
@@ -424,7 +461,7 @@ redef class AArrayExpr
 end
 
 redef class AStringFormExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var mtype = self.mtype.as(not null)
                v.add_type(mtype)
@@ -436,7 +473,7 @@ redef class AStringFormExpr
 end
 
 redef class ASuperstringExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var arraytype = v.get_class("Array").get_mtype([v.get_class("Object").mclass_type])
                v.add_type(arraytype)
@@ -447,7 +484,7 @@ redef class ASuperstringExpr
 end
 
 redef class ACrangeExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var mtype = self.mtype.as(not null)
                v.add_type(mtype)
@@ -457,7 +494,7 @@ redef class ACrangeExpr
 end
 
 redef class AOrangeExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var mtype = self.mtype.as(not null)
                v.add_type(mtype)
@@ -467,28 +504,28 @@ redef class AOrangeExpr
 end
 
 redef class ATrueExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_type(self.mtype.as(not null))
        end
 end
 
 redef class AFalseExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_type(self.mtype.as(not null))
        end
 end
 
 redef class AIsaExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_cast_type(self.cast_type.as(not null))
        end
 end
 
 redef class AAsCastExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_cast_type(self.mtype.as(not null))
        end
@@ -497,7 +534,7 @@ end
 #
 
 redef class ASendExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var mproperty = self.mproperty.as(not null)
                if n_expr isa ASelfExpr then
@@ -510,7 +547,7 @@ redef class ASendExpr
 end
 
 redef class ASendReassignFormExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_send(self.read_type.as(not null), self.reassign_property.mproperty)
                var mproperty = self.mproperty.as(not null)
@@ -527,21 +564,21 @@ redef class ASendReassignFormExpr
 end
 
 redef class AVarReassignExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_send(self.read_type.as(not null), self.reassign_property.mproperty)
        end
 end
 
 redef class AAttrReassignExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                v.add_send(self.read_type.as(not null), self.reassign_property.mproperty)
        end
 end
 
 redef class ASuperExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var mproperty = self.mproperty
                if mproperty != null then
@@ -562,7 +599,7 @@ redef class ASuperExpr
 end
 
 redef class AForExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var recvtype = self.n_expr.mtype.as(not null)
                var colltype = v.get_class("Collection").mclassdefs.first.bound_mtype
@@ -576,7 +613,7 @@ redef class AForExpr
 end
 
 redef class ANewExpr
-       redef fun accept_runtime_type_vistor(v)
+       redef fun accept_rapid_type_vistor(v)
        do
                var recvtype = self.mtype.as(not null)
                v.add_type(recvtype)