- # The customized method definitions that remain to visit
- private var todo: List[CustomizedMethodDef] = new List[CustomizedMethodDef]
-
- # Adapt and remove nullable
- # return null if we got the null type
- fun cleanup_type(mtype: MType, recvtype: MClassType): nullable MClassType
- do
- mtype = mtype.anchor_to(self.mainmodule, recvtype)
- if mtype isa MNullType then return null
- if mtype isa MNullableType then mtype = mtype.mtype
- assert mtype isa MClassType
- assert not mtype.need_anchor
- return mtype
- end
-
- # 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
-
- assert not mtype.need_anchor
- self.live_types.add(mtype)
- self.check_depth(mtype)
-
- self.live_classes.add(mtype.mclass)
-
- # Collect default attributes
- for cd in mtype.collect_mclassdefs(self.mainmodule)
- do
- var nclassdef = self.modelbuilder.mclassdef2nclassdef[cd]
- for npropdef in nclassdef.n_propdefs do
- if not npropdef isa AAttrPropdef then continue
- var nexpr = npropdef.n_expr
- if nexpr == null then continue
- var v = new RapidTypeVisitor(self, nclassdef, npropdef.mpropdef.as(not null), mtype)
- v.enter_visit(nexpr)
- end
+ # Live method definitions.
+ var live_methoddefs = new HashSet[MMethodDef]
+
+ # 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)
+ mtype = mtype.undecorate
+ if mtype isa MClassType then 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