From: Jean Privat Date: Wed, 26 Mar 2014 18:25:24 +0000 (-0400) Subject: rta: add live_callsites and live_callsites X-Git-Tag: v0.6.5~8^2~2 X-Git-Url: http://nitlanguage.org rta: add live_callsites and live_callsites In a callgraph it is useful to be able to compute the live target of any callsite Signed-off-by: Jean Privat --- diff --git a/src/rapid_type_analysis.nit b/src/rapid_type_analysis.nit index ff72fac..978fab4 100644 --- a/src/rapid_type_analysis.nit +++ b/src/rapid_type_analysis.nit @@ -31,6 +31,8 @@ import auto_super_init import csv # for live_types_to_csv import ordered_tree # for live_methods_to_tree +private import more_collections + redef class ModelBuilder fun do_rapid_type_analysis(mainmodule: MModule): RapidTypeAnalysis do @@ -75,6 +77,36 @@ class RapidTypeAnalysis # Live methods. var live_methods = new HashSet[MMethod] + # Live callsites. + var live_callsites = new HashSet[CallSite] + + private var live_targets_cache = new HashMap2[MType, MProperty, Set[MMethodDef]] + + # The live targets of a specific callsite. + fun live_targets(callsite: CallSite): Set[MMethodDef] + do + var mtype = callsite.recv + var anchor = callsite.anchor + if anchor != null then mtype = mtype.anchor_to(callsite.mmodule, anchor) + if mtype isa MNullableType then mtype = mtype.mtype + assert mtype isa MClassType + mtype = mtype.mclass.intro.bound_mtype + var mproperty = callsite.mproperty + var res = live_targets_cache[mtype, mproperty] + if res != null then return res + res = new ArraySet[MMethodDef] + live_targets_cache[mtype, mproperty] = res + + for c in live_classes do + var tc = c.intro.bound_mtype + if not tc.is_subtype(mainmodule, null, mtype) then continue + var d = mproperty.lookup_first_definition(mainmodule, tc) + res.add d + end + + return res + end + # Live call-to-super. var live_super_sends = new HashSet[MMethodDef] @@ -442,7 +474,10 @@ class RapidTypeVisitor fun add_cast_type(mtype: MType) do analysis.add_cast(mtype) - fun add_callsite(callsite: nullable CallSite) do if callsite != null then analysis.add_send(callsite.recv, callsite.mproperty) + fun add_callsite(callsite: nullable CallSite) do if callsite != null then + analysis.add_send(callsite.recv, callsite.mproperty) + analysis.live_callsites.add(callsite) + end end ###