This is an automated email from the ASF dual-hosted git repository.
lkishalmi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 2d565fe [NETBEANS-3693] Create only one instance of javac
2d565fe is described below
commit 2d565fe02be31e33009fefb4880254ba0a692f47
Author: Akshay-Gupta-Oracle <[email protected]>
AuthorDate: Sun Aug 9 19:04:59 2020 +0530
[NETBEANS-3693] Create only one instance of javac
---
.../java/source/parsing/CompilationInfoImpl.java | 18 +++-
.../modules/java/source/parsing/JavacParser.java | 118 ++++++++++++++-------
.../java/source/parsing/ModuleOraculumTest.java | 5 +-
3 files changed, 98 insertions(+), 43 deletions(-)
diff --git
a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CompilationInfoImpl.java
b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CompilationInfoImpl.java
index fe95c1f..c06c5a2 100644
---
a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CompilationInfoImpl.java
+++
b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/CompilationInfoImpl.java
@@ -89,7 +89,9 @@ public final class CompilationInfoImpl {
private final boolean isDetached;
JavaSource.Phase parserCrashed = JavaSource.Phase.UP_TO_DATE; //When
javac throws an error, the moveToPhase sets this to the last safe phase
private final Map<CacheClearPolicy, Map<Object, Object>> userCache = new
EnumMap<CacheClearPolicy, Map<Object, Object>>(CacheClearPolicy.class);
-
+ //cache of already parsed files
+ private Map<String, CompilationUnitTree> parsedTrees;
+
/**
* Creates a new CompilationInfoImpl for given source file
* @param parser used to parse the file
@@ -330,7 +332,11 @@ public final class CompilationInfoImpl {
}
return null;
}
-
+
+ public Map<String, CompilationUnitTree> getParsedTrees() {
+ return this.parsedTrees;
+ }
+
/**
* Moves the state to required phase. If given state was already reached
@@ -483,8 +489,12 @@ public final class CompilationInfoImpl {
assert compilationUnit != null;
this.compilationUnit = compilationUnit;
}
-
- private boolean hasSource () {
+
+ public void setParsedTrees(Map<String, CompilationUnitTree> parsedTrees) {
+ this.parsedTrees = parsedTrees;
+ }
+
+ private boolean hasSource() {
return this.jfo != null && !isClassFile;
}
diff --git
a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java
b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java
index ca0f9bd..9d1d6d5 100644
---
a/java/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java
+++
b/java/java.source.base/src/org/netbeans/modules/java/source/parsing/JavacParser.java
@@ -56,6 +56,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -153,6 +154,8 @@ public class JavacParser extends Parser {
public static final String MIME_TYPE = "text/x-java";
//No output writer like /dev/null
private static final PrintWriter DEV_NULL = new PrintWriter(new
NullWriter(), false);
+ //Maximum threshold size after which parse use one instance for one file
+ private static final int MAX_FILE_SIZE = (5 << 20);
//Max number of dump files
private static final int MAX_DUMPS =
Integer.getInteger("org.netbeans.modules.java.source.parsing.JavacParser.maxDumps",
255); //NOI18N
//Command line switch disabling partial reparse
@@ -187,8 +190,10 @@ public class JavacParser extends Parser {
private FileObject root;
//ClassPaths used by the parser
private ClasspathInfo cpInfo;
- //Count of files the parser was created for
- private final int sourceCount;
+ //all the files for which parser was created for
+ private final Collection<Snapshot> snapshots;
+ //size of all the files to check the memory leack
+ private long snapshotSize;
//Incremental parsing support
private final boolean supportsReparse;
//Incremental parsing support
@@ -218,9 +223,13 @@ public class JavacParser extends Parser {
JavacParser (final Collection<Snapshot> snapshots, boolean privateParser) {
this.privateParser = privateParser;
- this.sourceCount = snapshots.size();
- final boolean singleJavaFile = this.sourceCount == 1 &&
MIME_TYPE.equals(snapshots.iterator().next().getSource().getMimeType());
+ this.snapshots = snapshots;
+ final boolean singleJavaFile = this.snapshots.size() == 1 &&
MIME_TYPE.equals(snapshots.iterator().next().getSource().getMimeType());
this.supportsReparse = singleJavaFile && !DISABLE_PARTIAL_REPARSE;
+ this.snapshotSize=0;
+ for (Snapshot snapshot : snapshots) {
+ this.snapshotSize+=snapshot.getSource().getFileObject().getSize();
+ }
JavaFileFilterImplementation filter = null;
if (singleJavaFile) {
final Source source = snapshots.iterator().next().getSource();
@@ -236,7 +245,7 @@ public class JavacParser extends Parser {
new Runnable() {
@Override
public void run() {
- if (sourceCount == 0) {
+ if (snapshots.size() == 0) {
invalidate(true);
}
}
@@ -390,9 +399,10 @@ public class JavacParser extends Parser {
task.toString(),
snapshot == null ? "null" : snapshot.getText()}); //NOI18N
final CompilationInfoImpl oldInfo = ciImpl;
+ Map<String, CompilationUnitTree> oldParsedTrees = new HashMap<>();
boolean success = false;
try {
- switch (this.sourceCount) {
+ switch (this.snapshots.size()) {
case 0:
if (shouldParse(task)) {
init(task);
@@ -415,7 +425,7 @@ public class JavacParser extends Parser {
}
if (needsFullReparse) {
positions.clear();
- ciImpl = createCurrentInfo (this, file, root,
snapshot, null, null);
+ ciImpl = createCurrentInfo(this, file, root, snapshot,
null, null, oldParsedTrees);
LOGGER.fine("\t:created new javac");
//NOI18N
} else if (VERIFY_PARTIAL_REPARSE) {
CompilationInfoImpl verifyInfo = new
CompilationInfoImpl(this, file, root, null, null, snapshot, true);
@@ -423,10 +433,29 @@ public class JavacParser extends Parser {
}
break;
default:
- init (snapshot, task, false);
+ init(snapshot, task, false);
+ DiagnosticListener<JavaFileObject> diagnosticListener;
+ JavacTaskImpl javacTask;
+ boolean
oneInstanceJava=Boolean.getBoolean("java.enable.single.javac") &&
this.snapshotSize <= this.MAX_FILE_SIZE;
+ if (sequentialParsing == null && ciImpl == null &&
oneInstanceJava) {
+ List<JavaFileObject> jfos = new ArrayList<>();
+ for (Snapshot s : snapshots) {
+
jfos.add(FileObjects.sourceFileObject(s.getSource().getFileObject(), root,
JavaFileFilterQuery.getFilter(s.getSource().getFileObject()), s.getText()));
+ }
+ diagnosticListener = new
CompilationInfoImpl.DiagnosticListenerImpl(this.root, jfos.get(0), this.cpInfo);
+ javacTask = JavacParser.createJavacTask(this.file,
jfos, this.root, this.cpInfo,
+ this, diagnosticListener, false);
+ } else if (ciImpl != null && (sequentialParsing != null
|| oneInstanceJava)) {
+ diagnosticListener = ciImpl.getDiagnosticListener();
+ javacTask = ciImpl.getJavacTask();
+ oldParsedTrees = ciImpl.getParsedTrees();
+ } else {
+ diagnosticListener = null;
+ javacTask = null;
+ }
ciImpl = createCurrentInfo(this, file, root, snapshot,
- sequentialParsing == null || ciImpl == null ? null :
ciImpl.getJavacTask(),
- sequentialParsing == null || ciImpl == null ? null :
ciImpl.getDiagnosticListener());
+ javacTask,
+ diagnosticListener,oldParsedTrees);
}
success = true;
} finally {
@@ -459,14 +488,14 @@ public class JavacParser extends Parser {
if (isClasspathInfoProvider) {
final ClasspathInfo providedInfo =
((ClasspathInfo.Provider)task).getClasspathInfo();
if (providedInfo != null && !providedInfo.equals(cpInfo)) {
- if (sourceCount != 0) {
+ if (snapshots.size() != 0) {
LOGGER.log (Level.FINE, "Task {0} has changed
ClasspathInfo form: {1} to:{2}", new Object[]{task, cpInfo, providedInfo});
//NOI18N
}
invalidate(true); //Reset initialized, world has changed.
}
}
if (invalid) {
- assert cachedSnapShot != null || sourceCount == 0;
+ assert cachedSnapShot != null || snapshots.size() == 0;
try {
parseImpl(cachedSnapShot, task);
} catch (FileObjects.InvalidFileException ife) {
@@ -583,37 +612,50 @@ public class JavacParser extends Parser {
assert parserError != null;
Phase currentPhase = currentInfo.getPhase();
try {
- if (currentPhase.compareTo(Phase.PARSED)<0 &&
phase.compareTo(Phase.PARSED)>=0 && phase.compareTo(parserError)<=0) {
+ if (currentPhase.compareTo(Phase.PARSED) < 0 &&
phase.compareTo(Phase.PARSED) >= 0 && phase.compareTo(parserError) <= 0) {
if (cancellable && parserCanceled.get()) {
//Keep the currentPhase unchanged, it may happen that an
userActionTask
//runnig after the phace completion task may still use it.
return Phase.MODIFIED;
}
long start = System.currentTimeMillis();
- // XXX - this might be with wrong encoding
- Iterable<? extends CompilationUnitTree> trees;
- if (sequentialParsing != null) {
- trees =
sequentialParsing.parse(currentInfo.getJavacTask(), currentInfo.jfo);
+ Iterable<? extends CompilationUnitTree> trees = null;
+ Iterator<? extends CompilationUnitTree> it = null;
+ CompilationUnitTree unit = null;
+ if (snapshots.size() > 1 && currentInfo.getParsedTrees() !=
null && currentInfo.getParsedTrees().containsKey(currentInfo.jfo.getName())) {
+ unit =
currentInfo.getParsedTrees().get(currentInfo.jfo.getName());
} else {
- trees = currentInfo.getJavacTask(forcedSources).parse();
- }
- if (trees == null) {
- LOGGER.log( Level.INFO, "Did not parse anything for: {0}",
currentInfo.jfo.toUri()); //NOI18N
- return Phase.MODIFIED;
- }
- Iterator<? extends CompilationUnitTree> it = trees.iterator();
- if (!it.hasNext()) {
- LOGGER.log( Level.INFO, "Did not parse anything for: {0}",
currentInfo.jfo.toUri()); //NOI18N
- return Phase.MODIFIED;
+
+ if (sequentialParsing != null) {
+ trees =
sequentialParsing.parse(currentInfo.getJavacTask(), currentInfo.jfo);
+ } else {
+ trees =
currentInfo.getJavacTask(forcedSources).parse();
+ }
+ if (unit == null) {
+ if (trees == null) {
+ LOGGER.log(Level.INFO, "Did not parse anything
for: {0}", currentInfo.jfo.toUri()); //NOI18N
+ return Phase.MODIFIED;
+ }
+ it = trees.iterator();
+ if (!it.hasNext()) {
+ LOGGER.log(Level.INFO, "Did not parse anything
for: {0}", currentInfo.jfo.toUri()); //NOI18N
+ return Phase.MODIFIED;
+ }
+
+ List<JavaFileObject> parsedFiles = new ArrayList<>();
+ while (it.hasNext()) {
+ CompilationUnitTree oneFileTree = it.next();
+ parsedFiles.add(oneFileTree.getSourceFile());
+ CompilationUnitTree put =
currentInfo.getParsedTrees().put(oneFileTree.getSourceFile().getName(),
oneFileTree);
+ }
+ currentInfo.setParsedFiles(parsedFiles);
+ unit = trees.iterator().next();
+ }
+
}
- CompilationUnitTree unit = it.next();
+
currentInfo.setCompilationUnit(unit);
- List<JavaFileObject> parsedFiles = new ArrayList<>();
- parsedFiles.add(unit.getSourceFile());
- while (it.hasNext()) {
- parsedFiles.add(it.next().getSourceFile());
- }
- currentInfo.setParsedFiles(parsedFiles);
+
final Document doc = currentInfo.getDocument();
if (doc != null && supportsReparse) {
final FindMethodRegionsVisitor v = new
FindMethodRegionsVisitor(doc,Trees.instance(currentInfo.getJavacTask()).getSourcePositions(),this.parserCanceled,
unit);
@@ -729,18 +771,20 @@ public class JavacParser extends Parser {
final FileObject root,
final Snapshot snapshot,
final JavacTaskImpl javac,
- final DiagnosticListener<JavaFileObject> diagnosticListener)
throws IOException {
+ final DiagnosticListener<JavaFileObject> diagnosticListener,
+ final Map<String, CompilationUnitTree> parsedTrees) throws
IOException {
CompilationInfoImpl info = new CompilationInfoImpl(parser, file, root,
javac, diagnosticListener, snapshot, false);
if (file != null) {
Logger.getLogger("TIMER").log(Level.FINE, "CompilationInfo",
//NOI18N
new Object[] {file, info});
}
+ info.setParsedTrees(parsedTrees);
return info;
}
static JavacTaskImpl createJavacTask(
final FileObject file,
- final List<JavaFileObject> jfos,
+ final Iterable<? extends JavaFileObject> jfos,
final FileObject root,
final ClasspathInfo cpInfo,
final JavacParser parser,
@@ -761,7 +805,7 @@ public class JavacParser extends Parser {
}
final Set<ConfigFlags> flags = EnumSet.noneOf(ConfigFlags.class);
final Optional<JavacParser> mayBeParser = Optional.ofNullable(parser);
- if (mayBeParser.filter((p)->p.sourceCount>1).isPresent()) {
+ if (mayBeParser.filter((p) -> p.snapshots.size() > 1).isPresent()) {
flags.add(ConfigFlags.MULTI_SOURCE);
}
if (Optional.ofNullable(mayBeParser.map(p->(p.file))
diff --git
a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/ModuleOraculumTest.java
b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/ModuleOraculumTest.java
index d0e86e4..bcc3c80 100644
---
a/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/ModuleOraculumTest.java
+++
b/java/java.source.base/test/unit/src/org/netbeans/modules/java/source/parsing/ModuleOraculumTest.java
@@ -461,8 +461,9 @@ public class ModuleOraculumTest extends NbTestCase {
final DiagnosticListener<? super JavaFileObject>
diagnosticListener,
final boolean detached) {
try {
- List<JavaFileObject> jfo = file != null ?
Arrays.asList(FileObjects.sourceFileObject(file, root, null, false)) :
Collections.emptyList();
- return JavacParser.createJavacTask(file, jfo, root, cpInfo,
parser, diagnosticListener, detached);
+ JavaFileObject jfo = file != null ?
FileObjects.sourceFileObject(file, root, null, false) : null;
+ Iterable<? extends JavaFileObject> jfos = jfo != null ?
Arrays.asList(jfo) : Collections.emptyList();
+ return JavacParser.createJavacTask(file, jfos, root, cpInfo,
parser, diagnosticListener, detached);
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists