-
Notifications
You must be signed in to change notification settings - Fork 843
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
[NETBEANS-6077] Cached Transformation Classloader, based on set of classpath roots. #3213
Conversation
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.
Internal changes in groovy are fine. I don't understand (and agree to) the change in friend
module list. I don't understand the change in java
modules.
...y/groovy.editor/src/org/netbeans/modules/groovy/editor/compiler/PerfStatCompilationUnit.java
Show resolved
Hide resolved
java/java.source.base/src/org/netbeans/modules/java/source/classpath/CacheClassPath.java
Show resolved
Hide resolved
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.
Looks fine.
a98ab63
to
8defbe9
Compare
8defbe9
to
98d4930
Compare
Groovy parser creates two class loaders - as Groovy compiler uses ClassLoader API to reach out for resources in the user project and/or libraries:
ParsingClassLoader
, which should serve files from user project, sources etc. It is used for symbol or resource resolution.TransformationClassLoader
whose job is to load extensions to the Groovy Compiler, visitors and transformers.The distinction is that while the user project's content may change (user rewrites some files, adds or removes some from the project), so contents of Parsing Classloader should be thrown away, the classes loaded by Transformation ClassLoader are not intended to be part of user project, rather they become part of the IDE runtime.
So far, those classes are loaded to JVM during each parse request - performing all startup linking, verification - AND initialization. It's less visible during indexing, as the whole root is indexed using one set of classloaders, but has big impact on ad hoc parsing tasks like code completion, refrence search, semantic highlight etc.
The issue is highly visible on projects that use sophisticated libraries that add Groovy transformation visitors - which are likely to use its library classes so they are incorporated into IDE's runtime (and then thrown away).
This PR creates a classloader cache for the Transformation classloader. The cache is local to a project, so the contents eventually vanishes after the project closes. One instance of the cache is global to cover files that do not belong to any project. The cache is size-bound and expires (
TimedSoftReference
) its content after ~30 sec of inactivity (provided the classloader is not referenced from anywhere).The cached classloader monitors set of roots of the ClassPath it was created for; if the set of roots changes, the classloader invalidates itself - a new one will be created on next parse request. The validation is also done during parsing startup, so the parser should always start with a consistent state.
The speedup for completion is again on scale of a magnitude: instead of ~10-12 seconds (micronaut-core project), the completion now appears after about 0.5-2 secs.