From 63840900346f4314252f1990237bff82596db07f Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 14 Oct 2013 21:48:30 +0400 Subject: [PATCH] Use reference counting to dispose the application when needed --- .../cli/jvm/compiler/JetCoreEnvironment.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java index 2758841500c..125b02ba8fd 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/JetCoreEnvironment.java @@ -64,19 +64,38 @@ import java.util.List; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.ERROR; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.WARNING; +@SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") public class JetCoreEnvironment { private static final Object APPLICATION_LOCK = new Object(); private static JavaCoreApplicationEnvironment ourApplicationEnvironment; + private static int ourProjectCount = 0; @NotNull public static JetCoreEnvironment createForProduction(@NotNull Disposable parentDisposable, @NotNull CompilerConfiguration configuration) { - return new JetCoreEnvironment(parentDisposable, getOrCreateApplicationEnvironmentForProduction(), configuration); + // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) + // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + synchronized (APPLICATION_LOCK) { + if (--ourProjectCount <= 0) { + disposeApplicationEnvironment(); + } + } + } + }); + JetCoreEnvironment environment = new JetCoreEnvironment(parentDisposable, getOrCreateApplicationEnvironmentForProduction(), configuration); + synchronized (APPLICATION_LOCK) { + ourProjectCount++; + } + return environment; } @TestOnly @NotNull public static JetCoreEnvironment createForTests(@NotNull Disposable parentDisposable, @NotNull CompilerConfiguration configuration) { + // Tests are supposed to create a single project and dispose it right after use return new JetCoreEnvironment(parentDisposable, createApplicationEnvironment(parentDisposable), configuration); } @@ -87,11 +106,11 @@ public class JetCoreEnvironment { Disposable parentDisposable = Disposer.newDisposable(); ourApplicationEnvironment = createApplicationEnvironment(parentDisposable); + ourProjectCount = 0; Disposer.register(parentDisposable, new Disposable() { @Override public void dispose() { synchronized (APPLICATION_LOCK) { - //noinspection AssignmentToStaticFieldFromInstanceMethod ourApplicationEnvironment = null; } }