From bcfd837363626f37cb906f5c77122019b00325bb Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Fri, 15 Nov 2019 16:50:57 +0300 Subject: [PATCH] Smarter process abandoned foreign references. (#3568) --- runtime/src/main/cpp/Memory.cpp | 19 ++++++++++--------- runtime/src/main/cpp/Runtime.cpp | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index 41ca8ef8363..24ef2458410 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -375,22 +375,23 @@ private: void processAbandoned() { if (this->releaseList != nullptr) { - bool hadNoRuntimeInitialized = (memoryState == nullptr); + bool hadNoStateInitialized = (memoryState == nullptr); - if (hadNoRuntimeInitialized) { - Kotlin_initRuntimeIfNeeded(); // Required by ReleaseHeapRef. + if (hadNoStateInitialized) { + // Disregard request if all runtimes are no longer alive. + if (atomicGet(&aliveMemoryStatesCount) == 0) + return; + + memoryState = InitMemory(); // Required by ReleaseHeapRef. } processEnqueuedReleaseRefsWith([](ObjHeader* obj) { ReleaseHeapRef(obj); }); - if (hadNoRuntimeInitialized) { - // This thread is likely not intended to run Kotlin code. - // In this case it has no chances to process the release-refs enqueued above using - // the general heuristics, so do this manually: - garbageCollect(); - // TODO: how to handle subsequent processAbandoned() calls? + if (hadNoStateInitialized) { + // Discard the memory state. + DeinitMemory(memoryState); } } } diff --git a/runtime/src/main/cpp/Runtime.cpp b/runtime/src/main/cpp/Runtime.cpp index 55d07278b4a..366fef2a9dc 100644 --- a/runtime/src/main/cpp/Runtime.cpp +++ b/runtime/src/main/cpp/Runtime.cpp @@ -83,7 +83,7 @@ inline bool isValidRuntime() { return ::runtimeState != kInvalidRuntime; } -int aliveRuntimesCount = 0; +volatile int aliveRuntimesCount = 0; RuntimeState* initRuntime() { SetKonanTerminateHandler();