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
# 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]
return tree
end
- # Methods that are are still candidate to the try_send
+ # Methods that are still candidate to the try_send
private var totry_methods = new HashSet[MMethod]
+ # Methods that are or were candidate to the try_send
+ # Used to ensure that try_send is only used once
+ private var try_methods = new HashSet[MMethod]
+
# The method definitions that remain to visit
private var todo = new List[MMethodDef]
fun add_send(recv: MType, mproperty: MMethod)
do
- if live_methods.has(mproperty) then return
+ if try_methods.has(mproperty) then return
#print "new prop: {mproperty}"
live_methods.add(mproperty)
+ try_methods.add(mproperty)
if mproperty.mpropdefs.length == 1 then
# If there is only one definition, just add the definition and do not try again the property
var d = mproperty.mpropdefs.first
fun add_type(mtype: MClassType) do analysis.add_new(receiver, mtype)
- fun add_monomorphic_send(mtype: MType, mproperty: MMethod) do analysis.try_send(mtype.as(MClassType), mproperty)
+ fun add_monomorphic_send(mtype: MType, mproperty: MMethod)
+ do
+ analysis.live_methods.add(mproperty)
+ analysis.try_send(mtype.as(MClassType), mproperty)
+ end
fun add_send(mtype: MType, mproperty: MMethod) do analysis.add_send(mtype, mproperty)
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
###
do
var mtype = self.mtype.as(MClassType)
v.add_type(mtype)
- var prop = v.get_method(mtype, "init")
- v.add_monomorphic_send(mtype, prop)
+ v.add_callsite(init_callsite)
end
end
do
var mtype = self.mtype.as(MClassType)
v.add_type(mtype)
- var prop = v.get_method(mtype, "without_last")
- v.add_monomorphic_send(mtype, prop)
+ v.add_callsite(init_callsite)
end
end