-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Allocate fewer TypeMaps and TypeAccumulators #9618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
test performance please |
performance test scheduled: 17 job(s) in queue, 1 running. |
Performance test finished successfully: Visit http://dotty-bench.epfl.ch/9618/ to see the changes. Benchmarks is based on merging with master (387c562) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
def foldArgs(x: T, args: List[Type]): T = args match | ||
case arg :: rest => foldArgs(op(x, arg), rest) | ||
case nil => x | ||
foldArgs(op(x, tycon), args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In map
and fold
, do we need to recurse on typcon
? The semantics is quite different from TypeMap
and TypeAccumulator
, and is specific to Substituters
. Maybe add a note here to avoid misuse?
} | ||
|
||
final class SubstThisMap(from: ClassSymbol, to: Type)(using Context) extends DeepTypeMap { | ||
def apply(tp: Type): Type = substThis(tp, from, to, this) | ||
def apply(tp: Type): Type = substThis(tp, from, to, this)(using mapCtx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it mean all classes that inherit TypeMap
(e.g. DeepTypeMap
, ApproximatingTypeMap
and AsSeenFromMap
) have to write using mapCtx
explicitly everywhere?
There's something problematic going on here. TypeMaps usually take a context as a parameter, which becomes a private parameter acessor field. That parameter shadows the mapCtx field inherited from TypeMap. `mapCtx` is a variable that is temporarily mutated when mapping LazyRefs. But since it is shadowed, such mutations do not affect code that is defined in the subclass of TypeMap. One fix is to explicitly pass mapCtx to all code that is called from the maps. That's what's done here for substituters. There might be other solutions as well, which have to be tried out.
Delay allocation of TypeMap and TypeAccumulators by handling common cases directly
before doing an allocation. The biggest win is handling AppliedTypes directly. This risks
creating more than one map instance, since function part and every argument might
in the end require a map. But looking at stats shows that the benefits largely outweigh
the costs.