-
Notifications
You must be signed in to change notification settings - Fork 14
Consider eliminating static accessors for trait methods #228
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
Comments
cc @retronym @adriaanm @DarkDimius - let me know what you think. I'll also prepare a comparison of |
What about cases like: class C { def foo = "C" }
trait T extends C { override def foo = "T" }
class D extends C { override def foo = "D" }
class E extends D with T { super[T].foo } AFAICT we'd need to outlaw that |
No, this works as expected:
Method lookup for invokespecial only starts at the superclass if the receiver in the instruction is one of the superclasses of the current class. Here we get |
We decided to keep static accessors. Still to do: run compiler benchmarks combinations of
In particular, if we enable have both
gives
|
So, maybe it's better not to enable |
Preparing my scala world talk, I realized that the solution we currently have for emitting super calls to trait members is possibly not the best trade-off.
In RC1, for every non-private trait method (except
$init$
, which is a static method only), we emit a static method that forwards to the default method. This is to support arbitrary super calls. This was originally added in scala/scala#5177.At the time, we were still emitting mixin forwarders for every method that a class inherits from a trait (corresponding to
-Xmixin-force-forwarders:true
in RC1). This resulted in a large number of super calls to trait methods that were implemented usinginvokespecial
, which required adding the interface class as a direct parent to the class. The new scheme (using the static accessors) significantly reduced the number of implemented interfaces, which (hopefully) had a good effect on performance: Jason observed that adding redundant interfaces increases the class loading time significantly (#98 (comment)).However, three things have changed in the meantime:
$init$
methods are always emitted static, so they can always be invoked without adding the interface as direct parent. This was different at the time (they were instance methods).invokespecial
call.Example for the last point:
Here, emitting
invokespecial U.f
is correct, we don't need to addT
as a direct parent ofC
.For comparison, here's an example where adding an interface as parent is required:
The generated mixin forwarder in
C
invokesT2.f
. Usinginvokespecial U.f
would not work, asU
inherits two implementations forf
from two interfaces where none is a subtype of the other. So we need to addT2
toC
s interfaces.To get some numbers, I went ahead and eliminated the static accessors, and re-introduced the logic to add additional interfaces to classfiles. The numbers confirm my expectations (adding an interface is rare) for the compiler codebase, not so much for the library because of the collection library's extremely deep inheritance hierarchy. Some numbers:
Meanings:
invokespecial U.hashCode
whereU
is not the interface holding the definition ofhashCode
(but a parent interface ofU
) would resolve toObject.hashCode
. So we have to add the actual interface as parent.minimizeParents
.The data is here: https://1drv.ms/x/s!AgqXX83j_zSUcYDOIFgboc_L7G8
I also compiled everything with
-Xmixin-force-forwarders:true
, here's the data for this case:Observations
-Xmixin-force-forwarders:true
) can be implemented using a "rewrite" to an existing direct parent interfaceWIP branch here: https://github.com/scala/scala/compare/2.12.0...lrytz:traitSuperAccessors?expand=1. Note that it contains the
println
s to get the statistics summarized above.Another note: if we re-introduce to logic to add additional interfaces to classes, we can lift the current restriction on super calls to java-defined default methods.
The text was updated successfully, but these errors were encountered: