From ac6972106bf2a2a132d740e7b3a911e266d01384 Mon Sep 17 00:00:00 2001 From: Fedor Isakov Date: Fri, 27 Nov 2020 11:13:38 +0100 Subject: [PATCH] Fix memleak in LogicalState. Ensure processing machinery gets properly shut down on session end. Clearing the controller field in LogicalState is not enough, apparently some instances are leaked before the session gets terminated. --- .../reactor/core/internal/ConstraintsProcessing.kt | 7 +++++++ .../mps/logic/reactor/core/internal/ControllerImpl.kt | 9 ++++++++- .../reactor/core/internal/EvaluationSessionImpl.kt | 11 +++++------ .../mps/logic/reactor/core/internal/LogicalState.kt | 6 +++--- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt index b2583767..83ba62d2 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ConstraintsProcessing.kt @@ -56,6 +56,13 @@ internal class ConstraintsProcessing( fun getStateCleaner(): ProgramStateCleaner = ProgramStateCleaner() + fun engage(controller: Controller) { + logicalState.setController(controller) + } + + fun disengage(controller: Controller) { + logicalState.clearController(controller) + } fun activateContinue(controller: Controller, activeOcc: Occurrence, parent: MatchJournal.MatchChunk): FeedbackStatus { assert(activeOcc.stored) diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt index 1b7e6abc..e7378ab8 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/ControllerImpl.kt @@ -36,6 +36,14 @@ internal class ControllerImpl ( val profiler: Profiler? = null) : Controller, IncrSpecHolder { + init { + processing.engage(this) + } + + fun shutDown() { + processing.disengage(this) + } + /** For tests only */ override fun storeView(): StoreView = processing.storeView() @@ -361,6 +369,5 @@ fun createController( trace, profiler ) - logicalState.init(controller) return controller } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt index 54b17543..74361d7b 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/EvaluationSessionImpl.kt @@ -111,7 +111,6 @@ internal class EvaluationSessionImpl private constructor ( processing.setStrategy(processingStrategy) val controller = ControllerImpl(supervisor, processing, incrementality, trace, profiler) - logicalState.init(controller) return SessionParts(program.preambleInfo(), ruleIndex, journal, logicalState, dispatchingFront, controller, processing, processingStrategy) } @@ -121,18 +120,20 @@ internal class EvaluationSessionImpl private constructor ( journal.view(), ruleIndex.toRules(), emptyFrontState(), - logicalState.clear(), + logicalState, ruleIndex ) } override fun runSession(session: SessionParts, main: Constraint): EvaluationResult = with(session) { val status = run(main) + controller.shutDown() val newToken = endSession(session) return EvaluationResultImpl(newToken, status, strategy.invalidatedFeedback()) } private fun SessionParts.run(main: Constraint): FeedbackStatus = strategy.run(processing, controller, main) + } open inner class IncrementalProcessingSession(): DefaultProcessingSession() { @@ -151,7 +152,6 @@ internal class EvaluationSessionImpl private constructor ( processing.setStrategy(processingStrategy) val controller = ControllerImpl(supervisor, processing, incrementality, trace, profiler) - logicalState.init(controller) return SessionParts(program.preambleInfo(), ruleIndex, journal, logicalState, front, controller, processing, processingStrategy) } @@ -161,7 +161,7 @@ internal class EvaluationSessionImpl private constructor ( processing.resetStore() // clear observers // todo: need clearing occurrenceContractObservers? (MPSCR-66) val principalState = dispatchingFront.sessionState() - return SessionTokenImpl(histView, ruleIndex.toRules(), principalState, logicalState.clear(), ruleIndex) + return SessionTokenImpl(histView, ruleIndex.toRules(), principalState, logicalState, ruleIndex) } /** @@ -192,7 +192,6 @@ internal class EvaluationSessionImpl private constructor ( processing.setStrategy(processingStrategy) val controller = ControllerImpl(supervisor, processing, incrementality, trace, profiler) - logicalState.init(controller) this.tkn = tkn return SessionParts(program.preambleInfo(), ruleIndex, journal, logicalState, front, controller, processing, processingStrategy) @@ -214,7 +213,7 @@ internal class EvaluationSessionImpl private constructor ( val rules = ruleIndex.toRules().filter(preambleInfo::inPreamble) logicalState.reset() - tkn = SessionTokenImpl(histView, rules, principalState, logicalState.clear(), ruleIndex) + tkn = SessionTokenImpl(histView, rules, principalState, logicalState, ruleIndex) } return tkn!! } diff --git a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt index 8b5f9ed2..3cb026c0 100644 --- a/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt +++ b/reactor/Core/src/jetbrains/mps/logic/reactor/core/internal/LogicalState.kt @@ -50,13 +50,13 @@ class LogicalState : LogicalStateObservable, LogicalObserver stateFrames.push(LogicalStateFrame()) } - fun init(controller: Controller) { + internal fun setController(controller: Controller) { assert(this.controller === null) this.controller = controller } - fun clear() : LogicalState { - assert(this.controller !== null) + internal fun clearController(currController: Controller) : LogicalState { + assert(this.controller == currController) this.controller = null return this }