Rework the reflection cache
The reflection cache is now safer, because we use a hierarchical cache where
the node entries are weakly referenced `Class` instances. Typically the first
level of the cache would be the receiver, while lower levels would be the
argument types. If those types are collected, the weak hash maps that we use
internally would automatically clean the entries. Eventually, the value associated
with this "path" of `Class` itself references a `Method` or a `Constructor`
with additional, computed, data.
The advantage of this approach is that typically for the instantiator case,
we no longer need to match the argument types (`isMatch`) for each call: instead,
we go through the tree using subsequent argument types, and if a match is found,
we know it's the right one.