- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Implementation of SI-64
Sat, 2012-02-04, 21:17
Hi,
I was working on https://issues.scala-lang.org/browse/SI-64 lately, and I would like to get some feedback on my (partial) implementation.
The code can be found at https://github.com/szabolcsberecz/scala/tree/SI-64 (fjbg must be recompiled first)
In short, "def f = synchronized { ... }" is transformed into "<synchronized> def f = ..." if f is not defined in a trait, and the synchronized flag is set for these methods when generating the JVM bytecode. Inlining of these methods is disabled for know. The transformation phase is run just before tailcalls, so that tail call elimination can be done on synchronized methods also.
For a complete implementation, the inliner and GenMSIL needs to be updated. I expect the change to GenMSIL to be as straitforward as in GenJVM, but I can't really judge on the inliner. I know that at least the synchronized flag has to be expanded into bytecode and this expansion must be taken into account when deciding on whether to inline a call or not.
Traits are skipped because of java interoperability. It would be quite easy to make it work by applying the transformation to trait methods also but not setting the synchronized flag in the implementation classes. The forwarder methods in composed classes would still get the synchronized flag, so these implementation methods would be properly synchronized. The problem is that the resulting trait implementation class could not be correctly used from java because of the missing synchronization.
I think the only real benefit is the tail call elimination on synchronized methods, but there is also a small code size reduction (scala-library.jar shrinks by a whooping 1.7k, about 30 bytes per synchronized methods) and some speedup might be gained.
Do you see any problems with the implementation?
Do you think it worths finishing?
Thanks,
Szabolcs
I was working on https://issues.scala-lang.org/browse/SI-64 lately, and I would like to get some feedback on my (partial) implementation.
The code can be found at https://github.com/szabolcsberecz/scala/tree/SI-64 (fjbg must be recompiled first)
In short, "def f = synchronized { ... }" is transformed into "<synchronized> def f = ..." if f is not defined in a trait, and the synchronized flag is set for these methods when generating the JVM bytecode. Inlining of these methods is disabled for know. The transformation phase is run just before tailcalls, so that tail call elimination can be done on synchronized methods also.
For a complete implementation, the inliner and GenMSIL needs to be updated. I expect the change to GenMSIL to be as straitforward as in GenJVM, but I can't really judge on the inliner. I know that at least the synchronized flag has to be expanded into bytecode and this expansion must be taken into account when deciding on whether to inline a call or not.
Traits are skipped because of java interoperability. It would be quite easy to make it work by applying the transformation to trait methods also but not setting the synchronized flag in the implementation classes. The forwarder methods in composed classes would still get the synchronized flag, so these implementation methods would be properly synchronized. The problem is that the resulting trait implementation class could not be correctly used from java because of the missing synchronization.
I think the only real benefit is the tail call elimination on synchronized methods, but there is also a small code size reduction (scala-library.jar shrinks by a whooping 1.7k, about 30 bytes per synchronized methods) and some speedup might be gained.
Do you see any problems with the implementation?
Do you think it worths finishing?
Thanks,
Szabolcs
Sun, 2012-02-05, 14:01
#2
Re: Implementation of SI-64
On Sat, Feb 4, 2012 at 23:09, Paul Phillips <paulp@improving.org> wrote:
On Sat, Feb 4, 2012 at 12:17 PM, Szabolcs Berecz
<szabolcs.berecz@gmail.com> wrote:
> Do you see any problems with the implementation?
A whole flag, a whole phase, and a field in every IMethod is
unreasonably decadent.
I can fix these. An annotation can be used in place of the flag and field, and I guess the phase can be easily merged with tailcalls.
Anything else?
On Sat, Feb 4, 2012 at 12:17 PM, Szabolcs Berecz
wrote:
> Do you see any problems with the implementation?
A whole flag, a whole phase, and a field in every IMethod is
unreasonably decadent.
> Do you think it worths finishing?
I've asked a number of people over the years whether they can say with
any confidence whether it will make any difference speedwise, and so
far I haven't gotten the confident yea/nay I've been hoping for.
Whether it's worth finishing mostly comes down to whether it's
materially faster, something I still don't know.