Skip to content

Cache classloaders in Splicer #4235

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

Merged

Conversation

nicolasstucki
Copy link
Contributor

No description provided.

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

performance test scheduled: 1 job(s) in queue, 0 running.

@nicolasstucki
Copy link
Contributor Author

While inlining 1000 times power(1000, 5.0) from power-macro/Macro1.scala, the ReifyQuotes phase became 2X faster.

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4235/ to see the changes.

Benchmarks is based on merging with master (14187e2)

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

performance test scheduled: 1 job(s) in queue, 0 running.

@@ -93,6 +93,8 @@ object Splicer {
}
}

private val classLoaders = scala.collection.mutable.HashMap.empty[String, URLClassLoader]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means the cache is going to be shared by all compiler runs? I'm not sure about the following:

  • concurrency
  • memory leak
  • setting changes between runs

I'm not familiar with these areas, could you explain?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concurrency should not be an issue. In the worst case, we create two different classloaders for the same classpath. Which is already happening now, hence the performance.

There is a potential memory leak as classloaders will be cached indefinitely. Maybe I could make it a sized cache that drops the oldest elements if it overflows. Or, maybe use a weak map.

Maybe I should invalidate the cache if the run has changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the Splicer to a class and instantiate one per run to avoid the issues above.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not to share s.c.m.HashMap between threads without synchronization.

I'm thinking about using a timed cache in Scalac to deal with the leak problem (keep the loader around for X seconds after last use).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other issue with caching classloaders is having a good plan for invalidating them when JARs and directories on disk change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the cache is only valid during one phase of one run of the compiler. None of these should be an issue.

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

performance test scheduled: 3 job(s) in queue, 1 running.

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4235/ to see the changes.

Benchmarks is based on merging with master (14187e2)

@@ -21,9 +21,11 @@ import dotty.tools.dotc.util.Positions.Position
import scala.reflect.ClassTag

/** Utility class to splice quoted expressions */
object Splicer {
class Splicer {
Copy link
Member

@smarter smarter Apr 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's weird to make the whole thing a class if the only bit of state is the classloader cache used in a single method, the cache could be passed as an argument instead

@nicolasstucki nicolasstucki force-pushed the cache-classloader-in-splicer branch from 5cf42a5 to 0d1243a Compare April 3, 2018 15:37
@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

performance test scheduled: 3 job(s) in queue, 1 running.

@@ -88,7 +88,8 @@ import dotty.tools.dotc.core.quoted._
class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
import ast.tpd._

private lazy val splicer: Splicer = new Splicer
/** Classloader used for loading macros */
private var macroClassLoader: java.lang.ClassLoader = _
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private[this] also usually we put the field and the getter next to each other, and we call the field myXXX and the getter XXX.

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4235/ to see the changes.

Benchmarks is based on merging with master (1fdb94b)

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

performance test scheduled: 6 job(s) in queue, 1 running.

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4235/ to see the changes.

Benchmarks is based on merging with master (1fdb94b)

@dottybot
Copy link
Member

dottybot commented Apr 3, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4235/ to see the changes.

Benchmarks is based on merging with master (7d01268)

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Apr 4, 2018

performance test scheduled: 112 job(s) in queue, 1 running.

@dottybot
Copy link
Member

dottybot commented Apr 4, 2018

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/4235/ to see the changes.

Benchmarks is based on merging with master (4c8a2bd)

Copy link
Contributor

@liufengyun liufengyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nicolasstucki nicolasstucki merged commit 2174d04 into scala:master Apr 6, 2018
@allanrenucci allanrenucci deleted the cache-classloader-in-splicer branch April 6, 2018 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants